chiark / gitweb /
bus-proxyd: explicitly address messages to unique and well-known name
[elogind.git] / src / libsystemd-network / test-ipv4ll.c
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"
31
32 #include "sd-ipv4ll.h"
33 #include "ipv4ll-internal.h"
34
35 static bool verbose = false;
36 static bool extended = false;
37 static int test_fd[2];
38
39 static int basic_request_handler_bind = 0;
40 static int basic_request_handler_stop = 0;
41 static void* basic_request_handler_user_data = (void*)0xCABCAB;
42 static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
43         assert_se(userdata == basic_request_handler_user_data);
44
45         switch(event) {
46                 case IPV4LL_EVENT_STOP:
47                         basic_request_handler_stop = 1;
48                         break;
49                 case IPV4LL_EVENT_BIND:
50                         basic_request_handler_bind = 1;
51                         break;
52                 default:
53                         assert_se(0);
54                         break;
55         }
56 }
57
58 int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
59                                         const struct ether_arp *arp) {
60         assert_se(arp);
61         assert_se(link);
62         assert_se(fd >= 0);
63
64         if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
65                 return -errno;
66
67         return 0;
68 }
69
70 int arp_network_bind_raw_socket(int index, union sockaddr_union *link) {
71         if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
72                 return -errno;
73
74         return test_fd[0];
75 }
76
77 static void test_arp_header(struct ether_arp *arp) {
78         assert_se(arp);
79         assert_se(arp->ea_hdr.ar_hrd == htons(ARPHRD_ETHER)); /* HTYPE */
80         assert_se(arp->ea_hdr.ar_pro == htons(ETHERTYPE_IP)); /* PTYPE */
81         assert_se(arp->ea_hdr.ar_hln == ETH_ALEN); /* HLEN */
82         assert_se(arp->ea_hdr.ar_pln == sizeof arp->arp_spa); /* PLEN */
83         assert_se(arp->ea_hdr.ar_op == htons(ARPOP_REQUEST)); /* REQUEST */
84 }
85
86 static void test_arp_probe(void) {
87         struct ether_arp arp;
88         struct ether_addr mac_addr = {
89                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
90         be32_t pa = 0x3030;
91
92         if (verbose)
93                 printf("* %s\n", __FUNCTION__);
94
95         arp_packet_probe(&arp, pa, &mac_addr);
96         test_arp_header(&arp);
97         assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
98         assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
99 }
100
101 static void test_arp_announce(void) {
102         struct ether_arp arp;
103         struct ether_addr mac_addr = {
104                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
105         be32_t pa = 0x3131;
106
107         if (verbose)
108                 printf("* %s\n", __FUNCTION__);
109
110         arp_packet_announcement(&arp, pa, &mac_addr);
111         test_arp_header(&arp);
112         assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
113         assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
114         assert_se(memcmp(arp.arp_spa, &pa, sizeof(pa)) == 0);
115 }
116
117 static void test_public_api_setters(sd_event *e) {
118         uint8_t seed[8];
119         sd_ipv4ll *ll;
120         struct ether_addr mac_addr = {
121                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
122
123         if (verbose)
124                 printf("* %s\n", __FUNCTION__);
125
126         assert_se(sd_ipv4ll_new(&ll) == 0);
127         assert_se(ll);
128
129         assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
130         assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
131         assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);
132
133         assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
134         assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
135
136         assert_se(sd_ipv4ll_set_address_seed(NULL, NULL) == -EINVAL);
137         assert_se(sd_ipv4ll_set_address_seed(ll, NULL) == -EINVAL);
138         assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
139
140         assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
141         assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
142         assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
143
144         assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
145         assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
146         assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
147         assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
148         assert_se(sd_ipv4ll_set_index(ll, 99) == 0);
149
150         assert_se(sd_ipv4ll_ref(ll) == ll);
151         assert_se(sd_ipv4ll_unref(ll) == ll);
152
153         /* Cleanup */
154         assert_se(sd_ipv4ll_unref(ll) == NULL);
155 }
156
157 static void test_basic_request(sd_event *e) {
158
159         sd_ipv4ll *ll;
160         struct ether_arp arp;
161         struct ether_addr mac_addr = {
162                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
163
164         if (verbose)
165                 printf("* %s\n", __FUNCTION__);
166
167         assert_se(sd_ipv4ll_new(&ll) == 0);
168         assert_se(sd_ipv4ll_start(ll) == -EINVAL);
169
170         assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
171         assert_se(sd_ipv4ll_start(ll) == -EINVAL);
172
173         assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
174         assert_se(sd_ipv4ll_start(ll) == -EINVAL);
175
176         assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
177                                          basic_request_handler_user_data) == 0);
178         assert_se(sd_ipv4ll_start(ll) == -EINVAL);
179
180         assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
181         assert_se(sd_ipv4ll_start(ll) == 0);
182
183         sd_event_run(e, (uint64_t) -1);
184         assert_se(sd_ipv4ll_start(ll) == -EBUSY);
185
186         /* PROBE */
187         sd_event_run(e, (uint64_t) -1);
188         assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
189         test_arp_header(&arp);
190
191         if (extended) {
192                 /* PROBE */
193                 sd_event_run(e, (uint64_t) -1);
194                 assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
195                 test_arp_header(&arp);
196
197                 /* PROBE */
198                 sd_event_run(e, (uint64_t) -1);
199                 assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
200                 test_arp_header(&arp);
201
202                 sd_event_run(e, (uint64_t) -1);
203                 assert_se(basic_request_handler_bind == 1);
204         }
205
206         sd_ipv4ll_stop(ll);
207         assert_se(basic_request_handler_stop == 1);
208
209         /* Cleanup */
210         assert_se(sd_ipv4ll_unref(ll) == NULL);
211         safe_close(test_fd[1]);
212 }
213
214 int main(int argc, char *argv[]) {
215         sd_event *e;
216
217         assert_se(sd_event_new(&e) >= 0);
218
219         test_public_api_setters(e);
220         test_arp_probe();
221         test_arp_announce();
222         test_basic_request(e);
223
224         return 0;
225 }