test-dhcp-client.c revision 8fc8e3ab98104db40f5674984dd3edb54e62267f
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright (C) 2013 Intel Corporation. All rights reserved.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stdlib.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <assert.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stdio.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/types.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/socket.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "socket-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "dhcp-protocol.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "dhcp-internal.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering#include "sd-dhcp-client.h"
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic struct ether_addr mac_addr = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering};
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringtypedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool verbose = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int test_fd[2];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic test_callback_recv_t callback_recv;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic be32_t xid;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic sd_event_source *test_hangcheck;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poetteringstatic int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *userdata)
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering{
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_not_reached("Test case should have completed in 2 seconds");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
afc6adb5ec7e73bc13156c43f52fb015cd80cc68Lennart Poettering
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poetteringstatic void test_request_basic(sd_event *e)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_dhcp_client *client;
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering
cde93897cdefdd7c7f66c400a61e42ceee5f6a46Lennart Poettering if (verbose)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("* %s\n", __FUNCTION__);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_dhcp_client_new(&client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(r >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_dhcp_client_attach_event(client, e, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(r >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_index(client, 15) == 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sd_dhcp_client_set_index(client, -1) == 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering DHCP_OPTION_SUBNET_MASK) == -EEXIST);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_ROUTER) == -EEXIST);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_HOST_NAME) == -EEXIST);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_DOMAIN_NAME_SERVER)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering == -EEXIST);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_NTP_SERVER) == -EEXIST);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_PAD) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_END) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_OVERLOAD) == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DHCP_OPTION_PARAMETER_REQUEST_LIST)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering == -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void test_checksum(void)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering uint8_t buf[20] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0xff, 0xff, 0xff, 0xff
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (verbose)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("* %s\n", __FUNCTION__);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(dhcp_packet_checksum(&buf, 20) == be16toh(0x78ae));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int check_options(uint8_t code, uint8_t len, const uint8_t *option,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *user_data)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const void *packet, size_t len)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size_t size;
76b543756ef69ce69784d571aefe8de65eaeb331Lennart Poettering _cleanup_free_ DHCPPacket *discover;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering uint16_t ip_check, udp_check;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(s >= 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(packet);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering size = sizeof(DHCPPacket) + 4;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(len > size);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering discover = memdup(packet, len);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(discover->ip.ttl == IPDEFTTL);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering assert_se(discover->ip.protocol == IPPROTO_UDP);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(discover->ip.saddr == INADDR_ANY);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(discover->ip.daddr == INADDR_BROADCAST);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering ip_check = discover->ip.check;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering discover->ip.ttl = 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering discover->ip.check = discover->udp.len;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering udp_check = ~dhcp_packet_checksum(&discover->ip.ttl, len - 8);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(udp_check == 0xffff);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering discover->ip.ttl = IPDEFTTL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering discover->ip.check = ip_check;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering ip_check = ~dhcp_packet_checksum(&discover->ip, sizeof(discover->ip));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(ip_check == 0xffff);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(discover->dhcp.xid);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(memcmp(discover->dhcp.chaddr,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering &mac_addr.ether_addr_octet, 6) == 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(callback_recv);
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering callback_recv(size, &discover->dhcp);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 575;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringint dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering{
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return -errno;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return test_fd[0];
943aca8efb39453e3994ccdd1e08534b788c5aeeLennart Poettering}
943aca8efb39453e3994ccdd1e08534b788c5aeeLennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringint dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port)
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering{
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringint dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const void *packet, size_t len)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering{
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int res;
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering res = dhcp_option_parse(dhcp, size, check_options, NULL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(res == DHCP_DISCOVER);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (verbose)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering return 0;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering}
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic void test_discover_message(sd_event *e)
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering{
6797c324a653f119a3d7133122648aaa4878ddd6Lennart Poettering sd_dhcp_client *client;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering int res, r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (verbose)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("* %s\n", __FUNCTION__);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_dhcp_client_new(&client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(r >= 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = sd_dhcp_client_attach_event(client, e, 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(r >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
5bb658a1784a0fd4f0f32adb4b1fb636ff503f7dKay Sievers assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering callback_recv = test_discover_message_verify;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering res = sd_dhcp_client_start(client);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(res == 0 || res == -EINPROGRESS);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event_run(e, (uint64_t) -1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_dhcp_client_stop(client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_dhcp_client_free(client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering close(test_fd[0]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering close(test_fd[1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering callback_recv = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
71fda00f320379f5cbee8e118848de98caaa229dLennart Poetteringstatic uint8_t test_addr_acq_offer[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering};
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poetteringstatic uint8_t test_addr_acq_ack[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering};
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void test_addr_acq_acquired(sd_dhcp_client *client, int event,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering void *userdata)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering{
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event *e = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_dhcp_lease *lease;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct in_addr addr;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(client);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(event == DHCP_EVENT_IP_ACQUIRE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(lease);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sizeof(addr.s_addr)) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sizeof(addr.s_addr)) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
assert_se(sd_dhcp_lease_get_router(lease, &addr) >= 0);
assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[308],
sizeof(addr.s_addr)) == 0);
if (verbose)
printf(" DHCP address acquired\n");
sd_event_exit(e, 0);
}
static int test_addr_acq_recv_request(size_t size, DHCPMessage *request)
{
uint16_t udp_check = 0;
int res;
res = dhcp_option_parse(request, size, check_options, NULL);
assert_se(res == DHCP_REQUEST);
assert_se(xid == request->xid);
if (verbose)
printf(" recv DHCP Request 0x%08x\n", be32toh(xid));
memcpy(&test_addr_acq_ack[26], &udp_check, sizeof(udp_check));
memcpy(&test_addr_acq_ack[32], &xid, sizeof(xid));
memcpy(&test_addr_acq_ack[56], &mac_addr.ether_addr_octet,
ETHER_ADDR_LEN);
callback_recv = NULL;
res = write(test_fd[1], test_addr_acq_ack,
sizeof(test_addr_acq_ack));
assert_se(res == sizeof(test_addr_acq_ack));
if (verbose)
printf(" send DHCP Ack\n");
return 0;
};
static int test_addr_acq_recv_discover(size_t size, DHCPMessage *discover)
{
uint16_t udp_check = 0;
int res;
res = dhcp_option_parse(discover, size, check_options, NULL);
assert_se(res == DHCP_DISCOVER);
xid = discover->xid;
if (verbose)
printf(" recv DHCP Discover 0x%08x\n", be32toh(xid));
memcpy(&test_addr_acq_offer[26], &udp_check, sizeof(udp_check));
memcpy(&test_addr_acq_offer[32], &xid, sizeof(xid));
memcpy(&test_addr_acq_offer[56], &mac_addr.ether_addr_octet,
ETHER_ADDR_LEN);
callback_recv = test_addr_acq_recv_request;
res = write(test_fd[1], test_addr_acq_offer,
sizeof(test_addr_acq_offer));
assert_se(res == sizeof(test_addr_acq_offer));
if (verbose)
printf(" send DHCP Offer\n");
return 0;
}
static void test_addr_acq(sd_event *e)
{
usec_t time_now = now(CLOCK_MONOTONIC);
sd_dhcp_client *client;
int res, r;
if (verbose)
printf("* %s\n", __FUNCTION__);
r = sd_dhcp_client_new(&client);
assert_se(r >= 0);
assert_se(client);
r = sd_dhcp_client_attach_event(client, e, 0);
assert_se(r >= 0);
assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
>= 0);
callback_recv = test_addr_acq_recv_discover;
assert_se(sd_event_add_monotonic(e, &test_hangcheck,
time_now + 2 * USEC_PER_SEC, 0,
test_dhcp_hangcheck, NULL) >= 0);
res = sd_dhcp_client_start(client);
assert_se(res == 0 || res == -EINPROGRESS);
sd_event_loop(e);
test_hangcheck = sd_event_source_unref(test_hangcheck);
sd_dhcp_client_set_callback(client, NULL, NULL);
sd_dhcp_client_stop(client);
sd_dhcp_client_free(client);
close(test_fd[0]);
close(test_fd[1]);
callback_recv = NULL;
xid = 0;
}
int main(int argc, char *argv[])
{
sd_event *e;
assert_se(sd_event_new(&e) >= 0);
test_request_basic(e);
test_checksum();
test_discover_message(e);
test_addr_acq(e);
return 0;
}