chiark / gitweb /
sd-dhcp6-client: Add basic DHCPv6 option handling
[elogind.git] / src / libsystemd-network / test-dhcp6-client.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 Intel Corporation. All rights reserved.
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdbool.h>
23 #include <stdio.h>
24
25 #include "macro.h"
26 #include "sd-event.h"
27 #include "event-util.h"
28
29 #include "sd-dhcp6-client.h"
30 #include "dhcp6-protocol.h"
31 #include "dhcp6-internal.h"
32
33 static struct ether_addr mac_addr = {
34         .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
35 };
36
37 static bool verbose = false;
38
39 static int test_client_basic(sd_event *e) {
40         sd_dhcp6_client *client;
41
42         if (verbose)
43                 printf("* %s\n", __FUNCTION__);
44
45         assert_se(sd_dhcp6_client_new(&client) >= 0);
46         assert_se(client);
47
48         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
49
50         assert_se(sd_dhcp6_client_set_index(client, 15) == 0);
51         assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL);
52         assert_se(sd_dhcp6_client_set_index(client, -1) == 0);
53         assert_se(sd_dhcp6_client_set_index(client, 42) >= 0);
54
55         assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
56
57         assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
58
59         assert_se(sd_dhcp6_client_detach_event(client) >= 0);
60         assert_se(!sd_dhcp6_client_unref(client));
61
62         return 0;
63 }
64
65 static int test_option(sd_event *e) {
66         uint8_t packet[] = {
67                 'F', 'O', 'O',
68                 0x00, DHCP6_OPTION_ORO, 0x00, 0x07,
69                 'A', 'B', 'C', 'D', 'E', 'F', 'G',
70                 0x00, DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
71                 '1', '2', '3', '4', '5', '6', '7', '8', '9',
72                 'B', 'A', 'R',
73         };
74         uint8_t result[] = {
75                 'F', 'O', 'O',
76                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79                 'B', 'A', 'R',
80         };
81         uint16_t optcode;
82         size_t optlen;
83         uint8_t *optval, *buf, *out;
84         size_t zero = 0, pos = 3;
85         size_t buflen = sizeof(packet), outlen = sizeof(result);
86
87         if (verbose)
88                 printf("* %s\n", __FUNCTION__);
89
90         assert_se(buflen == outlen);
91
92         assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
93                                      &optval) == -ENOMSG);
94
95         buflen -= 3;
96         buf = &packet[3];
97         outlen -= 3;
98         out = &result[3];
99
100         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
101                                      &optval) >= 0);
102         pos += 4 + optlen;
103         assert_se(buf == &packet[pos]);
104         assert_se(optcode == DHCP6_OPTION_ORO);
105         assert_se(optlen == 7);
106         assert_se(buflen + pos == sizeof(packet));
107
108         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
109                                       optval) >= 0);
110         assert_se(out == &result[pos]);
111         assert_se(*out == 0x00);
112
113         assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
114                                      &optval) >= 0);
115         pos += 4 + optlen;
116         assert_se(buf == &packet[pos]);
117         assert_se(optcode == DHCP6_OPTION_VENDOR_CLASS);
118         assert_se(optlen == 9);
119         assert_se(buflen + pos == sizeof(packet));
120
121         assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
122                                       optval) >= 0);
123         assert_se(out == &result[pos]);
124         assert_se(*out == 'B');
125
126         assert_se(memcmp(packet, result, sizeof(packet)) == 0);
127
128         return 0;
129 }
130
131 int main(int argc, char *argv[]) {
132         _cleanup_event_unref_ sd_event *e;
133
134         assert_se(sd_event_new(&e) >= 0);
135
136         log_set_max_level(LOG_DEBUG);
137         log_parse_environment();
138         log_open();
139
140         test_client_basic(e);
141         test_option(e);
142
143         assert_se(!sd_event_unref(e));
144
145         return 0;
146 }