summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2015-04-19 13:28:46 +0200
committerAndy Wingo <wingo@pobox.com>2015-04-19 13:32:24 +0200
commite418908760d8b7826017b07b2a5d2e365152e7ae (patch)
tree82044c18a470e935170c97b5870a545de47f4084 /src
parenta2109619cd5c28c4739e659e40b6b524c7c0d488 (diff)
Remove src/libsystemd-network
Diffstat (limited to 'src')
l---------src/libsystemd-network/Makefile1
-rw-r--r--src/libsystemd-network/dhcp-identifier.c98
-rw-r--r--src/libsystemd-network/dhcp-identifier.h64
-rw-r--r--src/libsystemd-network/dhcp-internal.h74
-rw-r--r--src/libsystemd-network/dhcp-lease-internal.h87
-rw-r--r--src/libsystemd-network/dhcp-network.c235
-rw-r--r--src/libsystemd-network/dhcp-option.c253
-rw-r--r--src/libsystemd-network/dhcp-packet.c192
-rw-r--r--src/libsystemd-network/dhcp-protocol.h141
-rw-r--r--src/libsystemd-network/dhcp-server-internal.h93
-rw-r--r--src/libsystemd-network/dhcp6-internal.h79
-rw-r--r--src/libsystemd-network/dhcp6-lease-internal.h62
-rw-r--r--src/libsystemd-network/dhcp6-network.c194
-rw-r--r--src/libsystemd-network/dhcp6-option.c319
-rw-r--r--src/libsystemd-network/dhcp6-protocol.h144
-rw-r--r--src/libsystemd-network/ipv4ll-internal.h38
-rw-r--r--src/libsystemd-network/ipv4ll-network.c91
-rw-r--r--src/libsystemd-network/ipv4ll-packet.c71
-rw-r--r--src/libsystemd-network/lldp-internal.c533
-rw-r--r--src/libsystemd-network/lldp-internal.h99
-rw-r--r--src/libsystemd-network/lldp-network.c111
-rw-r--r--src/libsystemd-network/lldp-network.h28
-rw-r--r--src/libsystemd-network/lldp-port.c116
-rw-r--r--src/libsystemd-network/lldp-port.h63
-rw-r--r--src/libsystemd-network/lldp-tlv.c321
-rw-r--r--src/libsystemd-network/lldp-tlv.h87
-rw-r--r--src/libsystemd-network/lldp-util.h26
-rw-r--r--src/libsystemd-network/lldp.h115
-rw-r--r--src/libsystemd-network/network-internal.c511
-rw-r--r--src/libsystemd-network/network-internal.h76
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c1733
-rw-r--r--src/libsystemd-network/sd-dhcp-lease.c865
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c991
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c1249
-rw-r--r--src/libsystemd-network/sd-dhcp6-lease.c207
-rw-r--r--src/libsystemd-network/sd-icmp6-nd.c715
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c648
-rw-r--r--src/libsystemd-network/sd-lldp.c684
-rw-r--r--src/libsystemd-network/sd-pppoe.c801
-rw-r--r--src/libsystemd-network/test-dhcp-client.c528
-rw-r--r--src/libsystemd-network/test-dhcp-option.c382
-rw-r--r--src/libsystemd-network/test-dhcp-server.c250
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c707
-rw-r--r--src/libsystemd-network/test-icmp6-rs.c357
-rw-r--r--src/libsystemd-network/test-ipv4ll.c225
-rw-r--r--src/libsystemd-network/test-lldp.c231
-rw-r--r--src/libsystemd-network/test-pppoe.c175
47 files changed, 0 insertions, 15070 deletions
diff --git a/src/libsystemd-network/Makefile b/src/libsystemd-network/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/libsystemd-network/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
deleted file mode 100644
index f7a1492363..0000000000
--- a/src/libsystemd-network/dhcp-identifier.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2015 Tom Gundersen <teg@jklmen>
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-#include "sd-id128.h"
-#include "libudev.h"
-#include "udev-util.h"
-
-#include "virt.h"
-#include "sparse-endian.h"
-#include "siphash24.h"
-
-#include "dhcp6-protocol.h"
-#include "dhcp-identifier.h"
-#include "network-internal.h"
-
-#define SYSTEMD_PEN 43793
-#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
-
-int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
- sd_id128_t machine_id;
- int r;
-
- assert(duid);
- assert(len);
-
- r = sd_id128_get_machine(&machine_id);
- if (r < 0)
- return r;
-
- duid->type = htobe16(DHCP6_DUID_EN);
- duid->en.pen = htobe32(SYSTEMD_PEN);
- *len = sizeof(duid->type) + sizeof(duid->en);
-
- /* a bit of snake-oil perhaps, but no need to expose the machine-id
- directly */
- siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
-
- return 0;
-}
-
-
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, uint32_t *_id) {
- /* name is a pointer to memory in the udev_device struct, so must
- have the same scope */
- _cleanup_udev_device_unref_ struct udev_device *device = NULL;
- const char *name = NULL;
- uint64_t id;
-
- if (detect_container(NULL) <= 0) {
- /* not in a container, udev will be around */
- _cleanup_udev_unref_ struct udev *udev;
- char ifindex_str[2 + DECIMAL_STR_MAX(int)];
-
- udev = udev_new();
- if (!udev)
- return -ENOMEM;
-
- sprintf(ifindex_str, "n%d", ifindex);
- device = udev_device_new_from_device_id(udev, ifindex_str);
- if (device) {
- if (udev_device_get_is_initialized(device) <= 0)
- /* not yet ready */
- return -EBUSY;
-
- name = net_get_name(device);
- }
- }
-
- if (name)
- siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
- else
- /* fall back to MAC address if no predictable name available */
- siphash24((uint8_t*)&id, mac, mac_len, HASH_KEY.bytes);
-
- /* fold into 32 bits */
- *_id = (id & 0xffffffff) ^ (id >> 32);
-
- return 0;
-}
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
deleted file mode 100644
index 643d4970d5..0000000000
--- a/src/libsystemd-network/dhcp-identifier.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2015 Tom Gundersen <teg@jklmen>
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-
-#include "macro.h"
-#include "sparse-endian.h"
-#include "sd-id128.h"
-
-/* RFC 3315 section 9.1:
- * A DUID can be no more than 128 octets long (not including the type code).
- */
-#define MAX_DUID_LEN 128
-
-struct duid {
- uint16_t type;
- union {
- struct {
- /* DHCP6_DUID_LLT */
- uint16_t htype;
- uint32_t time;
- uint8_t haddr[0];
- } _packed_ llt;
- struct {
- /* DHCP6_DUID_EN */
- uint32_t pen;
- uint8_t id[8];
- } _packed_ en;
- struct {
- /* DHCP6_DUID_LL */
- int16_t htype;
- uint8_t haddr[0];
- } _packed_ ll;
- struct {
- /* DHCP6_DUID_UUID */
- sd_id128_t uuid;
- } _packed_ uuid;
- struct {
- uint8_t data[MAX_DUID_LEN];
- } _packed_ raw;
- };
-} _packed_;
-
-int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
-int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, uint32_t *_id);
diff --git a/src/libsystemd-network/dhcp-internal.h b/src/libsystemd-network/dhcp-internal.h
deleted file mode 100644
index 7c60ef123c..0000000000
--- a/src/libsystemd-network/dhcp-internal.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-#include <linux/if_packet.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-
-#include "socket-util.h"
-
-#include "sd-dhcp-client.h"
-#include "dhcp-protocol.h"
-
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
- uint32_t xid, const uint8_t *mac_addr,
- size_t mac_addr_len, uint16_t arp_type);
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
- const void *packet, size_t len);
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
- const void *packet, size_t len);
-
-int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload,
- uint8_t code, size_t optlen, const void *optval);
-
-typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len,
- const uint8_t *option, void *user_data);
-
-int dhcp_option_parse(DHCPMessage *message, size_t len,
- dhcp_option_cb_t cb, void *user_data);
-
-int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
- uint8_t type, uint16_t arp_type, size_t optlen,
- size_t *optoffset);
-
-uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
-
-void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
- uint16_t source, be32_t destination_addr,
- uint16_t destination, uint16_t len);
-
-int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
-#define _cleanup_dhcp_client_unref_ _cleanup_(sd_dhcp_client_unrefp)
-
-/* If we are invoking callbacks of a dhcp-client, ensure unreffing the
- * client from the callback doesn't destroy the object we are working
- * on */
-#define DHCP_CLIENT_DONT_DESTROY(client) \
- _cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
-
-#define log_dhcp_client(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h
deleted file mode 100644
index 9e184ac4b5..0000000000
--- a/src/libsystemd-network/dhcp-lease-internal.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-#include <linux/if_packet.h>
-
-#include "refcnt.h"
-#include "util.h"
-
-#include "dhcp-protocol.h"
-
-#include "sd-dhcp-client.h"
-
-struct sd_dhcp_route {
- struct in_addr dst_addr;
- struct in_addr gw_addr;
- unsigned char dst_prefixlen;
-};
-
-struct sd_dhcp_lease {
- RefCount n_ref;
-
- int32_t time_offset;
- uint32_t t1;
- uint32_t t2;
- uint32_t lifetime;
- uint32_t mtu_aging_timeout;
- be32_t address;
- be32_t server_address;
- be32_t subnet_mask;
- be32_t router;
- be32_t next_server;
- be32_t broadcast;
- struct in_addr *dns;
- size_t dns_size;
- struct in_addr *ntp;
- size_t ntp_size;
- struct in_addr *policy_filter;
- size_t policy_filter_size;
- struct sd_dhcp_route *static_route;
- size_t static_route_size;
- size_t static_route_allocated;
- uint16_t boot_file_size;
- uint16_t mdr;
- uint16_t mtu;
- uint8_t ttl;
- bool ip_forward;
- bool ip_forward_non_local;
- char *domainname;
- char *hostname;
- char *root_path;
- uint8_t *client_id;
- size_t client_id_len;
-};
-
-int dhcp_lease_new(sd_dhcp_lease **ret);
-int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
- void *user_data);
-
-int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
-
-int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
- size_t client_id_len);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_lease*, sd_dhcp_lease_unref);
-#define _cleanup_dhcp_lease_unref_ _cleanup_(sd_dhcp_lease_unrefp)
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
deleted file mode 100644
index 7f10838de1..0000000000
--- a/src/libsystemd-network/dhcp-network.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <linux/if_packet.h>
-#include <linux/if_infiniband.h>
-#include <net/ethernet.h>
-#include <net/if_arp.h>
-#include <stdio.h>
-#include <linux/filter.h>
-
-#include "socket-util.h"
-
-#include "dhcp-internal.h"
-
-static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
- uint32_t xid, const uint8_t *mac_addr,
- size_t mac_addr_len,
- const uint8_t *bcast_addr,
- const struct ether_addr *eth_mac,
- uint16_t arp_type, uint8_t dhcp_hlen) {
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
- BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0), /* packet >= DHCPPacket ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.protocol)), /* A <- IP protocol */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), /* IP protocol == UDP ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags */
- BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x20), /* A <- A & 0x20 (More Fragments bit) */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, ip.frag_off)), /* A <- Flags + Fragment offset */
- BPF_STMT(BPF_ALU + BPF_AND + BPF_K, 0x1fff), /* A <- A & 0x1fff (Fragment offset) */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, udp.dest)), /* A <- UDP destination port */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), /* UDP destination port == DHCP client port ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.op)), /* A <- DHCP op */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), /* op == BOOTREPLY ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)), /* A <- DHCP header type */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0), /* header type == arp_type ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- MAC address length */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), /* address length == dhcp_hlen ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), /* client identifier == xid ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))), /* A <- 4 bytes of client's MAC */
- BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */
- BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))), /* A <- remainder of client's MAC */
- BPF_STMT(BPF_MISC + BPF_TAX, 0), /* X <- A */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */
- BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), /* A xor X */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), /* A == 0 ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.magic)), /* A <- DHCP magic cookie */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, 0), /* cookie == DHCP magic cookie ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
- };
- struct sock_fprog fprog = {
- .len = ELEMENTSOF(filter),
- .filter = filter
- };
- _cleanup_close_ int s = -1;
- int r, on = 1;
-
- assert(ifindex > 0);
- assert(link);
-
- s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
- if (s < 0)
- return -errno;
-
- r = setsockopt(s, SOL_PACKET, PACKET_AUXDATA, &on, sizeof(on));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
- if (r < 0)
- return -errno;
-
- link->ll.sll_family = AF_PACKET;
- link->ll.sll_protocol = htons(ETH_P_IP);
- link->ll.sll_ifindex = ifindex;
- link->ll.sll_hatype = htons(arp_type);
- link->ll.sll_halen = mac_addr_len;
- memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len);
-
- r = bind(s, &link->sa, sizeof(link->ll));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
-
- return r;
-}
-
-int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
- uint32_t xid, const uint8_t *mac_addr,
- size_t mac_addr_len, uint16_t arp_type) {
- static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- /* Default broadcast address for IPoIB */
- static const uint8_t ib_bcast[] = {
- 0x00, 0xff, 0xff, 0xff, 0xff, 0x12, 0x40, 0x1b,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff
- };
- struct ether_addr eth_mac = { { 0, 0, 0, 0, 0, 0 } };
- const uint8_t *bcast_addr = NULL;
- uint8_t dhcp_hlen = 0;
-
- assert_return(mac_addr_len > 0, -EINVAL);
-
- if (arp_type == ARPHRD_ETHER) {
- assert_return(mac_addr_len == ETH_ALEN, -EINVAL);
- memcpy(&eth_mac, mac_addr, ETH_ALEN);
- bcast_addr = eth_bcast;
- dhcp_hlen = ETH_ALEN;
- } else if (arp_type == ARPHRD_INFINIBAND) {
- assert_return(mac_addr_len == INFINIBAND_ALEN, -EINVAL);
- bcast_addr = ib_bcast;
- } else
- return -EINVAL;
-
- return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len,
- bcast_addr, &eth_mac, arp_type, dhcp_hlen);
-}
-
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
- union sockaddr_union src = {
- .in.sin_family = AF_INET,
- .in.sin_port = htobe16(port),
- .in.sin_addr.s_addr = address,
- };
- _cleanup_close_ int s = -1;
- int r, on = 1, tos = IPTOS_CLASS_CS6;
-
- s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
- if (s < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- if (r < 0)
- return -errno;
-
- if (address == INADDR_ANY) {
- r = setsockopt(s, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
- if (r < 0)
- return -errno;
- } else {
- r = setsockopt(s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on));
- if (r < 0)
- return -errno;
- }
-
- r = bind(s, &src.sa, sizeof(src.in));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
-
- return r;
-}
-
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
- const void *packet, size_t len) {
- int r;
-
- assert(link);
- assert(packet);
- assert(len);
-
- r = sendto(s, packet, len, 0, &link->sa, sizeof(link->ll));
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
- const void *packet, size_t len) {
- union sockaddr_union dest = {
- .in.sin_family = AF_INET,
- .in.sin_port = htobe16(port),
- .in.sin_addr.s_addr = address,
- };
- int r;
-
- assert(s >= 0);
- assert(packet);
- assert(len);
-
- r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in));
- if (r < 0)
- return -errno;
-
- return 0;
-}
diff --git a/src/libsystemd-network/dhcp-option.c b/src/libsystemd-network/dhcp-option.c
deleted file mode 100644
index b6110c5f16..0000000000
--- a/src/libsystemd-network/dhcp-option.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include "dhcp-internal.h"
-
-static int option_append(uint8_t options[], size_t size, size_t *offset,
- uint8_t code, size_t optlen, const void *optval) {
- assert(options);
- assert(offset);
-
- if (code != DHCP_OPTION_END)
- /* always make sure there is space for an END option */
- size --;
-
- switch (code) {
-
- case DHCP_OPTION_PAD:
- case DHCP_OPTION_END:
- if (size < *offset + 1)
- return -ENOBUFS;
-
- options[*offset] = code;
- *offset += 1;
- break;
-
- default:
- if (size < *offset + optlen + 2)
- return -ENOBUFS;
-
- options[*offset] = code;
- options[*offset + 1] = optlen;
-
- if (optlen) {
- assert(optval);
-
- memcpy(&options[*offset + 2], optval, optlen);
- }
-
- *offset += optlen + 2;
-
- break;
- }
-
- return 0;
-}
-
-int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
- uint8_t overload,
- uint8_t code, size_t optlen, const void *optval) {
- size_t file_offset = 0, sname_offset =0;
- bool file, sname;
- int r;
-
- assert(message);
- assert(offset);
-
- file = overload & DHCP_OVERLOAD_FILE;
- sname = overload & DHCP_OVERLOAD_SNAME;
-
- if (*offset < size) {
- /* still space in the options array */
- r = option_append(message->options, size, offset, code, optlen, optval);
- if (r >= 0)
- return 0;
- else if (r == -ENOBUFS && (file || sname)) {
- /* did not fit, but we have more buffers to try
- close the options array and move the offset to its end */
- r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- *offset = size;
- } else
- return r;
- }
-
- if (overload & DHCP_OVERLOAD_FILE) {
- file_offset = *offset - size;
-
- if (file_offset < sizeof(message->file)) {
- /* still space in the 'file' array */
- r = option_append(message->file, sizeof(message->file), &file_offset, code, optlen, optval);
- if (r >= 0) {
- *offset = size + file_offset;
- return 0;
- } else if (r == -ENOBUFS && sname) {
- /* did not fit, but we have more buffers to try
- close the file array and move the offset to its end */
- r = option_append(message->options, size, offset, DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- *offset = size + sizeof(message->file);
- } else
- return r;
- }
- }
-
- if (overload & DHCP_OVERLOAD_SNAME) {
- sname_offset = *offset - size - (file ? sizeof(message->file) : 0);
-
- if (sname_offset < sizeof(message->sname)) {
- /* still space in the 'sname' array */
- r = option_append(message->sname, sizeof(message->sname), &sname_offset, code, optlen, optval);
- if (r >= 0) {
- *offset = size + (file ? sizeof(message->file) : 0) + sname_offset;
- return 0;
- } else {
- /* no space, or other error, give up */
- return r;
- }
- }
- }
-
- return -ENOBUFS;
-}
-
-static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload,
- uint8_t *message_type, dhcp_option_cb_t cb,
- void *user_data) {
- uint8_t code, len;
- size_t offset = 0;
-
- while (offset < buflen) {
- switch (options[offset]) {
- case DHCP_OPTION_PAD:
- offset++;
-
- break;
-
- case DHCP_OPTION_END:
- return 0;
-
- case DHCP_OPTION_MESSAGE_TYPE:
- if (buflen < offset + 3)
- return -ENOBUFS;
-
- len = options[++offset];
- if (len != 1)
- return -EINVAL;
-
- if (message_type)
- *message_type = options[++offset];
- else
- offset++;
-
- offset++;
-
- break;
-
- case DHCP_OPTION_OVERLOAD:
- if (buflen < offset + 3)
- return -ENOBUFS;
-
- len = options[++offset];
- if (len != 1)
- return -EINVAL;
-
- if (overload)
- *overload = options[++offset];
- else
- offset++;
-
- offset++;
-
- break;
-
- default:
- if (buflen < offset + 3)
- return -ENOBUFS;
-
- code = options[offset];
- len = options[++offset];
-
- if (buflen < ++offset + len)
- return -EINVAL;
-
- if (cb)
- cb(code, len, &options[offset], user_data);
-
- offset += len;
-
- break;
- }
- }
-
- if (offset < buflen)
- return -EINVAL;
-
- return 0;
-}
-
-int dhcp_option_parse(DHCPMessage *message, size_t len,
- dhcp_option_cb_t cb, void *user_data) {
- uint8_t overload = 0;
- uint8_t message_type = 0;
- int r;
-
- if (!message)
- return -EINVAL;
-
- if (len < sizeof(DHCPMessage))
- return -EINVAL;
-
- len -= sizeof(DHCPMessage);
-
- r = parse_options(message->options, len, &overload, &message_type,
- cb, user_data);
- if (r < 0)
- return r;
-
- if (overload & DHCP_OVERLOAD_FILE) {
- r = parse_options(message->file, sizeof(message->file),
- NULL, &message_type, cb, user_data);
- if (r < 0)
- return r;
- }
-
- if (overload & DHCP_OVERLOAD_SNAME) {
- r = parse_options(message->sname, sizeof(message->sname),
- NULL, &message_type, cb, user_data);
- if (r < 0)
- return r;
- }
-
- if (message_type)
- return message_type;
-
- return -ENOMSG;
-}
diff --git a/src/libsystemd-network/dhcp-packet.c b/src/libsystemd-network/dhcp-packet.c
deleted file mode 100644
index cd7f5095ca..0000000000
--- a/src/libsystemd-network/dhcp-packet.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-#include <net/ethernet.h>
-#include <net/if_arp.h>
-
-
-#include "dhcp-protocol.h"
-#include "dhcp-internal.h"
-
-#define DHCP_CLIENT_MIN_OPTIONS_SIZE 312
-
-int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
- uint8_t type, uint16_t arp_type, size_t optlen,
- size_t *optoffset) {
- size_t offset = 0;
- int r;
-
- assert(op == BOOTREQUEST || op == BOOTREPLY);
- assert(arp_type == ARPHRD_ETHER || arp_type == ARPHRD_INFINIBAND);
-
- message->op = op;
- message->htype = arp_type;
- message->hlen = (arp_type == ARPHRD_ETHER) ? ETHER_ADDR_LEN : 0;
- message->xid = htobe32(xid);
- message->magic = htobe32(DHCP_MAGIC_COOKIE);
-
- r = dhcp_option_append(message, optlen, &offset, 0,
- DHCP_OPTION_MESSAGE_TYPE, 1, &type);
- if (r < 0)
- return r;
-
- *optoffset = offset;
-
- return 0;
-}
-
-uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len) {
- uint64_t *buf_64 = (uint64_t*)buf;
- uint64_t *end_64 = buf_64 + (len / sizeof(uint64_t));
- uint64_t sum = 0;
-
- /* See RFC1071 */
-
- while (buf_64 < end_64) {
- sum += *buf_64;
- if (sum < *buf_64)
- /* wrap around in one's complement */
- sum++;
-
- buf_64 ++;
- }
-
- if (len % sizeof(uint64_t)) {
- /* If the buffer is not aligned to 64-bit, we need
- to zero-pad the last few bytes and add them in */
- uint64_t buf_tail = 0;
-
- memcpy(&buf_tail, buf_64, len % sizeof(uint64_t));
-
- sum += buf_tail;
- if (sum < buf_tail)
- /* wrap around */
- sum++;
- }
-
- while (sum >> 16)
- sum = (sum & 0xffff) + (sum >> 16);
-
- return ~sum;
-}
-
-void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
- uint16_t source_port, be32_t destination_addr,
- uint16_t destination_port, uint16_t len) {
- packet->ip.version = IPVERSION;
- packet->ip.ihl = DHCP_IP_SIZE / 4;
- packet->ip.tot_len = htobe16(len);
-
- packet->ip.tos = IPTOS_CLASS_CS6;
-
- packet->ip.protocol = IPPROTO_UDP;
- packet->ip.saddr = source_addr;
- packet->ip.daddr = destination_addr;
-
- packet->udp.source = htobe16(source_port);
- packet->udp.dest = htobe16(destination_port);
-
- packet->udp.len = htobe16(len - DHCP_IP_SIZE);
-
- packet->ip.check = packet->udp.len;
- packet->udp.check = dhcp_packet_checksum((uint8_t*)&packet->ip.ttl, len - 8);
-
- packet->ip.ttl = IPDEFTTL;
- packet->ip.check = 0;
- packet->ip.check = dhcp_packet_checksum((uint8_t*)&packet->ip, DHCP_IP_SIZE);
-}
-
-int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
- size_t hdrlen;
-
- assert(packet);
-
- /* IP */
-
- if (packet->ip.version != IPVERSION) {
- log_debug("ignoring packet: not IPv4");
- return -EINVAL;
- }
-
- if (packet->ip.ihl < 5) {
- log_debug("ignoring packet: IPv4 IHL (%u words) invalid",
- packet->ip.ihl);
- return -EINVAL;
- }
-
- hdrlen = packet->ip.ihl * 4;
- if (hdrlen < 20) {
- log_debug("ignoring packet: IPv4 IHL (%zu bytes) "
- "smaller than minimum (20 bytes)", hdrlen);
- return -EINVAL;
- }
-
- if (len < hdrlen) {
- log_debug("ignoring packet: packet (%zu bytes) "
- "smaller than expected (%zu) by IP header", len,
- hdrlen);
- return -EINVAL;
- }
-
- /* UDP */
-
- if (packet->ip.protocol != IPPROTO_UDP) {
- log_debug("ignoring packet: not UDP");
- return -EINVAL;
- }
-
- if (len < hdrlen + be16toh(packet->udp.len)) {
- log_debug("ignoring packet: packet (%zu bytes) "
- "smaller than expected (%zu) by UDP header", len,
- hdrlen + be16toh(packet->udp.len));
- return -EINVAL;
- }
-
- if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
- log_debug("ignoring packet: to port %u, which "
- "is not the DHCP client port (%u)",
- be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
- return -EINVAL;
- }
-
- /* checksums - computing these is relatively expensive, so only do it
- if all the other checks have passed
- */
-
- if (dhcp_packet_checksum((uint8_t*)&packet->ip, hdrlen)) {
- log_debug("ignoring packet: invalid IP checksum");
- return -EINVAL;
- }
-
- if (checksum && packet->udp.check) {
- packet->ip.check = packet->udp.len;
- packet->ip.ttl = 0;
-
- if (dhcp_packet_checksum((uint8_t*)&packet->ip.ttl,
- be16toh(packet->udp.len) + 12)) {
- log_debug("ignoring packet: invalid UDP checksum");
- return -EINVAL;
- }
- }
-
- return 0;
-}
diff --git a/src/libsystemd-network/dhcp-protocol.h b/src/libsystemd-network/dhcp-protocol.h
deleted file mode 100644
index abca9422c5..0000000000
--- a/src/libsystemd-network/dhcp-protocol.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/udp.h>
-#include <netinet/ip.h>
-#include <stdint.h>
-
-#include "macro.h"
-#include "sparse-endian.h"
-
-struct DHCPMessage {
- uint8_t op;
- uint8_t htype;
- uint8_t hlen;
- uint8_t hops;
- be32_t xid;
- be16_t secs;
- be16_t flags;
- be32_t ciaddr;
- be32_t yiaddr;
- be32_t siaddr;
- be32_t giaddr;
- uint8_t chaddr[16];
- uint8_t sname[64];
- uint8_t file[128];
- be32_t magic;
- uint8_t options[0];
-} _packed_;
-
-typedef struct DHCPMessage DHCPMessage;
-
-struct DHCPPacket {
- struct iphdr ip;
- struct udphdr udp;
- DHCPMessage dhcp;
-} _packed_;
-
-typedef struct DHCPPacket DHCPPacket;
-
-#define DHCP_IP_SIZE (int32_t)(sizeof(struct iphdr))
-#define DHCP_IP_UDP_SIZE (int32_t)(sizeof(struct udphdr) + DHCP_IP_SIZE)
-#define DHCP_MESSAGE_SIZE (int32_t)(sizeof(DHCPMessage))
-#define DHCP_DEFAULT_MIN_SIZE 576 /* the minimum internet hosts must be able to receive */
-#define DHCP_MIN_OPTIONS_SIZE DHCP_DEFAULT_MIN_SIZE - DHCP_IP_UDP_SIZE - DHCP_MESSAGE_SIZE
-#define DHCP_MAGIC_COOKIE (uint32_t)(0x63825363)
-
-enum {
- DHCP_PORT_SERVER = 67,
- DHCP_PORT_CLIENT = 68,
-};
-
-enum DHCPState {
- DHCP_STATE_INIT = 0,
- DHCP_STATE_SELECTING = 1,
- DHCP_STATE_INIT_REBOOT = 2,
- DHCP_STATE_REBOOTING = 3,
- DHCP_STATE_REQUESTING = 4,
- DHCP_STATE_BOUND = 5,
- DHCP_STATE_RENEWING = 6,
- DHCP_STATE_REBINDING = 7,
- DHCP_STATE_STOPPED = 8,
-};
-
-typedef enum DHCPState DHCPState;
-
-enum {
- BOOTREQUEST = 1,
- BOOTREPLY = 2,
-};
-
-enum {
- DHCP_DISCOVER = 1,
- DHCP_OFFER = 2,
- DHCP_REQUEST = 3,
- DHCP_DECLINE = 4,
- DHCP_ACK = 5,
- DHCP_NAK = 6,
- DHCP_RELEASE = 7,
- DHCP_INFORM = 8,
- DHCP_FORCERENEW = 9,
-};
-
-enum {
- DHCP_OVERLOAD_FILE = 1,
- DHCP_OVERLOAD_SNAME = 2,
-};
-
-enum {
- DHCP_OPTION_PAD = 0,
- DHCP_OPTION_SUBNET_MASK = 1,
- DHCP_OPTION_TIME_OFFSET = 2,
- DHCP_OPTION_ROUTER = 3,
- DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
- DHCP_OPTION_HOST_NAME = 12,
- DHCP_OPTION_BOOT_FILE_SIZE = 13,
- DHCP_OPTION_DOMAIN_NAME = 15,
- DHCP_OPTION_ROOT_PATH = 17,
- DHCP_OPTION_ENABLE_IP_FORWARDING = 19,
- DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20,
- DHCP_OPTION_POLICY_FILTER = 21,
- DHCP_OPTION_INTERFACE_MDR = 22,
- DHCP_OPTION_INTERFACE_TTL = 23,
- DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
- DHCP_OPTION_INTERFACE_MTU = 26,
- DHCP_OPTION_BROADCAST = 28,
- DHCP_OPTION_STATIC_ROUTE = 33,
- DHCP_OPTION_NTP_SERVER = 42,
- DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
- DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
- DHCP_OPTION_OVERLOAD = 52,
- DHCP_OPTION_MESSAGE_TYPE = 53,
- DHCP_OPTION_SERVER_IDENTIFIER = 54,
- DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
- DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57,
- DHCP_OPTION_RENEWAL_T1_TIME = 58,
- DHCP_OPTION_REBINDING_T2_TIME = 59,
- DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
- DHCP_OPTION_CLIENT_IDENTIFIER = 61,
- DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
- DHCP_OPTION_END = 255,
-};
diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h
deleted file mode 100644
index 58750c4418..0000000000
--- a/src/libsystemd-network/dhcp-server-internal.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include "sd-event.h"
-#include "sd-dhcp-server.h"
-
-#include "hashmap.h"
-#include "refcnt.h"
-#include "util.h"
-#include "log.h"
-
-#include "dhcp-internal.h"
-
-typedef struct DHCPClientId {
- size_t length;
- uint8_t *data;
-} DHCPClientId;
-
-typedef struct DHCPLease {
- DHCPClientId client_id;
-
- be32_t address;
- be32_t gateway;
- uint8_t chaddr[16];
- usec_t expiration;
-} DHCPLease;
-
-struct sd_dhcp_server {
- RefCount n_ref;
-
- sd_event *event;
- int event_priority;
- sd_event_source *receive_message;
- int fd;
- int fd_raw;
-
- int index;
- be32_t address;
- be32_t netmask;
- be32_t pool_start;
- size_t pool_size;
- size_t next_offer;
-
- Hashmap *leases_by_client_id;
- DHCPLease **bound_leases;
-};
-
-typedef struct DHCPRequest {
- /* received message */
- DHCPMessage *message;
-
- /* options */
- DHCPClientId client_id;
- size_t max_optlen;
- be32_t server_id;
- be32_t requested_ip;
- int lifetime;
-} DHCPRequest;
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
-#define _cleanup_dhcp_server_unref_ _cleanup_(sd_dhcp_server_unrefp)
-
-#define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
-
-int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
- size_t length);
-int dhcp_server_send_packet(sd_dhcp_server *server,
- DHCPRequest *req, DHCPPacket *packet,
- int type, size_t optoffset);
-
-unsigned long client_id_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
-int client_id_compare_func(const void *_a, const void *_b);
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
deleted file mode 100644
index 4f54ad89a6..0000000000
--- a/src/libsystemd-network/dhcp6-internal.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <net/ethernet.h>
-#include <netinet/in.h>
-
-#include "sparse-endian.h"
-#include "sd-event.h"
-#include "list.h"
-#include "macro.h"
-
-typedef struct DHCP6Address DHCP6Address;
-
-struct DHCP6Address {
- LIST_FIELDS(DHCP6Address, addresses);
-
- struct {
- struct in6_addr address;
- be32_t lifetime_preferred;
- be32_t lifetime_valid;
- } iaaddr _packed_;
-};
-
-struct DHCP6IA {
- uint16_t type;
- struct {
- be32_t id;
- be32_t lifetime_t1;
- be32_t lifetime_t2;
- } _packed_;
- sd_event_source *timeout_t1;
- sd_event_source *timeout_t2;
-
- LIST_HEAD(DHCP6Address, addresses);
-};
-
-typedef struct DHCP6IA DHCP6IA;
-
-#define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
-
-int dhcp_network_icmp6_bind_router_solicitation(int index);
-int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
-
-int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
- size_t optlen, const void *optval);
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia);
-int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
- size_t *optlen, uint8_t **optvalue);
-int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
- DHCP6IA *ia);
-
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
-int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
- const void *packet, size_t len);
-
-const char *dhcp6_message_type_to_string(int s) _const_;
-int dhcp6_message_type_from_string(const char *s) _pure_;
-const char *dhcp6_message_status_to_string(int s) _const_;
-int dhcp6_message_status_from_string(const char *s) _pure_;
diff --git a/src/libsystemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/dhcp6-lease-internal.h
deleted file mode 100644
index 109e0f4f21..0000000000
--- a/src/libsystemd-network/dhcp6-lease-internal.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdint.h>
-
-#include "refcnt.h"
-
-#include "sd-dhcp6-lease.h"
-#include "dhcp6-internal.h"
-
-struct sd_dhcp6_lease {
- RefCount n_ref;
-
- uint8_t *serverid;
- size_t serverid_len;
- uint8_t preference;
- bool rapid_commit;
-
- DHCP6IA ia;
-
- DHCP6Address *addr_iter;
-};
-
-int dhcp6_lease_clear_timers(DHCP6IA *ia);
-int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire);
-DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia);
-
-int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
- size_t len);
-int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len);
-int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference);
-int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference);
-int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease);
-int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit);
-
-int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid);
-
-int dhcp6_lease_new(sd_dhcp6_lease **ret);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_lease*, sd_dhcp6_lease_unref);
-#define _cleanup_dhcp6_lease_free_ _cleanup_(sd_dhcp6_lease_unrefp)
diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c
deleted file mode 100644
index fe56c10273..0000000000
--- a/src/libsystemd-network/dhcp6-network.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <string.h>
-#include <linux/if_packet.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet/in.h>
-
-#include "socket-util.h"
-
-#include "dhcp6-internal.h"
-#include "dhcp6-protocol.h"
-
-#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
-
-#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
-
-int dhcp_network_icmp6_bind_router_solicitation(int index)
-{
- struct icmp6_filter filter = { };
- struct ipv6_mreq mreq = {
- .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
- .ipv6mr_interface = index,
- };
- _cleanup_close_ int s = -1;
- int r, zero = 0, hops = 255;
-
- s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK,
- IPPROTO_ICMPV6);
- if (s < 0)
- return -errno;
-
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
- r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
- sizeof(filter));
- if (r < 0)
- return -errno;
-
- /* RFC 3315, section 6.7, bullet point 2 may indicate that an
- IPV6_PKTINFO socket option also applies for ICMPv6 multicast.
- Empirical experiments indicates otherwise and therefore an
- IPV6_MULTICAST_IF socket option is used here instead */
- r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &index,
- sizeof(index));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &zero,
- sizeof(zero));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops,
- sizeof(hops));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
- sizeof(mreq));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
- return r;
-}
-
-int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr)
-{
- struct sockaddr_in6 dst = {
- .sin6_family = AF_INET6,
- .sin6_addr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
- };
- struct {
- struct nd_router_solicit rs;
- struct nd_opt_hdr rs_opt;
- struct ether_addr rs_opt_mac;
- } _packed_ rs = {
- .rs.nd_rs_type = ND_ROUTER_SOLICIT,
- };
- struct iovec iov[1] = {
- { &rs, },
- };
- struct msghdr msg = {
- .msg_name = &dst,
- .msg_namelen = sizeof(dst),
- .msg_iov = iov,
- .msg_iovlen = 1,
- };
- int r;
-
- if (ether_addr) {
- memcpy(&rs.rs_opt_mac, ether_addr, ETH_ALEN);
- rs.rs_opt.nd_opt_type = ND_OPT_SOURCE_LINKADDR;
- rs.rs_opt.nd_opt_len = 1;
- iov[0].iov_len = sizeof(rs);
- } else
- iov[0].iov_len = sizeof(rs.rs);
-
- r = sendmsg(s, &msg, 0);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
- struct in6_pktinfo pktinfo = {
- .ipi6_ifindex = index,
- };
- union sockaddr_union src = {
- .in6.sin6_family = AF_INET6,
- .in6.sin6_port = htobe16(DHCP6_PORT_CLIENT),
- .in6.sin6_addr = IN6ADDR_ANY_INIT,
- };
- _cleanup_close_ int s = -1;
- int r, off = 0, on = 1;
-
- if (local_address)
- memcpy(&src.in6.sin6_addr, local_address,
- sizeof(src.in6.sin6_addr));
-
- s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- IPPROTO_UDP);
- if (s < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &pktinfo,
- sizeof(pktinfo));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
- if (r < 0)
- return -errno;
-
- r = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off, sizeof(off));
- if (r < 0)
- return -errno;
-
- r = bind(s, &src.sa, sizeof(src.in6));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
- return r;
-}
-
-int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
- const void *packet, size_t len) {
- union sockaddr_union dest = {
- .in6.sin6_family = AF_INET6,
- .in6.sin6_port = htobe16(DHCP6_PORT_SERVER),
- };
- int r;
-
- assert(server_address);
-
- memcpy(&dest.in6.sin6_addr, server_address, sizeof(dest.in6.sin6_addr));
-
- r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in6));
- if (r < 0)
- return -errno;
-
- return 0;
-}
diff --git a/src/libsystemd-network/dhcp6-option.c b/src/libsystemd-network/dhcp6-option.c
deleted file mode 100644
index ea863f45e4..0000000000
--- a/src/libsystemd-network/dhcp6-option.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/in.h>
-#include <errno.h>
-#include <string.h>
-
-#include "sparse-endian.h"
-#include "unaligned.h"
-#include "util.h"
-
-#include "dhcp6-internal.h"
-#include "dhcp6-protocol.h"
-
-#define DHCP6_OPTION_IA_NA_LEN 12
-#define DHCP6_OPTION_IA_TA_LEN 4
-
-typedef struct DHCP6Option {
- be16_t code;
- be16_t len;
- uint8_t data[];
-} _packed_ DHCP6Option;
-
-static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode,
- size_t optlen) {
- DHCP6Option *option = (DHCP6Option*) *buf;
-
- assert_return(buf, -EINVAL);
- assert_return(*buf, -EINVAL);
- assert_return(buflen, -EINVAL);
-
- if (optlen > 0xffff || *buflen < optlen + sizeof(DHCP6Option))
- return -ENOBUFS;
-
- option->code = htobe16(optcode);
- option->len = htobe16(optlen);
-
- *buf += sizeof(DHCP6Option);
- *buflen -= sizeof(DHCP6Option);
-
- return 0;
-}
-
-int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
- size_t optlen, const void *optval) {
- int r;
-
- assert_return(optval || optlen == 0, -EINVAL);
-
- r = option_append_hdr(buf, buflen, code, optlen);
- if (r < 0)
- return r;
-
- if (optval)
- memcpy(*buf, optval, optlen);
-
- *buf += optlen;
- *buflen -= optlen;
-
- return 0;
-}
-
-int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia) {
- uint16_t len;
- uint8_t *ia_hdr;
- size_t ia_buflen, ia_addrlen = 0;
- DHCP6Address *addr;
- int r;
-
- assert_return(buf && *buf && buflen && ia, -EINVAL);
-
- switch (ia->type) {
- case DHCP6_OPTION_IA_NA:
- len = DHCP6_OPTION_IA_NA_LEN;
- break;
-
- case DHCP6_OPTION_IA_TA:
- len = DHCP6_OPTION_IA_TA_LEN;
- break;
-
- default:
- return -EINVAL;
- }
-
- if (*buflen < len)
- return -ENOBUFS;
-
- ia_hdr = *buf;
- ia_buflen = *buflen;
-
- *buf += sizeof(DHCP6Option);
- *buflen -= sizeof(DHCP6Option);
-
- memcpy(*buf, &ia->id, len);
-
- *buf += len;
- *buflen -= len;
-
- LIST_FOREACH(addresses, addr, ia->addresses) {
- r = option_append_hdr(buf, buflen, DHCP6_OPTION_IAADDR,
- sizeof(addr->iaaddr));
- if (r < 0)
- return r;
-
- memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr));
-
- *buf += sizeof(addr->iaaddr);
- *buflen -= sizeof(addr->iaaddr);
-
- ia_addrlen += sizeof(DHCP6Option) + sizeof(addr->iaaddr);
- }
-
- r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-
-static int option_parse_hdr(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen) {
- DHCP6Option *option = (DHCP6Option*) *buf;
- uint16_t len;
-
- assert_return(buf, -EINVAL);
- assert_return(optcode, -EINVAL);
- assert_return(optlen, -EINVAL);
-
- if (*buflen < sizeof(DHCP6Option))
- return -ENOMSG;
-
- len = be16toh(option->len);
-
- if (len > *buflen)
- return -ENOMSG;
-
- *optcode = be16toh(option->code);
- *optlen = len;
-
- *buf += 4;
- *buflen -= 4;
-
- return 0;
-}
-
-int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
- size_t *optlen, uint8_t **optvalue) {
- int r;
-
- assert_return(buf && buflen && optcode && optlen && optvalue, -EINVAL);
-
- r = option_parse_hdr(buf, buflen, optcode, optlen);
- if (r < 0)
- return r;
-
- if (*optlen > *buflen)
- return -ENOBUFS;
-
- *optvalue = *buf;
- *buflen -= *optlen;
- *buf += *optlen;
-
- return 0;
-}
-
-int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype,
- DHCP6IA *ia) {
- int r;
- uint16_t opt, status;
- size_t optlen;
- size_t iaaddr_offset;
- DHCP6Address *addr;
- uint32_t lt_t1, lt_t2, lt_valid, lt_pref, lt_min = ~0;
-
- assert_return(ia, -EINVAL);
- assert_return(!ia->addresses, -EINVAL);
-
- switch (iatype) {
- case DHCP6_OPTION_IA_NA:
-
- if (*buflen < DHCP6_OPTION_IA_NA_LEN + sizeof(DHCP6Option) +
- sizeof(addr->iaaddr)) {
- r = -ENOBUFS;
- goto error;
- }
-
- iaaddr_offset = DHCP6_OPTION_IA_NA_LEN;
- memcpy(&ia->id, *buf, iaaddr_offset);
-
- lt_t1 = be32toh(ia->lifetime_t1);
- lt_t2 = be32toh(ia->lifetime_t2);
-
- if (lt_t1 && lt_t2 && lt_t1 > lt_t2) {
- log_dhcp6_client(client, "IA T1 %ds > T2 %ds",
- lt_t1, lt_t2);
- r = -EINVAL;
- goto error;
- }
-
- break;
-
- case DHCP6_OPTION_IA_TA:
- if (*buflen < DHCP6_OPTION_IA_TA_LEN + sizeof(DHCP6Option) +
- sizeof(addr->iaaddr)) {
- r = -ENOBUFS;
- goto error;
- }
-
- iaaddr_offset = DHCP6_OPTION_IA_TA_LEN;
- memcpy(&ia->id, *buf, iaaddr_offset);
-
- ia->lifetime_t1 = 0;
- ia->lifetime_t2 = 0;
-
- break;
-
- default:
- r = -ENOMSG;
- goto error;
- }
-
- ia->type = iatype;
-
- *buflen -= iaaddr_offset;
- *buf += iaaddr_offset;
-
- while ((r = option_parse_hdr(buf, buflen, &opt, &optlen)) >= 0) {
-
- switch (opt) {
- case DHCP6_OPTION_IAADDR:
-
- addr = new0(DHCP6Address, 1);
- if (!addr) {
- r = -ENOMEM;
- goto error;
- }
-
- LIST_INIT(addresses, addr);
-
- memcpy(&addr->iaaddr, *buf, sizeof(addr->iaaddr));
-
- lt_valid = be32toh(addr->iaaddr.lifetime_valid);
- lt_pref = be32toh(addr->iaaddr.lifetime_valid);
-
- if (!lt_valid || lt_pref > lt_valid) {
- log_dhcp6_client(client, "IA preferred %ds > valid %ds",
- lt_pref, lt_valid);
- free(addr);
- } else {
- LIST_PREPEND(addresses, ia->addresses, addr);
- if (lt_valid < lt_min)
- lt_min = lt_valid;
- }
-
- break;
-
- case DHCP6_OPTION_STATUS_CODE:
- if (optlen < sizeof(status))
- break;
-
- status = (*buf)[0] << 8 | (*buf)[1];
- if (status) {
- log_dhcp6_client(client, "IA status %d",
- status);
- r = -EINVAL;
- goto error;
- }
-
- break;
-
- default:
- log_dhcp6_client(client, "Unknown IA option %d", opt);
- break;
- }
-
- *buflen -= optlen;
- *buf += optlen;
- }
-
- if (r == -ENOMSG)
- r = 0;
-
- if (!ia->lifetime_t1 && !ia->lifetime_t2) {
- lt_t1 = lt_min / 2;
- lt_t2 = lt_min / 10 * 8;
- ia->lifetime_t1 = htobe32(lt_t1);
- ia->lifetime_t2 = htobe32(lt_t2);
-
- log_dhcp6_client(client, "Computed IA T1 %ds and T2 %ds as both were zero",
- lt_t1, lt_t2);
- }
-
- if (*buflen)
- r = -ENOMSG;
-
-error:
- *buf += *buflen;
- *buflen = 0;
-
- return r;
-}
diff --git a/src/libsystemd-network/dhcp6-protocol.h b/src/libsystemd-network/dhcp6-protocol.h
deleted file mode 100644
index 3e0f339237..0000000000
--- a/src/libsystemd-network/dhcp6-protocol.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-
-#include "macro.h"
-#include "sparse-endian.h"
-
-struct DHCP6Message {
- union {
- struct {
- uint8_t type;
- uint8_t _pad[3];
- } _packed_;
- be32_t transaction_id;
- };
-} _packed_;
-
-typedef struct DHCP6Message DHCP6Message;
-
-#define DHCP6_MIN_OPTIONS_SIZE \
- 1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr)
-
-#define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT \
- { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } }
-
-enum {
- DHCP6_PORT_SERVER = 547,
- DHCP6_PORT_CLIENT = 546,
-};
-
-#define DHCP6_INF_TIMEOUT 1 * USEC_PER_SEC
-#define DHCP6_INF_MAX_RT 120 * USEC_PER_SEC
-#define DHCP6_SOL_MAX_DELAY 1 * USEC_PER_SEC
-#define DHCP6_SOL_TIMEOUT 1 * USEC_PER_SEC
-#define DHCP6_SOL_MAX_RT 120 * USEC_PER_SEC
-#define DHCP6_REQ_TIMEOUT 1 * USEC_PER_SEC
-#define DHCP6_REQ_MAX_RT 120 * USEC_PER_SEC
-#define DHCP6_REQ_MAX_RC 10
-#define DHCP6_REN_TIMEOUT 10 * USEC_PER_SEC
-#define DHCP6_REN_MAX_RT 600 * USEC_PER_SEC
-#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC
-#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC
-
-enum {
- DHCP6_DUID_LLT = 1,
- DHCP6_DUID_EN = 2,
- DHCP6_DUID_LL = 3,
- DHCP6_DUID_UUID = 4,
-};
-
-enum DHCP6State {
- DHCP6_STATE_STOPPED = 0,
- DHCP6_STATE_INFORMATION_REQUEST = 1,
- DHCP6_STATE_SOLICITATION = 2,
- DHCP6_STATE_REQUEST = 3,
- DHCP6_STATE_BOUND = 4,
- DHCP6_STATE_RENEW = 5,
- DHCP6_STATE_REBIND = 6,
-};
-
-enum {
- DHCP6_SOLICIT = 1,
- DHCP6_ADVERTISE = 2,
- DHCP6_REQUEST = 3,
- DHCP6_CONFIRM = 4,
- DHCP6_RENEW = 5,
- DHCP6_REBIND = 6,
- DHCP6_REPLY = 7,
- DHCP6_RELEASE = 8,
- DHCP6_DECLINE = 9,
- DHCP6_RECONFIGURE = 10,
- DHCP6_INFORMATION_REQUEST = 11,
- DHCP6_RELAY_FORW = 12,
- DHCP6_RELAY_REPL = 13,
- _DHCP6_MESSAGE_MAX = 14,
-};
-
-enum {
- DHCP6_OPTION_CLIENTID = 1,
- DHCP6_OPTION_SERVERID = 2,
- DHCP6_OPTION_IA_NA = 3,
- DHCP6_OPTION_IA_TA = 4,
- DHCP6_OPTION_IAADDR = 5,
- DHCP6_OPTION_ORO = 6,
- DHCP6_OPTION_PREFERENCE = 7,
- DHCP6_OPTION_ELAPSED_TIME = 8,
- DHCP6_OPTION_RELAY_MSG = 9,
- /* option code 10 is unassigned */
- DHCP6_OPTION_AUTH = 11,
- DHCP6_OPTION_UNICAST = 12,
- DHCP6_OPTION_STATUS_CODE = 13,
- DHCP6_OPTION_RAPID_COMMIT = 14,
- DHCP6_OPTION_USER_CLASS = 15,
- DHCP6_OPTION_VENDOR_CLASS = 16,
- DHCP6_OPTION_VENDOR_OPTS = 17,
- DHCP6_OPTION_INTERFACE_ID = 18,
- DHCP6_OPTION_RECONF_MSG = 19,
- DHCP6_OPTION_RECONF_ACCEPT = 20,
-
- DHCP6_OPTION_DNS_SERVERS = 23, /* RFC 3646 */
- DHCP6_OPTION_DOMAIN_LIST = 24, /* RFC 3646 */
-
- DHCP6_OPTION_SNTP_SERVERS = 31, /* RFC 4075 */
-
- /* option code 35 is unassigned */
-
- DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
-
- /* option codes 89-142 are unassigned */
- /* option codes 144-65535 are unassigned */
-};
-
-enum {
- DHCP6_STATUS_SUCCESS = 0,
- DHCP6_STATUS_UNSPEC_FAIL = 1,
- DHCP6_STATUS_NO_ADDRS_AVAIL = 2,
- DHCP6_STATUS_NO_BINDING = 3,
- DHCP6_STATUS_NOT_ON_LINK = 4,
- DHCP6_STATUS_USE_MULTICAST = 5,
- _DHCP6_STATUS_MAX = 6,
-};
diff --git a/src/libsystemd-network/ipv4ll-internal.h b/src/libsystemd-network/ipv4ll-internal.h
deleted file mode 100644
index ae0ce43985..0000000000
--- a/src/libsystemd-network/ipv4ll-internal.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Axis Communications AB. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/if_ether.h>
-
-#include "sparse-endian.h"
-#include "socket-util.h"
-
-int arp_network_bind_raw_socket(int index, union sockaddr_union *link);
-int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
- const struct ether_arp *arp);
-
-void arp_packet_init(struct ether_arp *arp);
-void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
-void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
-int arp_packet_verify_headers(struct ether_arp *arp);
-
-#define log_ipv4ll(ll, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/ipv4ll-network.c b/src/libsystemd-network/ipv4ll-network.c
deleted file mode 100644
index 93ffed408f..0000000000
--- a/src/libsystemd-network/ipv4ll-network.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Axis Communications AB. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <linux/filter.h>
-
-#include "util.h"
-#include "ipv4ll-internal.h"
-
-int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
- const struct ether_arp *arp) {
- int r;
-
- assert(arp);
- assert(link);
- assert(fd >= 0);
-
- r = sendto(fd, arp, sizeof(struct ether_arp), 0, &link->sa, sizeof(link->ll));
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-int arp_network_bind_raw_socket(int ifindex, union sockaddr_union *link) {
-
- static const struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
- BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct ether_arp), 1, 0), /* packet >= arp packet ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hrd)), /* A <- header */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0), /* header == ethernet ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pro)), /* A <- protocol */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 1, 0), /* protocol == IP ? */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_op)), /* A <- operation */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 0, 1), /* protocol == request ? */
- BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 0, 1), /* protocol == reply ? */
- BPF_STMT(BPF_RET + BPF_K, 65535), /* return all */
- BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
- };
- struct sock_fprog fprog = {
- .len = ELEMENTSOF(filter),
- .filter = (struct sock_filter*) filter
- };
- _cleanup_close_ int s = -1;
- int r;
-
- assert(ifindex > 0);
- assert(link);
-
- s = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
- if (s < 0)
- return -errno;
-
- r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
- if (r < 0)
- return -errno;
-
- link->ll.sll_family = AF_PACKET;
- link->ll.sll_protocol = htons(ETH_P_ARP);
- link->ll.sll_ifindex = ifindex;
- link->ll.sll_halen = ETH_ALEN;
- memset(link->ll.sll_addr, 0xff, ETH_ALEN);
-
- r = bind(s, &link->sa, sizeof(link->ll));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
-
- return r;
-}
diff --git a/src/libsystemd-network/ipv4ll-packet.c b/src/libsystemd-network/ipv4ll-packet.c
deleted file mode 100644
index 2b6c73ab4b..0000000000
--- a/src/libsystemd-network/ipv4ll-packet.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Axis Communications AB. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-#include <arpa/inet.h>
-
-#include "util.h"
-#include "ipv4ll-internal.h"
-
-void arp_packet_init(struct ether_arp *arp) {
- assert(arp);
-
- memzero(arp, sizeof(struct ether_arp));
- /* Header */
- arp->ea_hdr.ar_hrd = htons(ARPHRD_ETHER); /* HTYPE */
- arp->ea_hdr.ar_pro = htons(ETHERTYPE_IP); /* PTYPE */
- arp->ea_hdr.ar_hln = ETH_ALEN; /* HLEN */
- arp->ea_hdr.ar_pln = sizeof arp->arp_spa; /* PLEN */
- arp->ea_hdr.ar_op = htons(ARPOP_REQUEST); /* REQUEST */
-}
-
-void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha) {
- assert(ha);
-
- arp_packet_init(arp);
- memcpy(arp->arp_sha, ha, ETH_ALEN);
- memcpy(arp->arp_tpa, &pa, sizeof(pa));
-}
-
-void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha) {
- assert(ha);
-
- arp_packet_init(arp);
- memcpy(arp->arp_sha, ha, ETH_ALEN);
- memcpy(arp->arp_tpa, &pa, sizeof(pa));
- memcpy(arp->arp_spa, &pa, sizeof(pa));
-}
-
-int arp_packet_verify_headers(struct ether_arp *arp) {
- assert(arp);
-
- if (arp->ea_hdr.ar_hrd != htons(ARPHRD_ETHER)) {
- log_ipv4ll(NULL, "ignoring packet: header is not ARPHRD_ETHER");
- return -EINVAL;
- }
- if (arp->ea_hdr.ar_pro != htons(ETHERTYPE_IP)) {
- log_ipv4ll(NULL, "ignoring packet: protocol is not ETHERTYPE_IP");
- return -EINVAL;
- }
- if (arp->ea_hdr.ar_op != htons(ARPOP_REQUEST) &&
- arp->ea_hdr.ar_op != htons(ARPOP_REPLY)) {
- log_ipv4ll(NULL, "ignoring packet: operation is not ARPOP_REQUEST or ARPOP_REPLY");
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-internal.c b/src/libsystemd-network/lldp-internal.c
deleted file mode 100644
index 0f354461f7..0000000000
--- a/src/libsystemd-network/lldp-internal.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "lldp-internal.h"
-
-/* We store maximum 1K chassis entries */
-#define LLDP_MIB_MAX_CHASSIS 1024
-
-/* Maximum Ports can be attached to any chassis */
-#define LLDP_MIB_MAX_PORT_PER_CHASSIS 32
-
-int lldp_read_chassis_id(tlv_packet *tlv,
- uint8_t *type,
- uint16_t *length,
- uint8_t **data) {
- uint8_t subtype;
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_CHASSIS_ID);
- if (r < 0)
- goto out2;
-
- r = tlv_packet_read_u8(tlv, &subtype);
- if (r < 0)
- goto out1;
-
- switch (subtype) {
- case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
-
- r = tlv_packet_read_bytes(tlv, data, length);
- if (r < 0)
- goto out1;
-
- break;
- default:
- r = -EOPNOTSUPP;
- break;
- }
-
- *type = subtype;
-
- out1:
- (void) lldp_tlv_packet_exit_container(tlv);
-
- out2:
- return r;
-}
-
-int lldp_read_port_id(tlv_packet *tlv,
- uint8_t *type,
- uint16_t *length,
- uint8_t **data) {
- uint8_t subtype;
- char *s;
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_ID);
- if (r < 0)
- goto out2;
-
- r = tlv_packet_read_u8(tlv, &subtype);
- if (r < 0)
- goto out1;
-
- switch (subtype) {
- case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
- case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
- case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
- case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out1;
-
- *data = (uint8_t *) s;
-
- break;
- case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
-
- r = tlv_packet_read_bytes(tlv, data, length);
- if (r < 0)
- goto out1;
-
- break;
- default:
- r = -EOPNOTSUPP;
- break;
- }
-
- *type = subtype;
-
- out1:
- (void) lldp_tlv_packet_exit_container(tlv);
-
- out2:
- return r;
-}
-
-int lldp_read_ttl(tlv_packet *tlv, uint16_t *ttl) {
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_TTL);
- if (r < 0)
- goto out;
-
- r = tlv_packet_read_u16(tlv, ttl);
-
- (void) lldp_tlv_packet_exit_container(tlv);
-
- out:
- return r;
-}
-
-int lldp_read_system_name(tlv_packet *tlv,
- uint16_t *length,
- char **data) {
- char *s;
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_NAME);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out;
-
- *data = (char *) s;
-
- out:
- (void) lldp_tlv_packet_exit_container(tlv);
-
- return r;
-}
-
-int lldp_read_system_description(tlv_packet *tlv,
- uint16_t *length,
- char **data) {
- char *s;
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_DESCRIPTION);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out;
-
- *data = (char *) s;
-
- out:
- (void) lldp_tlv_packet_exit_container(tlv);
-
- return r;
-}
-
-int lldp_read_port_description(tlv_packet *tlv,
- uint16_t *length,
- char **data) {
- char *s;
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_PORT_DESCRIPTION);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_string(tlv, &s, length);
- if (r < 0)
- goto out;
-
- *data = (char *) s;
-
- out:
- (void) lldp_tlv_packet_exit_container(tlv);
-
- return r;
-}
-
-int lldp_read_system_capability(tlv_packet *tlv, uint16_t *data) {
- int r;
-
- assert_return(tlv, -EINVAL);
-
- r = lldp_tlv_packet_enter_container(tlv, LLDP_TYPE_SYSTEM_CAPABILITIES);
- if (r < 0)
- return r;
-
- r = tlv_packet_read_u16(tlv, data);
- if (r < 0)
- goto out;
-
- return 0;
- out:
-
- (void) lldp_tlv_packet_exit_container(tlv);
-
- return r;
-}
-
-/* 10.5.5.2.2 mibUpdateObjects ()
- * The mibUpdateObjects () procedure updates the MIB objects corresponding to
- * the TLVs contained in the received LLDPDU for the LLDP remote system
- * indicated by the LLDP remote systems update process defined in 10.3.5 */
-
-int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv) {
- lldp_neighbour_port *p;
- uint16_t length, ttl;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert_return(c, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = lldp_read_port_id(tlv, &type, &length, &data);
- if (r < 0)
- return r;
-
- /* Update the packet if we already have */
- LIST_FOREACH(port, p, c->ports) {
-
- if ((p->type == type && p->length == length && !memcmp(p->data, data, p->length))) {
-
- r = lldp_read_ttl(tlv, &ttl);
- if (r < 0)
- return r;
-
- p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
- tlv_packet_free(p->packet);
- p->packet = tlv;
-
- prioq_reshuffle(p->c->by_expiry, p, &p->prioq_idx);
-
- return 0;
- }
- }
-
- return -1;
-}
-
-int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv) {
- lldp_neighbour_port *p, *q;
- uint8_t *data;
- uint16_t length;
- uint8_t type;
- int r;
-
- assert_return(c, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = lldp_read_port_id(tlv, &type, &length, &data);
- if (r < 0)
- return r;
-
- LIST_FOREACH_SAFE(port, p, q, c->ports) {
-
- /* Find the port */
- if (p->type == type && p->length == length && !memcmp(p->data, data, p->length)) {
- lldp_neighbour_port_remove_and_free(p);
- break;
- }
- }
-
- return 0;
-}
-
-int lldp_mib_add_objects(Prioq *by_expiry,
- Hashmap *neighbour_mib,
- tlv_packet *tlv) {
- _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
- _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
- lldp_chassis_id chassis_id;
- bool new_chassis = false;
- uint8_t subtype, *data;
- uint16_t ttl, length;
- int r;
-
- assert_return(by_expiry, -EINVAL);
- assert_return(neighbour_mib, -EINVAL);
- assert_return(tlv, -EINVAL);
-
- r = lldp_read_chassis_id(tlv, &subtype, &length, &data);
- if (r < 0)
- goto drop;
-
- r = lldp_read_ttl(tlv, &ttl);
- if (r < 0)
- goto drop;
-
- /* Make hash key */
- chassis_id.type = subtype;
- chassis_id.length = length;
- chassis_id.data = data;
-
- /* Try to find the Chassis */
- c = hashmap_get(neighbour_mib, &chassis_id);
- if (!c) {
-
- /* Don't create chassis if ttl 0 is received . Silently drop it */
- if (ttl == 0) {
- log_lldp("TTL value 0 received. Skiping Chassis creation.");
- goto drop;
- }
-
- /* Admission Control: Can we store this packet ? */
- if (hashmap_size(neighbour_mib) >= LLDP_MIB_MAX_CHASSIS) {
-
- log_lldp("Exceeding number of chassie: %d. Dropping ...",
- hashmap_size(neighbour_mib));
- goto drop;
- }
-
- r = lldp_chassis_new(tlv, by_expiry, neighbour_mib, &c);
- if (r < 0)
- goto drop;
-
- new_chassis = true;
-
- r = hashmap_put(neighbour_mib, &c->chassis_id, c);
- if (r < 0)
- goto drop;
-
- } else {
-
- /* When the TTL field is set to zero, the receiving LLDP agent is notified all
- * system information associated with the LLDP agent/port is to be deleted */
- if (ttl == 0) {
- log_lldp("TTL value 0 received . Deleting associated Port ...");
-
- lldp_mib_remove_objects(c, tlv);
-
- c = NULL;
- goto drop;
- }
-
- /* if we already have this port just update it */
- r = lldp_mib_update_objects(c, tlv);
- if (r >= 0) {
- c = NULL;
- return r;
- }
-
- /* Admission Control: Can this port attached to the existing chassis ? */
- if (REFCNT_GET(c->n_ref) >= LLDP_MIB_MAX_PORT_PER_CHASSIS) {
- log_lldp("Port limit reached. Chassis has: %d ports. Dropping ...",
- REFCNT_GET(c->n_ref));
-
- c = NULL;
- goto drop;
- }
- }
-
- /* This is a new port */
- r = lldp_neighbour_port_new(c, tlv, &p);
- if (r < 0)
- goto drop;
-
- r = prioq_put(c->by_expiry, p, &p->prioq_idx);
- if (r < 0)
- goto drop;
-
- /* Attach new port to chassis */
- LIST_PREPEND(port, c->ports, p);
- REFCNT_INC(c->n_ref);
-
- p = NULL;
- c = NULL;
-
- return 0;
-
- drop:
- tlv_packet_free(tlv);
-
- if (new_chassis)
- hashmap_remove(neighbour_mib, &c->chassis_id);
-
- return r;
-}
-
-void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p) {
- lldp_chassis *c;
-
- assert(p);
- assert(p->c);
-
- c = p->c;
-
- prioq_remove(c->by_expiry, p, &p->prioq_idx);
-
- LIST_REMOVE(port, c->ports, p);
- lldp_neighbour_port_free(p);
-
- /* Drop the Chassis if no port is attached */
- if (REFCNT_DEC(c->n_ref) <= 1) {
- hashmap_remove(c->neighbour_mib, &c->chassis_id);
- lldp_chassis_free(c);
- }
-}
-
-void lldp_neighbour_port_free(lldp_neighbour_port *p) {
-
- if(!p)
- return;
-
- tlv_packet_free(p->packet);
-
- free(p->data);
- free(p);
-}
-
-int lldp_neighbour_port_new(lldp_chassis *c,
- tlv_packet *tlv,
- lldp_neighbour_port **ret) {
- _cleanup_lldp_neighbour_port_free_ lldp_neighbour_port *p = NULL;
- uint16_t length, ttl;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert(tlv);
-
- r = lldp_read_port_id(tlv, &type, &length, &data);
- if (r < 0)
- return r;
-
- r = lldp_read_ttl(tlv, &ttl);
- if (r < 0)
- return r;
-
- p = new0(lldp_neighbour_port, 1);
- if (!p)
- return -ENOMEM;
-
- p->c = c;
- p->type = type;
- p->length = length;
- p->packet = tlv;
- p->prioq_idx = PRIOQ_IDX_NULL;
- p->until = ttl * USEC_PER_SEC + now(clock_boottime_or_monotonic());
-
- p->data = memdup(data, length);
- if (!p->data)
- return -ENOMEM;
-
- *ret = p;
- p = NULL;
-
- return 0;
-}
-
-void lldp_chassis_free(lldp_chassis *c) {
-
- if (!c)
- return;
-
- if (REFCNT_GET(c->n_ref) > 1)
- return;
-
- free(c->chassis_id.data);
- free(c);
-}
-
-int lldp_chassis_new(tlv_packet *tlv,
- Prioq *by_expiry,
- Hashmap *neighbour_mib,
- lldp_chassis **ret) {
- _cleanup_lldp_chassis_free_ lldp_chassis *c = NULL;
- uint16_t length;
- uint8_t *data;
- uint8_t type;
- int r;
-
- assert(tlv);
-
- r = lldp_read_chassis_id(tlv, &type, &length, &data);
- if (r < 0)
- return r;
-
- c = new0(lldp_chassis, 1);
- if (!c)
- return -ENOMEM;
-
- c->n_ref = REFCNT_INIT;
- c->chassis_id.type = type;
- c->chassis_id.length = length;
-
- c->chassis_id.data = memdup(data, length);
- if (!c->chassis_id.data)
- return -ENOMEM;
-
- LIST_HEAD_INIT(c->ports);
-
- c->by_expiry = by_expiry;
- c->neighbour_mib = neighbour_mib;
-
- *ret = c;
- c = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-internal.h b/src/libsystemd-network/lldp-internal.h
deleted file mode 100644
index 8e09ee8f3a..0000000000
--- a/src/libsystemd-network/lldp-internal.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include "log.h"
-#include "list.h"
-#include "refcnt.h"
-#include "lldp-tlv.h"
-#include "prioq.h"
-
-typedef struct lldp_neighbour_port lldp_neighbour_port;
-typedef struct lldp_chassis lldp_chassis;
-typedef struct lldp_chassis_id lldp_chassis_id;
-typedef struct lldp_agent_statistics lldp_agent_statistics;
-
-struct lldp_neighbour_port {
- uint8_t type;
- uint8_t *data;
-
- uint16_t length;
- usec_t until;
-
- unsigned prioq_idx;
-
- lldp_chassis *c;
- tlv_packet *packet;
-
- LIST_FIELDS(lldp_neighbour_port, port);
-};
-
-int lldp_neighbour_port_new(lldp_chassis *c, tlv_packet *tlv, lldp_neighbour_port **ret);
-void lldp_neighbour_port_free(lldp_neighbour_port *p);
-void lldp_neighbour_port_remove_and_free(lldp_neighbour_port *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_neighbour_port *, lldp_neighbour_port_free);
-#define _cleanup_lldp_neighbour_port_free_ _cleanup_(lldp_neighbour_port_freep)
-
-struct lldp_chassis_id {
- uint8_t type;
- uint16_t length;
-
- uint8_t *data;
-};
-
-struct lldp_chassis {
- RefCount n_ref;
-
- lldp_chassis_id chassis_id;
-
- Prioq *by_expiry;
- Hashmap *neighbour_mib;
-
- LIST_HEAD(lldp_neighbour_port, ports);
-};
-
-int lldp_chassis_new(tlv_packet *tlv,
- Prioq *by_expiry,
- Hashmap *neighbour_mib,
- lldp_chassis **ret);
-
-void lldp_chassis_free(lldp_chassis *c);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_chassis *, lldp_chassis_free);
-#define _cleanup_lldp_chassis_free_ _cleanup_(lldp_chassis_freep)
-
-int lldp_mib_update_objects(lldp_chassis *c, tlv_packet *tlv);
-int lldp_mib_add_objects(Prioq *by_expiry, Hashmap *neighbour_mib, tlv_packet *tlv);
-int lldp_mib_remove_objects(lldp_chassis *c, tlv_packet *tlv);
-
-int lldp_read_chassis_id(tlv_packet *tlv, uint8_t *type, uint16_t *length, uint8_t **data);
-int lldp_read_port_id(tlv_packet *tlv, uint8_t *type, uint16_t *length, uint8_t **data);
-int lldp_read_ttl(tlv_packet *tlv, uint16_t *ttl);
-int lldp_read_system_name(tlv_packet *tlv, uint16_t *length, char **data);
-int lldp_read_system_description(tlv_packet *tlv, uint16_t *length, char **data);
-int lldp_read_system_capability(tlv_packet *tlv, uint16_t *data);
-int lldp_read_port_description(tlv_packet *tlv, uint16_t *length, char **data);
-
-int lldp_handle_packet(tlv_packet *m, uint16_t length);
-#define log_lldp(fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__)
diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c
deleted file mode 100644
index 664d2f7867..0000000000
--- a/src/libsystemd-network/lldp-network.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <linux/filter.h>
-#include <linux/if_ether.h>
-
-#include "socket-util.h"
-#include "lldp-tlv.h"
-#include "lldp-network.h"
-#include "lldp-internal.h"
-
-int lldp_network_bind_raw_socket(int ifindex) {
- typedef struct LLDPFrame {
- struct ethhdr hdr;
- uint8_t tlvs[0];
- } LLDPFrame;
-
- struct sock_filter filter[] = {
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest)), /* A <- 4 bytes of destination MAC */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0180c200, 1, 0), /* A != 01:80:c2:00 */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_dest) + 4), /* A <- remaining 2 bytes of destination MAC */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0000, 3, 0), /* A != 00:00 */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x0003, 2, 0), /* A != 00:03 */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0x000e, 1, 0), /* A != 00:0e */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(LLDPFrame, hdr.h_proto)), /* A <- protocol */
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_LLDP, 1, 0), /* A != ETHERTYPE_LLDP */
- BPF_STMT(BPF_RET + BPF_K, 0), /* drop packet */
- BPF_STMT(BPF_RET + BPF_K, (uint32_t) -1), /* accept packet */
- };
-
- struct sock_fprog fprog = {
- .len = ELEMENTSOF(filter),
- .filter = filter
- };
-
- _cleanup_close_ int s = -1;
-
- union sockaddr_union saddrll = {
- .ll.sll_family = AF_PACKET,
- .ll.sll_ifindex = ifindex,
- };
-
- int r;
-
- assert(ifindex > 0);
-
- s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (s < 0)
- return -errno;
-
- r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
- if (r < 0)
- return -errno;
-
- r = bind(s, &saddrll.sa, sizeof(saddrll.ll));
- if (r < 0)
- return -errno;
-
- r = s;
- s = -1;
-
- return r;
-}
-
-int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- _cleanup_tlv_packet_free_ tlv_packet *packet = NULL;
- tlv_packet *p;
- uint16_t length;
- int r;
-
- assert(fd);
- assert(userdata);
-
- r = tlv_packet_new(&packet);
- if (r < 0)
- return r;
-
- length = read(fd, &packet->pdu, sizeof(packet->pdu));
-
- /* Silently drop the packet */
- if ((size_t) length > ETHER_MAX_LEN)
- return 0;
-
- packet->userdata = userdata;
-
- p = packet;
- packet = NULL;
-
- return lldp_handle_packet(p, (uint16_t) length);
-}
diff --git a/src/libsystemd-network/lldp-network.h b/src/libsystemd-network/lldp-network.h
deleted file mode 100644
index b7f8d3bf80..0000000000
--- a/src/libsystemd-network/lldp-network.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include "sd-event.h"
-
-int lldp_network_bind_raw_socket(int ifindex);
-int lldp_receive_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata);
diff --git a/src/libsystemd-network/lldp-port.c b/src/libsystemd-network/lldp-port.c
deleted file mode 100644
index aa6a3b9224..0000000000
--- a/src/libsystemd-network/lldp-port.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "async.h"
-#include "lldp-port.h"
-#include "lldp-network.h"
-
-int lldp_port_start(lldp_port *p) {
- int r;
-
- assert_return(p, -EINVAL);
-
- r = lldp_network_bind_raw_socket(p->ifindex);
- if (r < 0)
- return r;
-
- p->rawfd = r;
-
- r = sd_event_add_io(p->event, &p->lldp_port_rx,
- p->rawfd, EPOLLIN, lldp_receive_packet, p);
- if (r < 0) {
- log_debug("Failed to allocate event source: %s", strerror(-r));
- return r;
- }
-
- r = sd_event_source_set_priority(p->lldp_port_rx, p->event_priority);
- if (r < 0) {
- log_debug("Failed to set event priority: %s", strerror(-r));
- goto fail;
- }
-
- r = sd_event_source_set_description(p->lldp_port_rx, "lldp-port-rx");
- if (r < 0) {
- log_debug("Failed to set event name: %s", strerror(-r));
- goto fail;
- }
-
- return 0;
-
-fail:
- lldp_port_stop(p);
-
- return r;
-}
-
-int lldp_port_stop(lldp_port *p) {
-
- assert_return(p, -EINVAL);
-
- p->rawfd = asynchronous_close(p->rawfd);
- p->lldp_port_rx = sd_event_source_unref(p->lldp_port_rx);
-
- return 0;
-}
-
-void lldp_port_free(lldp_port *p) {
- if (!p)
- return;
-
- lldp_port_stop(p);
-
- free(p->ifname);
- free(p);
-}
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret) {
- _cleanup_free_ lldp_port *p = NULL;
-
- assert_return(ifindex, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(addr, -EINVAL);
-
- p = new0(lldp_port, 1);
- if (!p)
- return -ENOMEM;
-
- p->rawfd = -1;
- p->ifindex = ifindex;
-
- p->ifname = strdup(ifname);
- if (!p->ifname)
- return -ENOMEM;
-
- memcpy(&p->mac, addr, ETH_ALEN);
-
- p->userdata = userdata;
-
- *ret = p;
-
- p = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-port.h b/src/libsystemd-network/lldp-port.h
deleted file mode 100644
index b2d3180091..0000000000
--- a/src/libsystemd-network/lldp-port.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include <net/ethernet.h>
-
-#include "sd-event.h"
-#include "sd-lldp.h"
-
-#include "util.h"
-
-typedef struct lldp_port lldp_port;
-
-struct lldp_port {
- LLDPPortStatus status;
-
- int ifindex;
- char *ifname;
-
- struct ether_addr mac;
-
- int rawfd;
-
- sd_event *event;
- sd_event_source *lldp_port_rx;
-
- int event_priority;
-
- void *userdata;
-};
-
-int lldp_port_new(int ifindex,
- const char *ifname,
- const struct ether_addr *addr,
- void *userdata,
- lldp_port **ret);
-void lldp_port_free(lldp_port *p);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(lldp_port*, lldp_port_free);
-#define _cleanup_lldp_port_free_ _cleanup_(lldp_port_freep)
-
-int lldp_port_start(lldp_port *p);
-int lldp_port_stop(lldp_port *p);
diff --git a/src/libsystemd-network/lldp-tlv.c b/src/libsystemd-network/lldp-tlv.c
deleted file mode 100644
index e32783f3eb..0000000000
--- a/src/libsystemd-network/lldp-tlv.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <net/ethernet.h>
-#include <arpa/inet.h>
-
-#include "macro.h"
-#include "lldp-tlv.h"
-
-int tlv_section_new(tlv_section **ret) {
- tlv_section *s;
-
- s = new0(tlv_section, 1);
- if (!s)
- return -ENOMEM;
-
- *ret = s;
-
- return 0;
-}
-
-void tlv_section_free(tlv_section *m) {
-
- if (!m)
- return;
-
- free(m);
-}
-
-int tlv_packet_new(tlv_packet **ret) {
- tlv_packet *m;
-
- m = new0(tlv_packet, 1);
- if (!m)
- return -ENOMEM;
-
- LIST_HEAD_INIT(m->sections);
-
- *ret = m;
-
- return 0;
-}
-
-void tlv_packet_free(tlv_packet *m) {
- tlv_section *s, *n;
-
- if (!m)
- return;
-
- LIST_FOREACH_SAFE(section, s, n, m->sections)
- tlv_section_free(s);
-
- free(m);
-}
-
-int tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length) {
- uint8_t *p;
-
- assert_return(m, -EINVAL);
- assert_return(data, -EINVAL);
- assert_return(data_length, -EINVAL);
-
- if (m->length + data_length > ETHER_MAX_LEN)
- return -ENOMEM;
-
- p = m->pdu + m->length;
- memcpy(p, data, data_length);
- m->length += data_length;
-
- return 0;
-}
-
-int tlv_packet_append_u8(tlv_packet *m, uint8_t data) {
-
- assert_return(m, -EINVAL);
-
- return tlv_packet_append_bytes(m, &data, sizeof(uint8_t));
-}
-
-int tlv_packet_append_u16(tlv_packet *m, uint16_t data) {
- uint16_t type;
-
- assert_return(m, -EINVAL);
-
- type = htons(data);
-
- return tlv_packet_append_bytes(m, &type, sizeof(uint16_t));
-}
-
-int tlv_packet_append_u32(tlv_packet *m, uint32_t data) {
- uint32_t type;
-
- assert_return(m, -EINVAL);
-
- type = htonl(data);
-
- return tlv_packet_append_bytes(m, &type, sizeof(uint32_t));
-}
-
-int tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size) {
-
- assert_return(m, -EINVAL);
-
- return tlv_packet_append_bytes(m, data, size);
-}
-
-int lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type) {
-
- assert_return(m, -EINVAL);
-
- m->container_pos = m->pdu + m->length;
-
- return tlv_packet_append_u16(m, type << 9);
-}
-
-int lldp_tlv_packet_close_container(tlv_packet *m) {
- uint16_t type;
-
- assert_return(m, -EINVAL);
- assert_return(m->container_pos, -EINVAL);
-
- memcpy(&type, m->container_pos, sizeof(uint16_t));
-
- type |= htons(((m->pdu + m->length) - (m->container_pos + 2)) & 0x01ff);
- memcpy(m->container_pos, &type, sizeof(uint16_t));
-
- return 0;
-}
-
-static inline int tlv_packet_read_internal(tlv_section *m, void **data) {
-
- assert_return(m->read_pos, -EINVAL);
-
- *data = m->read_pos;
-
- return 0;
-}
-
-int tlv_packet_read_u8(tlv_packet *m, uint8_t *data) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(data, val, sizeof(uint8_t));
-
- m->container->read_pos ++;
-
- return 0;
-}
-
-int tlv_packet_read_u16(tlv_packet *m, uint16_t *data) {
- uint16_t t;
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(&t, val, sizeof(uint16_t));
- *data = ntohs(t);
-
- m->container->read_pos += 2;
-
- return 0;
-}
-
-int tlv_packet_read_u32(tlv_packet *m, uint32_t *data) {
- uint32_t t;
- void *val;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- memcpy(&t, val, sizeof(uint32_t));
- *data = ntohl(t);
-
- m->container->read_pos += 4;
-
- return r;
-}
-
-int tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- *data = (char *) val;
- *data_length = m->container->length;
-
- m->container->read_pos += m->container->length;
-
- return 0;
-}
-
-int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length) {
- void *val = NULL;
- int r;
-
- assert_return(m, -EINVAL);
-
- r = tlv_packet_read_internal(m->container, &val);
- if (r < 0)
- return r;
-
- *data = (uint8_t *) val;
- *data_length = m->container->length;
-
- m->container->read_pos += m->container->length;
-
- return 0;
-}
-
-/* parse raw TLV packet */
-int tlv_packet_parse_pdu(tlv_packet *m, uint16_t size) {
- tlv_section *section, *tail;
- uint16_t t, l;
- uint8_t *p;
- int r;
-
- assert_return(m, -EINVAL);
- assert_return(size, -EINVAL);
-
- p = m->pdu;
-
- /* extract ethernet herader */
- memcpy(&m->mac, p, ETH_ALEN);
- p += sizeof(struct ether_header);
-
- for (l = 0; l <= size; ) {
- r = tlv_section_new(&section);
- if (r < 0)
- return r;
-
- memcpy(&t, p, sizeof(uint16_t));
-
- section->type = ntohs(t) >> 9;
- section->length = ntohs(t) & 0x01ff;
-
- if (section->type == LLDP_TYPE_END || section->type >=_LLDP_TYPE_MAX) {
- tlv_section_free(section);
- break;
- }
-
- p += 2;
- section->data = p;
-
- LIST_FIND_TAIL(section, m->sections, tail);
- LIST_INSERT_AFTER(section, m->sections, tail, section);
-
- p += section->length;
- l += (section->length + 2);
- }
-
- return 0;
-}
-
-int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type) {
- tlv_section *s;
-
- assert_return(m, -EINVAL);
-
- LIST_FOREACH(section, s, m->sections)
- if (s->type == type)
- break;
- if (!s)
- return -1;
-
- m->container = s;
-
- m->container->read_pos = s->data;
- if (!m->container->read_pos) {
- m->container = 0;
- return -1;
- }
-
- return 0;
-}
-
-int lldp_tlv_packet_exit_container(tlv_packet *m) {
- assert_return(m, -EINVAL);
-
- m->container = 0;
-
- return 0;
-}
diff --git a/src/libsystemd-network/lldp-tlv.h b/src/libsystemd-network/lldp-tlv.h
deleted file mode 100644
index ce3334e115..0000000000
--- a/src/libsystemd-network/lldp-tlv.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#include <net/ethernet.h>
-
-#include "util.h"
-#include "lldp.h"
-#include "list.h"
-
-typedef struct tlv_packet tlv_packet;
-typedef struct tlv_section tlv_section;
-
-struct tlv_section {
- uint16_t type;
- uint16_t length;
-
- uint8_t *read_pos;
- uint8_t *data;
-
- LIST_FIELDS(tlv_section, section);
-};
-
-int tlv_section_new(tlv_section **ret);
-void tlv_section_free(tlv_section *ret);
-
-struct tlv_packet {
- uint16_t type;
- uint16_t length;
- usec_t ts;
-
- uint8_t *container_pos;
- uint8_t pdu[ETHER_MAX_LEN];
-
- void *userdata;
-
- struct ether_addr mac;
- tlv_section *container;
-
- LIST_HEAD(tlv_section, sections);
-};
-
-int tlv_packet_new(tlv_packet **ret);
-void tlv_packet_free(tlv_packet *m);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(tlv_packet*, tlv_packet_free);
-#define _cleanup_tlv_packet_free_ _cleanup_(tlv_packet_freep)
-
-int lldp_tlv_packet_open_container(tlv_packet *m, uint16_t type);
-int lldp_tlv_packet_close_container(tlv_packet *m);
-
-int tlv_packet_append_bytes(tlv_packet *m, const void *data, size_t data_length);
-int tlv_packet_append_u8(tlv_packet *m, uint8_t data);
-int tlv_packet_append_u16(tlv_packet *m, uint16_t data);
-int tlv_packet_append_u32(tlv_packet *m, uint32_t data);
-int tlv_packet_append_string(tlv_packet *m, char *data, uint16_t size);
-
-int lldp_tlv_packet_enter_container(tlv_packet *m, uint16_t type);
-int lldp_tlv_packet_exit_container(tlv_packet *m);
-
-int tlv_packet_read_bytes(tlv_packet *m, uint8_t **data, uint16_t *data_length);
-int tlv_packet_read_string(tlv_packet *m, char **data, uint16_t *data_length);
-int tlv_packet_read_u8(tlv_packet *m, uint8_t *data);
-int tlv_packet_read_u16(tlv_packet *m, uint16_t *data);
-int tlv_packet_read_u32(tlv_packet *m, uint32_t *data);
-
-int tlv_packet_parse_pdu(tlv_packet *t, uint16_t size);
diff --git a/src/libsystemd-network/lldp-util.h b/src/libsystemd-network/lldp-util.h
deleted file mode 100644
index 112001e4b9..0000000000
--- a/src/libsystemd-network/lldp-util.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_lldp *, sd_lldp_free);
-#define _cleanup_lldp_free_ _cleanup_(sd_lldp_freep)
diff --git a/src/libsystemd-network/lldp.h b/src/libsystemd-network/lldp.h
deleted file mode 100644
index 5e4b283e26..0000000000
--- a/src/libsystemd-network/lldp.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#pragma once
-
-#define LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
-
-#define ETHERTYPE_LLDP 0x88cc
-
-/* IEEE 802.3AB Clause 9: TLV Types */
-typedef enum LLDPTypes {
- LLDP_TYPE_END = 0,
- LLDP_TYPE_CHASSIS_ID = 1,
- LLDP_TYPE_PORT_ID = 2,
- LLDP_TYPE_TTL = 3,
- LLDP_TYPE_PORT_DESCRIPTION = 4,
- LLDP_TYPE_SYSTEM_NAME = 5,
- LLDP_TYPE_SYSTEM_DESCRIPTION = 6,
- LLDP_TYPE_SYSTEM_CAPABILITIES = 7,
- LLDP_TYPE_MGMT_ADDRESS = 8,
- LLDP_TYPE_PRIVATE = 127,
- _LLDP_TYPE_MAX,
- _LLDP_TYPE_INVALID = -1,
-} LLDPTypes;
-
-/* IEEE 802.3AB Clause 9.5.2: Chassis subtypes */
-typedef enum LLDPChassisSubtypes {
- LLDP_CHASSIS_SUBTYPE_RESERVED = 0,
- LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT = 1,
- LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS = 2,
- LLDP_CHASSIS_SUBTYPE_PORT_COMPONENT = 3,
- LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS = 4,
- LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS = 5,
- LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME = 6,
- LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED = 7,
- _LLDP_CHASSIS_SUBTYPE_MAX,
- _LLDP_CHASSIS_SUBTYPE_INVALID = -1,
-} LLDPChassisSubtypes;
-
-/* IEEE 802.3AB Clause 9.5.3: Port subtype */
-typedef enum LLDPPortSubtypes {
- LLDP_PORT_SUBTYPE_RESERVED = 0,
- LLDP_PORT_SUBTYPE_INTERFACE_ALIAS = 1,
- LLDP_PORT_SUBTYPE_PORT_COMPONENT = 2,
- LLDP_PORT_SUBTYPE_MAC_ADDRESS = 3,
- LLDP_PORT_SUBTYPE_NETWORK = 4,
- LLDP_PORT_SUBTYPE_INTERFACE_NAME = 5,
- LLDP_PORT_SUBTYPE_AGENT_CIRCUIT_ID = 6,
- LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED = 7,
- _LLDP_PORT_SUBTYPE_MAX,
- _LLDP_PORT_SUBTYPE_INVALID = -1
-} LLDPPortSubtypes;
-
-typedef enum LLDPSystemCapabilities {
- LLDP_SYSTEM_CAPABILITIES_OTHER = 1 << 0,
- LLDP_SYSTEM_CAPABILITIES_REPEATER = 1 << 1,
- LLDP_SYSTEM_CAPABILITIES_BRIDGE = 1 << 2,
- LLDP_SYSTEM_CAPABILITIES_WLAN_AP = 1 << 3,
- LLDP_SYSTEM_CAPABILITIES_ROUTER = 1 << 4,
- LLDP_SYSTEM_CAPABILITIES_PHONE = 1 << 5,
- LLDP_SYSTEM_CAPABILITIES_DOCSIS = 1 << 6,
- LLDP_SYSTEM_CAPABILITIES_STATION = 1 << 7,
- LLDP_SYSTEM_CAPABILITIES_CVLAN = 1 << 8,
- LLDP_SYSTEM_CAPABILITIES_SVLAN = 1 << 9,
- LLDP_SYSTEM_CAPABILITIES_TPMR = 1 << 10,
- _LLDP_SYSTEM_CAPABILITIES_MAX,
- _LLDP_SYSTEM_CAPABILITIES_INVALID = -1,
-} LLDPSystemCapabilities;
-
-typedef enum LLDPMedSubtype {
- LLDP_MED_SUBTYPE_RESERVED = 0,
- LLDP_MED_SUBTYPE_CAPABILITIES = 1,
- LLDP_MED_SUBTYPE_NETWORK_POLICY = 2,
- LLDP_MED_SUBTYPE_LOCATION_ID = 3,
- LLDP_MED_SUBTYPE_EXTENDED_PVMDI = 4,
- LLDP_MED_SUBTYPE_INV_HWREV = 5,
- LLDP_MED_SUBTYPE_INV_FWREV = 6,
- LLDP_MED_SUBTYPE_INV_SWREV = 7,
- LLDP_MED_SUBTYPE_INV_SERIAL = 8,
- LLDP_MED_SUBTYPE_INV_MANUFACTURER = 9,
- LLDP_MED_SUBTYPE_INV_MODELNAME = 10,
- LLDP_MED_SUBTYPE_INV_ASSETID = 11,
- _LLDP_MED_SUBTYPE_MAX,
- _LLDP_MED_SUBTYPE_INVALID = -1,
-} LLDPMedSubtype;
-
-typedef enum LLDPMedCapability {
- LLDP_MED_CAPABILITY_CAPAPILITIES = 1 << 0,
- LLDP_MED_CAPABILITY_NETWORK_POLICY = 1 << 1,
- LLDP_MED_CAPABILITY_LOCATION_ID = 1 << 2,
- LLDP_MED_CAPABILITY_EXTENDED_PSE = 1 << 3,
- LLDP_MED_CAPABILITY_EXTENDED_PD = 1 << 4,
- LLDP_MED_CAPABILITY_INVENTORY = 1 << 5,
- LLDP_MED_CAPABILITY_MAX,
- LLDP_MED_CAPABILITY_INVALID = -1,
-} LLDPMedCapability;
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
deleted file mode 100644
index d579755cc8..0000000000
--- a/src/libsystemd-network/network-internal.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/ether.h>
-#include <linux/if.h>
-#include <arpa/inet.h>
-
-#include "strv.h"
-#include "siphash24.h"
-#include "dhcp-lease-internal.h"
-#include "log.h"
-#include "utf8.h"
-#include "util.h"
-#include "conf-parser.h"
-#include "condition.h"
-#include "network-internal.h"
-
-const char *net_get_name(struct udev_device *device) {
- const char *name, *field;
-
- assert(device);
-
- /* fetch some persistent data unique (on this machine) to this device */
- FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") {
- name = udev_device_get_property_value(device, field);
- if (name)
- return name;
- }
-
- return NULL;
-}
-
-#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
-
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]) {
- size_t l, sz = 0;
- const char *name = NULL;
- int r;
- uint8_t *v;
-
- assert(device);
-
- name = net_get_name(device);
- if (!name)
- return -ENOENT;
-
- l = strlen(name);
- sz = sizeof(sd_id128_t) + l;
- v = alloca(sz);
-
- /* fetch some persistent data unique to this machine */
- r = sd_id128_get_machine((sd_id128_t*) v);
- if (r < 0)
- return r;
- memcpy(v + sizeof(sd_id128_t), name, l);
-
- /* Let's hash the machine ID plus the device name. We
- * use a fixed, but originally randomly created hash
- * key here. */
- siphash24(result, v, sz, HASH_KEY.bytes);
-
- return 0;
-}
-
-bool net_match_config(const struct ether_addr *match_mac,
- char * const *match_paths,
- char * const *match_drivers,
- char * const *match_types,
- char * const *match_names,
- Condition *match_host,
- Condition *match_virt,
- Condition *match_kernel,
- Condition *match_arch,
- const struct ether_addr *dev_mac,
- const char *dev_path,
- const char *dev_parent_driver,
- const char *dev_driver,
- const char *dev_type,
- const char *dev_name) {
-
- if (match_host && !condition_test(match_host))
- return false;
-
- if (match_virt && !condition_test(match_virt))
- return false;
-
- if (match_kernel && !condition_test(match_kernel))
- return false;
-
- if (match_arch && !condition_test(match_arch))
- return false;
-
- if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
- return false;
-
- if (!strv_isempty(match_paths) &&
- (!dev_path || !strv_fnmatch(match_paths, dev_path, 0)))
- return false;
-
- if (!strv_isempty(match_drivers) &&
- (!dev_driver || !strv_fnmatch(match_drivers, dev_driver, 0)))
- return false;
-
- if (!strv_isempty(match_types) &&
- (!dev_type || !strv_fnmatch_or_empty(match_types, dev_type, 0)))
- return false;
-
- if (!strv_isempty(match_names) &&
- (!dev_name || !strv_fnmatch_or_empty(match_names, dev_name, 0)))
- return false;
-
- return true;
-}
-
-int config_parse_net_condition(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- ConditionType cond = ltype;
- Condition **ret = data;
- bool negate;
- Condition *c;
- _cleanup_free_ char *s = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- negate = rvalue[0] == '!';
- if (negate)
- rvalue++;
-
- s = strdup(rvalue);
- if (!s)
- return log_oom();
-
- c = condition_new(cond, s, false, negate);
- if (!c)
- return log_oom();
-
- if (*ret)
- condition_free(*ret);
-
- *ret = c;
- return 0;
-}
-
-int config_parse_ifname(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data;
- _cleanup_free_ char *n = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- free(*s);
- if (*n) {
- *s = n;
- n = NULL;
- } else
- *s = NULL;
-
- return 0;
-}
-
-int config_parse_ifnames(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char ***sv = data;
- const char *word, *state;
- size_t l;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- FOREACH_WORD(word, l, rvalue, state) {
- char *n;
-
- n = strndup(word, l);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- free(n);
- return 0;
- }
-
- r = strv_consume(sv, n);
- if (r < 0)
- return log_oom();
- }
-
- return 0;
-}
-
-int config_parse_ifalias(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- char **s = data;
- _cleanup_free_ char *n = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- free(*s);
- if (*n) {
- *s = n;
- n = NULL;
- } else
- *s = NULL;
-
- return 0;
-}
-
-int config_parse_hwaddr(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
- struct ether_addr **hwaddr = data;
- struct ether_addr *n;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = new0(struct ether_addr, 1);
- if (!n)
- return log_oom();
-
- r = sscanf(rvalue, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- &n->ether_addr_octet[0],
- &n->ether_addr_octet[1],
- &n->ether_addr_octet[2],
- &n->ether_addr_octet[3],
- &n->ether_addr_octet[4],
- &n->ether_addr_octet[5]);
- if (r != 6) {
- log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Not a valid MAC address, ignoring assignment: %s", rvalue);
- free(n);
- return 0;
- }
-
- free(*hwaddr);
- *hwaddr = n;
-
- return 0;
-}
-
-void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
- unsigned i;
-
- assert(f);
- assert(addresses);
- assert(size);
-
- for (i = 0; i < size; i++)
- fprintf(f, "%s%s", inet_ntoa(addresses[i]),
- (i < (size - 1)) ? " ": "");
-}
-
-int deserialize_in_addrs(struct in_addr **ret, const char *string) {
- _cleanup_free_ struct in_addr *addresses = NULL;
- int size = 0;
- const char *word, *state;
- size_t len;
-
- assert(ret);
- assert(string);
-
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
- struct in_addr *new_addresses;
- int r;
-
- new_addresses = realloc(addresses, (size + 1) * sizeof(struct in_addr));
- if (!new_addresses)
- return -ENOMEM;
- else
- addresses = new_addresses;
-
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET, addr_str, &(addresses[size]));
- if (r <= 0)
- continue;
-
- size ++;
- }
-
- *ret = addresses;
- addresses = NULL;
-
- return size;
-}
-
-int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
- _cleanup_free_ struct in6_addr *addresses = NULL;
- int size = 0;
- const char *word, *state;
- size_t len;
-
- assert(ret);
- assert(string);
-
- FOREACH_WORD(word, len, string, state) {
- _cleanup_free_ char *addr_str = NULL;
- struct in6_addr *new_addresses;
- int r;
-
- new_addresses = realloc(addresses, (size + 1) * sizeof(struct in6_addr));
- if (!new_addresses)
- return -ENOMEM;
- else
- addresses = new_addresses;
-
- addr_str = strndup(word, len);
- if (!addr_str)
- return -ENOMEM;
-
- r = inet_pton(AF_INET6, addr_str, &(addresses[size]));
- if (r <= 0)
- continue;
-
- size++;
- }
-
- *ret = addresses;
- addresses = NULL;
-
- return size;
-}
-
-void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size) {
- unsigned i;
-
- assert(f);
- assert(key);
- assert(routes);
- assert(size);
-
- fprintf(f, "%s=", key);
-
- for (i = 0; i < size; i++) {
- fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr),
- routes[i].dst_prefixlen);
- fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr),
- (i < (size - 1)) ? " ": "");
- }
-
- fputs("\n", f);
-}
-
-int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string) {
- _cleanup_free_ struct sd_dhcp_route *routes = NULL;
- size_t size = 0, allocated = 0;
- const char *word, *state;
- size_t len;
-
- assert(ret);
- assert(ret_size);
- assert(ret_allocated);
- assert(string);
-
- FOREACH_WORD(word, len, string, state) {
- /* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
- _cleanup_free_ char* entry = NULL;
- char *tok, *tok_end;
- unsigned n;
- int r;
-
- if (!GREEDY_REALLOC(routes, allocated, size + 1))
- return -ENOMEM;
-
- entry = strndup(word, len);
- if(!entry)
- return -ENOMEM;
-
- tok = entry;
-
- /* get the subnet */
- tok_end = strchr(tok, '/');
- if (!tok_end)
- continue;
- *tok_end = '\0';
-
- r = inet_aton(tok, &routes[size].dst_addr);
- if (r == 0)
- continue;
-
- tok = tok_end + 1;
-
- /* get the prefixlen */
- tok_end = strchr(tok, ',');
- if (!tok_end)
- continue;
-
- *tok_end = '\0';
-
- r = safe_atou(tok, &n);
- if (r < 0 || n > 32)
- continue;
-
- routes[size].dst_prefixlen = (uint8_t) n;
- tok = tok_end + 1;
-
- /* get the gateway */
- r = inet_aton(tok, &routes[size].gw_addr);
- if (r == 0)
- continue;
-
- size++;
- }
-
- *ret_size = size;
- *ret_allocated = allocated;
- *ret = routes;
- routes = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
deleted file mode 100644
index 06aba893ce..0000000000
--- a/src/libsystemd-network/network-internal.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Tom Gundersen <teg@jklm.no>
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-#include "udev.h"
-#include "condition.h"
-
-bool net_match_config(const struct ether_addr *match_mac,
- char * const *match_path,
- char * const *match_driver,
- char * const *match_type,
- char * const *match_name,
- Condition *match_host,
- Condition *match_virt,
- Condition *match_kernel,
- Condition *match_arch,
- const struct ether_addr *dev_mac,
- const char *dev_path,
- const char *dev_parent_driver,
- const char *dev_driver,
- const char *dev_type,
- const char *dev_name);
-
-int config_parse_net_condition(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
-int config_parse_hwaddr(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
-int config_parse_ifname(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
-int config_parse_ifnames(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
-int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
- const char *section, unsigned section_line, const char *lvalue,
- int ltype, const char *rvalue, void *data, void *userdata);
-
-int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8]);
-const char *net_get_name(struct udev_device *device);
-
-void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size);
-int deserialize_in_addrs(struct in_addr **addresses, const char *string);
-int deserialize_in6_addrs(struct in6_addr **addresses, const char *string);
-
-/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */
-struct sd_dhcp_route;
-
-void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *routes, size_t size);
-int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
deleted file mode 100644
index a477cccecb..0000000000
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ /dev/null
@@ -1,1733 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <net/ethernet.h>
-#include <net/if_arp.h>
-#include <linux/if_infiniband.h>
-#include <sys/ioctl.h>
-
-#include "util.h"
-#include "refcnt.h"
-#include "async.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-internal.h"
-#include "dhcp-lease-internal.h"
-#include "dhcp-identifier.h"
-#include "sd-dhcp-client.h"
-
-#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
-#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
-
-struct sd_dhcp_client {
- RefCount n_ref;
-
- DHCPState state;
- sd_event *event;
- int event_priority;
- sd_event_source *timeout_resend;
- int index;
- int fd;
- union sockaddr_union link;
- sd_event_source *receive_message;
- bool request_broadcast;
- uint8_t *req_opts;
- size_t req_opts_allocated;
- size_t req_opts_size;
- be32_t last_addr;
- uint8_t mac_addr[MAX_MAC_ADDR_LEN];
- size_t mac_addr_len;
- uint16_t arp_type;
- struct {
- uint8_t type;
- union {
- struct {
- /* 0: Generic (non-LL) (RFC 2132) */
- uint8_t data[MAX_CLIENT_ID_LEN];
- } _packed_ gen;
- struct {
- /* 1: Ethernet Link-Layer (RFC 2132) */
- uint8_t haddr[ETH_ALEN];
- } _packed_ eth;
- struct {
- /* 2 - 254: ARP/Link-Layer (RFC 2132) */
- uint8_t haddr[0];
- } _packed_ ll;
- struct {
- /* 255: Node-specific (RFC 4361) */
- uint32_t iaid;
- struct duid duid;
- } _packed_ ns;
- struct {
- uint8_t data[MAX_CLIENT_ID_LEN];
- } _packed_ raw;
- };
- } _packed_ client_id;
- size_t client_id_len;
- char *hostname;
- char *vendor_class_identifier;
- uint32_t mtu;
- uint32_t xid;
- usec_t start_time;
- unsigned int attempt;
- usec_t request_sent;
- sd_event_source *timeout_t1;
- sd_event_source *timeout_t2;
- sd_event_source *timeout_expire;
- sd_dhcp_client_cb_t cb;
- void *userdata;
- sd_dhcp_lease *lease;
-};
-
-static const uint8_t default_req_opts[] = {
- DHCP_OPTION_SUBNET_MASK,
- DHCP_OPTION_ROUTER,
- DHCP_OPTION_HOST_NAME,
- DHCP_OPTION_DOMAIN_NAME,
- DHCP_OPTION_DOMAIN_NAME_SERVER,
- DHCP_OPTION_NTP_SERVER,
-};
-
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata);
-static void client_stop(sd_dhcp_client *client, int error);
-
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
- void *userdata) {
- assert_return(client, -EINVAL);
-
- client->cb = cb;
- client->userdata = userdata;
-
- return 0;
-}
-
-int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
- assert_return(client, -EINVAL);
-
- client->request_broadcast = !!broadcast;
-
- return 0;
-}
-
-int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
- size_t i;
-
- assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
-
- switch(option) {
- case DHCP_OPTION_PAD:
- case DHCP_OPTION_OVERLOAD:
- case DHCP_OPTION_MESSAGE_TYPE:
- case DHCP_OPTION_PARAMETER_REQUEST_LIST:
- case DHCP_OPTION_END:
- return -EINVAL;
-
- default:
- break;
- }
-
- for (i = 0; i < client->req_opts_size; i++)
- if (client->req_opts[i] == option)
- return -EEXIST;
-
- if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
- client->req_opts_size + 1))
- return -ENOMEM;
-
- client->req_opts[client->req_opts_size++] = option;
-
- return 0;
-}
-
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
- const struct in_addr *last_addr) {
- assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
-
- if (last_addr)
- client->last_addr = last_addr->s_addr;
- else
- client->last_addr = INADDR_ANY;
-
- return 0;
-}
-
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
- assert_return(client, -EINVAL);
- assert_return (IN_SET(client->state, DHCP_STATE_INIT,
- DHCP_STATE_STOPPED), -EBUSY);
- assert_return(interface_index > 0, -EINVAL);
-
- client->index = interface_index;
-
- return 0;
-}
-
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type) {
- DHCP_CLIENT_DONT_DESTROY(client);
- bool need_restart = false;
-
- assert_return(client, -EINVAL);
- assert_return(addr, -EINVAL);
- assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
- assert_return(arp_type > 0, -EINVAL);
-
- if (arp_type == ARPHRD_ETHER)
- assert_return(addr_len == ETH_ALEN, -EINVAL);
- else if (arp_type == ARPHRD_INFINIBAND)
- assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
- else
- return -EINVAL;
-
- if (client->mac_addr_len == addr_len &&
- memcmp(&client->mac_addr, addr, addr_len) == 0)
- return 0;
-
- if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
- log_dhcp_client(client, "Changing MAC address on running DHCP "
- "client, restarting");
- need_restart = true;
- client_stop(client, DHCP_EVENT_STOP);
- }
-
- memcpy(&client->mac_addr, addr, addr_len);
- client->mac_addr_len = addr_len;
- client->arp_type = arp_type;
-
- if (need_restart && client->state != DHCP_STATE_STOPPED)
- sd_dhcp_client_start(client);
-
- return 0;
-}
-
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
- const uint8_t **data, size_t *data_len) {
-
- assert_return(client, -EINVAL);
- assert_return(type, -EINVAL);
- assert_return(data, -EINVAL);
- assert_return(data_len, -EINVAL);
-
- *type = 0;
- *data = NULL;
- *data_len = 0;
- if (client->client_id_len) {
- *type = client->client_id.type;
- *data = client->client_id.raw.data;
- *data_len = client->client_id_len - sizeof(client->client_id.type);
- }
-
- return 0;
-}
-
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
- const uint8_t *data, size_t data_len) {
- DHCP_CLIENT_DONT_DESTROY(client);
- bool need_restart = false;
-
- assert_return(client, -EINVAL);
- assert_return(data, -EINVAL);
- assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
-
- switch (type) {
- case ARPHRD_ETHER:
- if (data_len != ETH_ALEN)
- return -EINVAL;
- break;
- case ARPHRD_INFINIBAND:
- if (data_len != INFINIBAND_ALEN)
- return -EINVAL;
- break;
- default:
- break;
- }
-
- if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
- client->client_id.type == type &&
- memcmp(&client->client_id.raw.data, data, data_len) == 0)
- return 0;
-
- if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
- log_dhcp_client(client, "Changing client ID on running DHCP "
- "client, restarting");
- need_restart = true;
- client_stop(client, DHCP_EVENT_STOP);
- }
-
- client->client_id.type = type;
- memcpy(&client->client_id.raw.data, data, data_len);
- client->client_id_len = data_len + sizeof (client->client_id.type);
-
- if (need_restart && client->state != DHCP_STATE_STOPPED)
- sd_dhcp_client_start(client);
-
- return 0;
-}
-
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
- const char *hostname) {
- char *new_hostname = NULL;
-
- assert_return(client, -EINVAL);
-
- if (streq_ptr(client->hostname, hostname))
- return 0;
-
- if (hostname) {
- new_hostname = strdup(hostname);
- if (!new_hostname)
- return -ENOMEM;
- }
-
- free(client->hostname);
- client->hostname = new_hostname;
-
- return 0;
-}
-
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
- const char *vci) {
- char *new_vci = NULL;
-
- assert_return(client, -EINVAL);
-
- new_vci = strdup(vci);
- if (!new_vci)
- return -ENOMEM;
-
- free(client->vendor_class_identifier);
-
- client->vendor_class_identifier = new_vci;
-
- return 0;
-}
-
-int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
- assert_return(client, -EINVAL);
- assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
-
- client->mtu = mtu;
-
- return 0;
-}
-
-int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
- assert_return(client, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (client->state != DHCP_STATE_BOUND &&
- client->state != DHCP_STATE_RENEWING &&
- client->state != DHCP_STATE_REBINDING)
- return -EADDRNOTAVAIL;
-
- *ret = sd_dhcp_lease_ref(client->lease);
-
- return 0;
-}
-
-static void client_notify(sd_dhcp_client *client, int event) {
- if (client->cb)
- client->cb(client, event, client->userdata);
-}
-
-static int client_initialize(sd_dhcp_client *client) {
- assert_return(client, -EINVAL);
-
- client->receive_message =
- sd_event_source_unref(client->receive_message);
-
- client->fd = asynchronous_close(client->fd);
-
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
- client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
- client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
- client->attempt = 1;
-
- client->state = DHCP_STATE_INIT;
- client->xid = 0;
-
- if (client->lease)
- client->lease = sd_dhcp_lease_unref(client->lease);
-
- return 0;
-}
-
-static void client_stop(sd_dhcp_client *client, int error) {
- assert(client);
-
- if (error < 0)
- log_dhcp_client(client, "STOPPED: %s", strerror(-error));
- else if (error == DHCP_EVENT_STOP)
- log_dhcp_client(client, "STOPPED");
- else
- log_dhcp_client(client, "STOPPED: Unknown event");
-
- client_notify(client, error);
-
- client_initialize(client);
-}
-
-static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
- uint8_t type, size_t *_optlen, size_t *_optoffset) {
- _cleanup_free_ DHCPPacket *packet;
- size_t optlen, optoffset, size;
- be16_t max_size;
- usec_t time_now;
- uint16_t secs;
- int r;
-
- assert(client);
- assert(client->start_time);
- assert(ret);
- assert(_optlen);
- assert(_optoffset);
- assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);
-
- optlen = DHCP_MIN_OPTIONS_SIZE;
- size = sizeof(DHCPPacket) + optlen;
-
- packet = malloc0(size);
- if (!packet)
- return -ENOMEM;
-
- r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
- client->arp_type, optlen, &optoffset);
- if (r < 0)
- return r;
-
- /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
- refuse to issue an DHCP lease if 'secs' is set to zero */
- r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- return r;
- assert(time_now >= client->start_time);
-
- /* seconds between sending first and last DISCOVER
- * must always be strictly positive to deal with broken servers */
- secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
- packet->dhcp.secs = htobe16(secs);
-
- /* RFC2132 section 4.1
- A client that cannot receive unicast IP datagrams until its protocol
- software has been configured with an IP address SHOULD set the
- BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
- DHCPREQUEST messages that client sends. The BROADCAST bit will
- provide a hint to the DHCP server and BOOTP relay agent to broadcast
- any messages to the client on the client's subnet.
-
- Note: some interfaces needs this to be enabled, but some networks
- needs this to be disabled as broadcasts are filteretd, so this
- needs to be configurable */
- if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
- packet->dhcp.flags = htobe16(0x8000);
-
- /* RFC2132 section 4.1.1:
- The client MUST include its hardware address in the ’chaddr’ field, if
- necessary for delivery of DHCP reply messages. Non-Ethernet
- interfaces will leave 'chaddr' empty and use the client identifier
- instead (eg, RFC 4390 section 2.1).
- */
- if (client->arp_type == ARPHRD_ETHER)
- memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
-
- /* If no client identifier exists, construct an RFC 4361-compliant one */
- if (client->client_id_len == 0) {
- size_t duid_len;
-
- client->client_id.type = 255;
-
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->client_id.ns.iaid);
- if (r < 0)
- return r;
-
- r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
- if (r < 0)
- return r;
-
- client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
- }
-
- /* Some DHCP servers will refuse to issue an DHCP lease if the Client
- Identifier option is not set */
- if (client->client_id_len) {
- r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_CLIENT_IDENTIFIER,
- client->client_id_len,
- &client->client_id);
- if (r < 0)
- return r;
- }
-
- /* RFC2131 section 3.5:
- in its initial DHCPDISCOVER or DHCPREQUEST message, a
- client may provide the server with a list of specific
- parameters the client is interested in. If the client
- includes a list of parameters in a DHCPDISCOVER message,
- it MUST include that list in any subsequent DHCPREQUEST
- messages.
- */
- r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_PARAMETER_REQUEST_LIST,
- client->req_opts_size, client->req_opts);
- if (r < 0)
- return r;
-
- /* RFC2131 section 3.5:
- The client SHOULD include the ’maximum DHCP message size’ option to
- let the server know how large the server may make its DHCP messages.
-
- Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
- than the defined default size unless the Maximum Messge Size option
- is explicitly set
-
- RFC3442 "Requirements to Avoid Sizing Constraints":
- Because a full routing table can be quite large, the standard 576
- octet maximum size for a DHCP message may be too short to contain
- some legitimate Classless Static Route options. Because of this,
- clients implementing the Classless Static Route option SHOULD send a
- Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
- stack is capable of receiving larger IP datagrams. In this case, the
- client SHOULD set the value of this option to at least the MTU of the
- interface that the client is configuring. The client MAY set the
- value of this option higher, up to the size of the largest UDP packet
- it is prepared to accept. (Note that the value specified in the
- Maximum DHCP Message Size option is the total maximum packet size,
- including IP and UDP headers.)
- */
- max_size = htobe16(size);
- r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
- DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
- 2, &max_size);
- if (r < 0)
- return r;
-
- *_optlen = optlen;
- *_optoffset = optoffset;
- *ret = packet;
- packet = NULL;
-
- return 0;
-}
-
-static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
- size_t len) {
- dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
- INADDR_BROADCAST, DHCP_PORT_SERVER, len);
-
- return dhcp_network_send_raw_socket(client->fd, &client->link,
- packet, len);
-}
-
-static int client_send_discover(sd_dhcp_client *client) {
- _cleanup_free_ DHCPPacket *discover = NULL;
- size_t optoffset, optlen;
- int r;
-
- assert(client);
- assert(client->state == DHCP_STATE_INIT ||
- client->state == DHCP_STATE_SELECTING);
-
- r = client_message_init(client, &discover, DHCP_DISCOVER,
- &optlen, &optoffset);
- if (r < 0)
- return r;
-
- /* the client may suggest values for the network address
- and lease time in the DHCPDISCOVER message. The client may include
- the ’requested IP address’ option to suggest that a particular IP
- address be assigned, and may include the ’IP address lease time’
- option to suggest the lease time it would like.
- */
- if (client->last_addr != INADDR_ANY) {
- r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_REQUESTED_IP_ADDRESS,
- 4, &client->last_addr);
- if (r < 0)
- return r;
- }
-
- /* it is unclear from RFC 2131 if client should send hostname in
- DHCPDISCOVER but dhclient does and so we do as well
- */
- if (client->hostname) {
- r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_HOST_NAME,
- strlen(client->hostname), client->hostname);
- if (r < 0)
- return r;
- }
-
- if (client->vendor_class_identifier) {
- r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
- strlen(client->vendor_class_identifier),
- client->vendor_class_identifier);
- if (r < 0)
- return r;
- }
-
- r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- /* We currently ignore:
- The client SHOULD wait a random time between one and ten seconds to
- desynchronize the use of DHCP at startup.
- */
- r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
- if (r < 0)
- return r;
-
- log_dhcp_client(client, "DISCOVER");
-
- return 0;
-}
-
-static int client_send_request(sd_dhcp_client *client) {
- _cleanup_free_ DHCPPacket *request = NULL;
- size_t optoffset, optlen;
- int r;
-
- r = client_message_init(client, &request, DHCP_REQUEST,
- &optlen, &optoffset);
- if (r < 0)
- return r;
-
- switch (client->state) {
- /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
- SELECTING should be REQUESTING)
- */
-
- case DHCP_STATE_REQUESTING:
- /* Client inserts the address of the selected server in ’server
- identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
- filled in with the yiaddr value from the chosen DHCPOFFER.
- */
-
- r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_SERVER_IDENTIFIER,
- 4, &client->lease->server_address);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_REQUESTED_IP_ADDRESS,
- 4, &client->lease->address);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_STATE_INIT_REBOOT:
- /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
- option MUST be filled in with client’s notion of its previously
- assigned address. ’ciaddr’ MUST be zero.
- */
- r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_REQUESTED_IP_ADDRESS,
- 4, &client->last_addr);
- if (r < 0)
- return r;
- break;
-
- case DHCP_STATE_RENEWING:
- /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
- option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
- client’s IP address.
- */
-
- /* fall through */
- case DHCP_STATE_REBINDING:
- /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
- option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
- client’s IP address.
-
- This message MUST be broadcast to the 0xffffffff IP broadcast address.
- */
- request->dhcp.ciaddr = client->lease->address;
-
- break;
-
- case DHCP_STATE_INIT:
- case DHCP_STATE_SELECTING:
- case DHCP_STATE_REBOOTING:
- case DHCP_STATE_BOUND:
- case DHCP_STATE_STOPPED:
- return -EINVAL;
- }
-
- if (client->hostname) {
- r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_HOST_NAME,
- strlen(client->hostname), client->hostname);
- if (r < 0)
- return r;
- }
-
- r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
- DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- if (client->state == DHCP_STATE_RENEWING) {
- r = dhcp_network_send_udp_socket(client->fd,
- client->lease->server_address,
- DHCP_PORT_SERVER,
- &request->dhcp,
- sizeof(DHCPMessage) + optoffset);
- } else {
- r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
- }
- if (r < 0)
- return r;
-
- switch (client->state) {
- case DHCP_STATE_REQUESTING:
- log_dhcp_client(client, "REQUEST (requesting)");
- break;
- case DHCP_STATE_INIT_REBOOT:
- log_dhcp_client(client, "REQUEST (init-reboot)");
- break;
- case DHCP_STATE_RENEWING:
- log_dhcp_client(client, "REQUEST (renewing)");
- break;
- case DHCP_STATE_REBINDING:
- log_dhcp_client(client, "REQUEST (rebinding)");
- break;
- default:
- log_dhcp_client(client, "REQUEST (invalid)");
- break;
- }
-
- return 0;
-}
-
-static int client_start(sd_dhcp_client *client);
-
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp_client *client = userdata;
- DHCP_CLIENT_DONT_DESTROY(client);
- usec_t next_timeout = 0;
- uint64_t time_now;
- uint32_t time_left;
- int r;
-
- assert(s);
- assert(client);
- assert(client->event);
-
- r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- goto error;
-
- switch (client->state) {
- case DHCP_STATE_RENEWING:
-
- time_left = (client->lease->t2 - client->lease->t1) / 2;
- if (time_left < 60)
- time_left = 60;
-
- next_timeout = time_now + time_left * USEC_PER_SEC;
-
- break;
-
- case DHCP_STATE_REBINDING:
-
- time_left = (client->lease->lifetime - client->lease->t2) / 2;
- if (time_left < 60)
- time_left = 60;
-
- next_timeout = time_now + time_left * USEC_PER_SEC;
- break;
-
- case DHCP_STATE_REBOOTING:
- /* start over as we did not receive a timely ack or nak */
- r = client_initialize(client);
- if (r < 0)
- goto error;
-
- r = client_start(client);
- if (r < 0)
- goto error;
- else {
- log_dhcp_client(client, "REBOOTED");
- return 0;
- }
-
- case DHCP_STATE_INIT:
- case DHCP_STATE_INIT_REBOOT:
- case DHCP_STATE_SELECTING:
- case DHCP_STATE_REQUESTING:
- case DHCP_STATE_BOUND:
-
- if (client->attempt < 64)
- client->attempt *= 2;
-
- next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
-
- break;
-
- case DHCP_STATE_STOPPED:
- r = -EINVAL;
- goto error;
- }
-
- next_timeout += (random_u32() & 0x1fffff);
-
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- next_timeout, 10 * USEC_PER_MSEC,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
- if (r < 0)
- goto error;
-
- switch (client->state) {
- case DHCP_STATE_INIT:
- r = client_send_discover(client);
- if (r >= 0) {
- client->state = DHCP_STATE_SELECTING;
- client->attempt = 1;
- } else {
- if (client->attempt >= 64)
- goto error;
- }
-
- break;
-
- case DHCP_STATE_SELECTING:
- r = client_send_discover(client);
- if (r < 0 && client->attempt >= 64)
- goto error;
-
- break;
-
- case DHCP_STATE_INIT_REBOOT:
- case DHCP_STATE_REQUESTING:
- case DHCP_STATE_RENEWING:
- case DHCP_STATE_REBINDING:
- r = client_send_request(client);
- if (r < 0 && client->attempt >= 64)
- goto error;
-
- if (client->state == DHCP_STATE_INIT_REBOOT)
- client->state = DHCP_STATE_REBOOTING;
-
- client->request_sent = time_now;
-
- break;
-
- case DHCP_STATE_REBOOTING:
- case DHCP_STATE_BOUND:
-
- break;
-
- case DHCP_STATE_STOPPED:
- r = -EINVAL;
- goto error;
- }
-
- return 0;
-
-error:
- client_stop(client, r);
-
- /* Errors were dealt with when stopping the client, don't spill
- errors into the event loop handler */
- return 0;
-}
-
-static int client_initialize_io_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
- int r;
-
- assert(client);
- assert(client->event);
-
- r = sd_event_add_io(client->event, &client->receive_message,
- client->fd, EPOLLIN, io_callback,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->receive_message,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
- if (r < 0)
- goto error;
-
-error:
- if (r < 0)
- client_stop(client, r);
-
- return 0;
-}
-
-static int client_initialize_time_events(sd_dhcp_client *client) {
- int r;
-
- assert(client);
- assert(client->event);
-
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- 0, 0,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
- if (r < 0)
- goto error;
-
-error:
- if (r < 0)
- client_stop(client, r);
-
- return 0;
-
-}
-
-static int client_initialize_events(sd_dhcp_client *client,
- sd_event_io_handler_t io_callback) {
- client_initialize_io_events(client, io_callback);
- client_initialize_time_events(client);
-
- return 0;
-}
-
-static int client_start(sd_dhcp_client *client) {
- int r;
-
- assert_return(client, -EINVAL);
- assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
- assert_return(client->fd < 0, -EBUSY);
- assert_return(client->xid == 0, -EINVAL);
- assert_return(client->state == DHCP_STATE_INIT ||
- client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
-
- client->xid = random_u32();
-
- r = dhcp_network_bind_raw_socket(client->index, &client->link,
- client->xid, client->mac_addr,
- client->mac_addr_len, client->arp_type);
- if (r < 0) {
- client_stop(client, r);
- return r;
- }
- client->fd = r;
-
- if (client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT)
- client->start_time = now(clock_boottime_or_monotonic());
-
- return client_initialize_events(client, client_receive_message_raw);
-}
-
-static int client_timeout_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp_client *client = userdata;
- DHCP_CLIENT_DONT_DESTROY(client);
-
- log_dhcp_client(client, "EXPIRED");
-
- client_notify(client, DHCP_EVENT_EXPIRED);
-
- /* lease was lost, start over if not freed or stopped in callback */
- if (client->state != DHCP_STATE_STOPPED) {
- client_initialize(client);
- client_start(client);
- }
-
- return 0;
-}
-
-static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_dhcp_client *client = userdata;
- DHCP_CLIENT_DONT_DESTROY(client);
- int r;
-
- client->receive_message = sd_event_source_unref(client->receive_message);
- client->fd = asynchronous_close(client->fd);
-
- client->state = DHCP_STATE_REBINDING;
- client->attempt = 1;
-
- r = dhcp_network_bind_raw_socket(client->index, &client->link,
- client->xid, client->mac_addr,
- client->mac_addr_len, client->arp_type);
- if (r < 0) {
- client_stop(client, r);
- return 0;
- }
- client->fd = r;
-
- return client_initialize_events(client, client_receive_message_raw);
-}
-
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp_client *client = userdata;
- DHCP_CLIENT_DONT_DESTROY(client);
-
- client->state = DHCP_STATE_RENEWING;
- client->attempt = 1;
-
- return client_initialize_time_events(client);
-}
-
-static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
- size_t len) {
- _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
- int r;
-
- r = dhcp_lease_new(&lease);
- if (r < 0)
- return r;
-
- if (client->client_id_len) {
- r = dhcp_lease_set_client_id(lease,
- (uint8_t *) &client->client_id,
- client->client_id_len);
- if (r < 0)
- return r;
- }
-
- r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
- if (r != DHCP_OFFER) {
- log_dhcp_client(client, "received message was not an OFFER, ignoring");
- return -ENOMSG;
- }
-
- lease->next_server = offer->siaddr;
-
- lease->address = offer->yiaddr;
-
- if (lease->address == INADDR_ANY ||
- lease->server_address == INADDR_ANY ||
- lease->lifetime == 0) {
- log_dhcp_client(client, "received lease lacks address, server "
- "address or lease lifetime, ignoring");
- return -ENOMSG;
- }
-
- if (lease->subnet_mask == INADDR_ANY) {
- r = dhcp_lease_set_default_subnet_mask(lease);
- if (r < 0) {
- log_dhcp_client(client, "received lease lacks subnet "
- "mask, and a fallback one can not be "
- "generated, ignoring");
- return -ENOMSG;
- }
- }
-
- sd_dhcp_lease_unref(client->lease);
- client->lease = lease;
- lease = NULL;
-
- log_dhcp_client(client, "OFFER");
-
- return 0;
-}
-
-static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
- size_t len) {
- int r;
-
- r = dhcp_option_parse(force, len, NULL, NULL);
- if (r != DHCP_FORCERENEW)
- return -ENOMSG;
-
- log_dhcp_client(client, "FORCERENEW");
-
- return 0;
-}
-
-static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
- size_t len) {
- _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
- int r;
-
- r = dhcp_lease_new(&lease);
- if (r < 0)
- return r;
-
- if (client->client_id_len) {
- r = dhcp_lease_set_client_id(lease,
- (uint8_t *) &client->client_id,
- client->client_id_len);
- if (r < 0)
- return r;
- }
-
- r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
- if (r == DHCP_NAK) {
- log_dhcp_client(client, "NAK");
- return -EADDRNOTAVAIL;
- }
-
- if (r != DHCP_ACK) {
- log_dhcp_client(client, "received message was not an ACK, ignoring");
- return -ENOMSG;
- }
-
- lease->next_server = ack->siaddr;
-
- lease->address = ack->yiaddr;
-
- if (lease->address == INADDR_ANY ||
- lease->server_address == INADDR_ANY ||
- lease->lifetime == 0) {
- log_dhcp_client(client, "received lease lacks address, server "
- "address or lease lifetime, ignoring");
- return -ENOMSG;
- }
-
- if (lease->subnet_mask == INADDR_ANY) {
- r = dhcp_lease_set_default_subnet_mask(lease);
- if (r < 0) {
- log_dhcp_client(client, "received lease lacks subnet "
- "mask, and a fallback one can not be "
- "generated, ignoring");
- return -ENOMSG;
- }
- }
-
- r = DHCP_EVENT_IP_ACQUIRE;
- if (client->lease) {
- if (client->lease->address != lease->address ||
- client->lease->subnet_mask != lease->subnet_mask ||
- client->lease->router != lease->router) {
- r = DHCP_EVENT_IP_CHANGE;
- } else
- r = DHCP_EVENT_RENEW;
-
- client->lease = sd_dhcp_lease_unref(client->lease);
- }
-
- client->lease = lease;
- lease = NULL;
-
- log_dhcp_client(client, "ACK");
-
- return r;
-}
-
-static uint64_t client_compute_timeout(sd_dhcp_client *client,
- uint32_t lifetime, double factor) {
- assert(client);
- assert(client->request_sent);
- assert(lifetime);
-
- return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
- + (random_u32() & 0x1fffff);
-}
-
-static int client_set_lease_timeouts(sd_dhcp_client *client) {
- usec_t time_now;
- uint64_t lifetime_timeout;
- uint64_t t2_timeout;
- uint64_t t1_timeout;
- char time_string[FORMAT_TIMESPAN_MAX];
- int r;
-
- assert(client);
- assert(client->event);
- assert(client->lease);
- assert(client->lease->lifetime);
-
- client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
- client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
- client->timeout_expire = sd_event_source_unref(client->timeout_expire);
-
- /* don't set timers for infinite leases */
- if (client->lease->lifetime == 0xffffffff)
- return 0;
-
- r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- return r;
- assert(client->request_sent <= time_now);
-
- /* convert the various timeouts from relative (secs) to absolute (usecs) */
- lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
- if (client->lease->t1 && client->lease->t2) {
- /* both T1 and T2 are given */
- if (client->lease->t1 < client->lease->t2 &&
- client->lease->t2 < client->lease->lifetime) {
- /* they are both valid */
- t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
- t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
- } else {
- /* discard both */
- t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
- client->lease->t2 = (client->lease->lifetime * 7) / 8;
- t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
- client->lease->t1 = client->lease->lifetime / 2;
- }
- } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
- /* only T2 is given, and it is valid */
- t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
- t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
- client->lease->t1 = client->lease->lifetime / 2;
- if (t2_timeout <= t1_timeout) {
- /* the computed T1 would be invalid, so discard T2 */
- t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
- client->lease->t2 = (client->lease->lifetime * 7) / 8;
- }
- } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
- /* only T1 is given, and it is valid */
- t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
- t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
- client->lease->t2 = (client->lease->lifetime * 7) / 8;
- if (t2_timeout <= t1_timeout) {
- /* the computed T2 would be invalid, so discard T1 */
- t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
- client->lease->t2 = client->lease->lifetime / 2;
- }
- } else {
- /* fall back to the default timeouts */
- t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
- client->lease->t1 = client->lease->lifetime / 2;
- t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
- client->lease->t2 = (client->lease->lifetime * 7) / 8;
- }
-
- /* arm lifetime timeout */
- r = sd_event_add_time(client->event, &client->timeout_expire,
- clock_boottime_or_monotonic(),
- lifetime_timeout, 10 * USEC_PER_MSEC,
- client_timeout_expire, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_expire,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
- if (r < 0)
- return r;
-
- log_dhcp_client(client, "lease expires in %s",
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- lifetime_timeout - time_now, 0));
-
- /* don't arm earlier timeouts if this has already expired */
- if (lifetime_timeout <= time_now)
- return 0;
-
- /* arm T2 timeout */
- r = sd_event_add_time(client->event,
- &client->timeout_t2,
- clock_boottime_or_monotonic(),
- t2_timeout,
- 10 * USEC_PER_MSEC,
- client_timeout_t2, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_t2,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
- if (r < 0)
- return r;
-
- log_dhcp_client(client, "T2 expires in %s",
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- t2_timeout - time_now, 0));
-
- /* don't arm earlier timeout if this has already expired */
- if (t2_timeout <= time_now)
- return 0;
-
- /* arm T1 timeout */
- r = sd_event_add_time(client->event,
- &client->timeout_t1,
- clock_boottime_or_monotonic(),
- t1_timeout, 10 * USEC_PER_MSEC,
- client_timeout_t1, client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_t1,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
- if (r < 0)
- return r;
-
- log_dhcp_client(client, "T1 expires in %s",
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- t1_timeout - time_now, 0));
-
- return 0;
-}
-
-static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
- int len) {
- DHCP_CLIENT_DONT_DESTROY(client);
- int r = 0, notify_event = 0;
-
- assert(client);
- assert(client->event);
- assert(message);
-
- switch (client->state) {
- case DHCP_STATE_SELECTING:
-
- r = client_handle_offer(client, message, len);
- if (r >= 0) {
-
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
-
- client->state = DHCP_STATE_REQUESTING;
- client->attempt = 1;
-
- r = sd_event_add_time(client->event,
- &client->timeout_resend,
- clock_boottime_or_monotonic(),
- 0, 0,
- client_timeout_resend, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
- if (r < 0)
- goto error;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
-
- break;
-
- case DHCP_STATE_REBOOTING:
- case DHCP_STATE_REQUESTING:
- case DHCP_STATE_RENEWING:
- case DHCP_STATE_REBINDING:
-
- r = client_handle_ack(client, message, len);
- if (r >= 0) {
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
- client->receive_message =
- sd_event_source_unref(client->receive_message);
- client->fd = asynchronous_close(client->fd);
-
- if (IN_SET(client->state, DHCP_STATE_REQUESTING,
- DHCP_STATE_REBOOTING))
- notify_event = DHCP_EVENT_IP_ACQUIRE;
- else if (r != DHCP_EVENT_IP_ACQUIRE)
- notify_event = r;
-
- client->state = DHCP_STATE_BOUND;
- client->attempt = 1;
-
- client->last_addr = client->lease->address;
-
- r = client_set_lease_timeouts(client);
- if (r < 0) {
- log_dhcp_client(client, "could not set lease timeouts");
- goto error;
- }
-
- r = dhcp_network_bind_udp_socket(client->lease->address,
- DHCP_PORT_CLIENT);
- if (r < 0) {
- log_dhcp_client(client, "could not bind UDP socket");
- goto error;
- }
-
- client->fd = r;
-
- client_initialize_io_events(client, client_receive_message_udp);
-
- if (notify_event) {
- client_notify(client, notify_event);
- if (client->state == DHCP_STATE_STOPPED)
- return 0;
- }
-
- } else if (r == -EADDRNOTAVAIL) {
- /* got a NAK, let's restart the client */
- client->timeout_resend =
- sd_event_source_unref(client->timeout_resend);
-
- r = client_initialize(client);
- if (r < 0)
- goto error;
-
- r = client_start(client);
- if (r < 0)
- goto error;
-
- log_dhcp_client(client, "REBOOTED");
-
- return 0;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
-
- break;
-
- case DHCP_STATE_BOUND:
- r = client_handle_forcerenew(client, message, len);
- if (r >= 0) {
- r = client_timeout_t1(NULL, 0, client);
- if (r < 0)
- goto error;
- } else if (r == -ENOMSG)
- /* invalid message, let's ignore it */
- return 0;
-
- break;
-
- case DHCP_STATE_INIT:
- case DHCP_STATE_INIT_REBOOT:
-
- break;
-
- case DHCP_STATE_STOPPED:
- r = -EINVAL;
- goto error;
- }
-
-error:
- if (r < 0)
- client_stop(client, r);
-
- return r;
-}
-
-static int client_receive_message_udp(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
- sd_dhcp_client *client = userdata;
- _cleanup_free_ DHCPMessage *message = NULL;
- int buflen = 0, len, r;
- const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
- bool expect_chaddr;
- uint8_t expected_hlen = 0;
-
- assert(s);
- assert(client);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0)
- return r;
-
- if (buflen < 0)
- /* this can't be right */
- return -EIO;
-
- message = malloc0(buflen);
- if (!message)
- return -ENOMEM;
-
- len = read(fd, message, buflen);
- if (len < 0) {
- log_dhcp_client(client, "could not receive message from UDP "
- "socket: %m");
- return 0;
- } else if ((size_t)len < sizeof(DHCPMessage)) {
- log_dhcp_client(client, "too small to be a DHCP message: ignoring");
- return 0;
- }
-
- if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
- log_dhcp_client(client, "not a DHCP message: ignoring");
- return 0;
- }
-
- if (message->op != BOOTREPLY) {
- log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
- return 0;
- }
-
- if (message->htype != client->arp_type) {
- log_dhcp_client(client, "packet type does not match client type");
- return 0;
- }
-
- if (client->arp_type == ARPHRD_ETHER) {
- expected_hlen = ETH_ALEN;
- expect_chaddr = true;
- } else {
- /* Non-ethernet links expect zero chaddr */
- expected_hlen = 0;
- expect_chaddr = false;
- }
-
- if (message->hlen != expected_hlen) {
- log_dhcp_client(client, "unexpected packet hlen %d", message->hlen);
- return 0;
- }
-
- if (memcmp(&message->chaddr[0], expect_chaddr ?
- (void *)&client->mac_addr :
- (void *)&zero_mac,
- ETH_ALEN)) {
- log_dhcp_client(client, "received chaddr does not match "
- "expected: ignoring");
- return 0;
- }
-
- if (client->state != DHCP_STATE_BOUND &&
- be32toh(message->xid) != client->xid) {
- /* in BOUND state, we may receive FORCERENEW with xid set by server,
- so ignore the xid in this case */
- log_dhcp_client(client, "received xid (%u) does not match "
- "expected (%u): ignoring",
- be32toh(message->xid), client->xid);
- return 0;
- }
-
- return client_handle_message(client, message, len);
-}
-
-static int client_receive_message_raw(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
- sd_dhcp_client *client = userdata;
- _cleanup_free_ DHCPPacket *packet = NULL;
- uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
- struct iovec iov = {};
- struct msghdr msg = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
- };
- struct cmsghdr *cmsg;
- bool checksum = true;
- int buflen = 0, len, r;
-
- assert(s);
- assert(client);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0)
- return r;
-
- if (buflen < 0)
- /* this can't be right */
- return -EIO;
-
- packet = malloc0(buflen);
- if (!packet)
- return -ENOMEM;
-
- iov.iov_base = packet;
- iov.iov_len = buflen;
-
- len = recvmsg(fd, &msg, 0);
- if (len < 0) {
- log_dhcp_client(client, "could not receive message from raw "
- "socket: %m");
- return 0;
- } else if ((size_t)len < sizeof(DHCPPacket))
- return 0;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == SOL_PACKET &&
- cmsg->cmsg_type == PACKET_AUXDATA &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
- struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
-
- checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
- break;
- }
- }
-
- r = dhcp_packet_verify_headers(packet, len, checksum);
- if (r < 0)
- return 0;
-
- len -= DHCP_IP_UDP_SIZE;
-
- return client_handle_message(client, &packet->dhcp, len);
-}
-
-int sd_dhcp_client_start(sd_dhcp_client *client) {
- int r;
-
- assert_return(client, -EINVAL);
-
- r = client_initialize(client);
- if (r < 0)
- return r;
-
- if (client->last_addr)
- client->state = DHCP_STATE_INIT_REBOOT;
-
- r = client_start(client);
- if (r >= 0)
- log_dhcp_client(client, "STARTED on ifindex %i", client->index);
-
- return r;
-}
-
-int sd_dhcp_client_stop(sd_dhcp_client *client) {
- DHCP_CLIENT_DONT_DESTROY(client);
-
- assert_return(client, -EINVAL);
-
- client_stop(client, DHCP_EVENT_STOP);
- client->state = DHCP_STATE_STOPPED;
-
- return 0;
-}
-
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
- int priority) {
- int r;
-
- assert_return(client, -EINVAL);
- assert_return(!client->event, -EBUSY);
-
- if (event)
- client->event = sd_event_ref(event);
- else {
- r = sd_event_default(&client->event);
- if (r < 0)
- return 0;
- }
-
- client->event_priority = priority;
-
- return 0;
-}
-
-int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
- assert_return(client, -EINVAL);
-
- client->event = sd_event_unref(client->event);
-
- return 0;
-}
-
-sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
- if (!client)
- return NULL;
-
- return client->event;
-}
-
-sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
- if (client)
- assert_se(REFCNT_INC(client->n_ref) >= 2);
-
- return client;
-}
-
-sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
- if (client && REFCNT_DEC(client->n_ref) == 0) {
- log_dhcp_client(client, "FREE");
-
- client_initialize(client);
-
- client->receive_message =
- sd_event_source_unref(client->receive_message);
-
- sd_dhcp_client_detach_event(client);
-
- sd_dhcp_lease_unref(client->lease);
-
- free(client->req_opts);
- free(client->hostname);
- free(client->vendor_class_identifier);
- free(client);
- }
-
- return NULL;
-}
-
-int sd_dhcp_client_new(sd_dhcp_client **ret) {
- _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
-
- assert_return(ret, -EINVAL);
-
- client = new0(sd_dhcp_client, 1);
- if (!client)
- return -ENOMEM;
-
- client->n_ref = REFCNT_INIT;
- client->state = DHCP_STATE_INIT;
- client->index = -1;
- client->fd = -1;
- client->attempt = 1;
- client->mtu = DHCP_DEFAULT_MIN_SIZE;
-
- client->req_opts_size = ELEMENTSOF(default_req_opts);
-
- client->req_opts = memdup(default_req_opts, client->req_opts_size);
- if (!client->req_opts)
- return -ENOMEM;
-
- *ret = client;
- client = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
deleted file mode 100644
index fa1fa112b1..0000000000
--- a/src/libsystemd-network/sd-dhcp-lease.c
+++ /dev/null
@@ -1,865 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <arpa/inet.h>
-
-#include "fileio.h"
-#include "unaligned.h"
-#include "in-addr-util.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-lease-internal.h"
-#include "sd-dhcp-lease.h"
-#include "network-internal.h"
-
-int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- addr->s_addr = lease->address;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
- assert_return(lease, -EINVAL);
- assert_return(lifetime, -EINVAL);
-
- *lifetime = lease->lifetime;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
- assert_return(lease, -EINVAL);
- assert_return(mtu, -EINVAL);
-
- if (lease->mtu)
- *mtu = lease->mtu;
- else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- if (lease->dns_size) {
- *addr = lease->dns;
- return lease->dns_size;
- } else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- if (lease->ntp_size) {
- *addr = lease->ntp;
- return lease->ntp_size;
- } else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
- assert_return(lease, -EINVAL);
- assert_return(domainname, -EINVAL);
-
- if (lease->domainname)
- *domainname = lease->domainname;
- else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
- assert_return(lease, -EINVAL);
- assert_return(hostname, -EINVAL);
-
- if (lease->hostname)
- *hostname = lease->hostname;
- else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
- assert_return(lease, -EINVAL);
- assert_return(root_path, -EINVAL);
-
- if (lease->root_path)
- *root_path = lease->root_path;
- else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, struct in_addr *addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- if (lease->router != INADDR_ANY)
- addr->s_addr = lease->router;
- else
- return -ENOENT;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- addr->s_addr = lease->subnet_mask;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- addr->s_addr = lease->server_address;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
-
- addr->s_addr = lease->next_server;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, struct sd_dhcp_route **routes) {
-
- assert_return(lease, -EINVAL);
- assert_return(routes, -EINVAL);
-
- if (lease->static_route_size) {
- *routes = lease->static_route;
- return lease->static_route_size;
- } else
- return -ENOENT;
-
- return 0;
-}
-
-sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
- if (lease)
- assert_se(REFCNT_INC(lease->n_ref) >= 2);
-
- return lease;
-}
-
-sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) {
- if (lease && REFCNT_DEC(lease->n_ref) == 0) {
- free(lease->hostname);
- free(lease->domainname);
- free(lease->dns);
- free(lease->ntp);
- free(lease->static_route);
- free(lease->client_id);
- free(lease);
- }
-
- return NULL;
-}
-
-static void lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) {
- assert(option);
- assert(ret);
-
- if (len == 4) {
- *ret = unaligned_read_be32((be32_t*) option);
-
- if (*ret < min)
- *ret = min;
- }
-}
-
-static void lease_parse_s32(const uint8_t *option, size_t len, int32_t *ret) {
- lease_parse_u32(option, len, (uint32_t *)ret, 0);
-}
-
-static void lease_parse_u16(const uint8_t *option, size_t len, uint16_t *ret, uint16_t min) {
- assert(option);
- assert(ret);
-
- if (len == 2) {
- *ret = unaligned_read_be16((be16_t*) option);
-
- if (*ret < min)
- *ret = min;
- }
-}
-
-static void lease_parse_be32(const uint8_t *option, size_t len, be32_t *ret) {
- assert(option);
- assert(ret);
-
- if (len == 4)
- memcpy(ret, option, 4);
-}
-
-static void lease_parse_bool(const uint8_t *option, size_t len, bool *ret) {
- assert(option);
- assert(ret);
-
- if (len == 1)
- *ret = !!(*option);
-}
-
-static void lease_parse_u8(const uint8_t *option, size_t len, uint8_t *ret, uint8_t min) {
- assert(option);
- assert(ret);
-
- if (len == 1) {
- *ret = *option;
-
- if (*ret < min)
- *ret = min;
- }
-}
-
-static int lease_parse_string(const uint8_t *option, size_t len, char **ret) {
- assert(option);
- assert(ret);
-
- if (len >= 1) {
- char *string;
-
- string = strndup((const char *)option, len);
- if (!string)
- return -errno;
-
- free(*ret);
- *ret = string;
- }
-
- return 0;
-}
-
-static int lease_parse_in_addrs_aux(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size, size_t mult) {
- assert(option);
- assert(ret);
- assert(ret_size);
-
- if (len && !(len % (4 * mult))) {
- size_t size;
- struct in_addr *addresses;
-
- size = len / 4;
-
- addresses = newdup(struct in_addr, option, size);
- if (!addresses)
- return -ENOMEM;
-
- free(*ret);
- *ret = addresses;
- *ret_size = size;
- }
-
- return 0;
-}
-
-static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
- return lease_parse_in_addrs_aux(option, len, ret, ret_size, 1);
-}
-
-static int lease_parse_in_addrs_pairs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *ret_size) {
- return lease_parse_in_addrs_aux(option, len, ret, ret_size, 2);
-}
-
-static int lease_parse_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
- size_t *routes_size, size_t *routes_allocated) {
-
- struct in_addr addr;
-
- assert(option);
- assert(routes);
- assert(routes_size);
- assert(routes_allocated);
-
- if (!len)
- return 0;
-
- if (len % 8 != 0)
- return -EINVAL;
-
- if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + (len / 8)))
- return -ENOMEM;
-
- while (len >= 8) {
- struct sd_dhcp_route *route = *routes + *routes_size;
- int r;
-
- r = in_addr_default_prefixlen((struct in_addr*) option, &route->dst_prefixlen);
- if (r < 0) {
- log_error("Failed to determine destination prefix length from class based IP, ignoring");
- continue;
- }
-
- lease_parse_be32(option, 4, &addr.s_addr);
- route->dst_addr = inet_makeaddr(inet_netof(addr), 0);
- option += 4;
-
- lease_parse_be32(option, 4, &route->gw_addr.s_addr);
- option += 4;
-
- len -= 8;
- (*routes_size)++;
- }
-
- return 0;
-}
-
-/* parses RFC3442 Classless Static Route Option */
-static int lease_parse_classless_routes(const uint8_t *option, size_t len, struct sd_dhcp_route **routes,
- size_t *routes_size, size_t *routes_allocated) {
-
- assert(option);
- assert(routes);
- assert(routes_size);
- assert(routes_allocated);
-
- /* option format: (subnet-mask-width significant-subnet-octets gateway-ip)* */
-
- while (len > 0) {
- uint8_t dst_octets;
- struct sd_dhcp_route *route;
-
- if (!GREEDY_REALLOC(*routes, *routes_allocated, *routes_size + 1))
- return -ENOMEM;
-
- route = *routes + *routes_size;
-
- dst_octets = (*option == 0 ? 0 : ((*option - 1) / 8) + 1);
- route->dst_prefixlen = *option;
- option++;
- len--;
-
- /* can't have more than 4 octets in IPv4 */
- if (dst_octets > 4 || len < dst_octets)
- return -EINVAL;
-
- route->dst_addr.s_addr = 0;
- memcpy(&route->dst_addr.s_addr, option, dst_octets);
- option += dst_octets;
- len -= dst_octets;
-
- if (len < 4)
- return -EINVAL;
-
- lease_parse_be32(option, 4, &route->gw_addr.s_addr);
- option += 4;
- len -= 4;
-
- (*routes_size)++;
- }
-
- return 0;
-}
-
-int dhcp_lease_parse_options(uint8_t code, uint8_t len, const uint8_t *option,
- void *user_data) {
- sd_dhcp_lease *lease = user_data;
- int r;
-
- assert(lease);
-
- switch(code) {
-
- case DHCP_OPTION_TIME_OFFSET:
- lease_parse_s32(option, len, &lease->time_offset);
-
- break;
-
- case DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT:
- lease_parse_u32(option, len, &lease->mtu_aging_timeout, 0);
-
- break;
-
- case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
- lease_parse_u32(option, len, &lease->lifetime, 1);
-
- break;
-
- case DHCP_OPTION_SERVER_IDENTIFIER:
- lease_parse_be32(option, len, &lease->server_address);
-
- break;
-
- case DHCP_OPTION_SUBNET_MASK:
- lease_parse_be32(option, len, &lease->subnet_mask);
-
- break;
-
- case DHCP_OPTION_BROADCAST:
- lease_parse_be32(option, len, &lease->broadcast);
-
- break;
-
- case DHCP_OPTION_ROUTER:
- lease_parse_be32(option, len, &lease->router);
-
- break;
-
- case DHCP_OPTION_DOMAIN_NAME_SERVER:
- r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_OPTION_NTP_SERVER:
- r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_OPTION_POLICY_FILTER:
- r = lease_parse_in_addrs_pairs(option, len, &lease->policy_filter, &lease->policy_filter_size);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_OPTION_STATIC_ROUTE:
- r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size,
- &lease->static_route_allocated);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_OPTION_INTERFACE_MTU:
- lease_parse_u16(option, len, &lease->mtu, 68);
-
- break;
-
- case DHCP_OPTION_INTERFACE_MDR:
- lease_parse_u16(option, len, &lease->mdr, 576);
-
- break;
-
- case DHCP_OPTION_INTERFACE_TTL:
- lease_parse_u8(option, len, &lease->ttl, 1);
-
- break;
-
- case DHCP_OPTION_BOOT_FILE_SIZE:
- lease_parse_u16(option, len, &lease->boot_file_size, 0);
-
- break;
-
- case DHCP_OPTION_DOMAIN_NAME:
- {
- _cleanup_free_ char *domainname = NULL;
- char *e;
-
- r = lease_parse_string(option, len, &domainname);
- if (r < 0)
- return r;
-
- /* Chop off trailing dot of domain name that some DHCP
- * servers send us back. Internally we want to store
- * host names without trailing dots and
- * host_name_is_valid() doesn't accept them. */
- e = endswith(domainname, ".");
- if (e)
- *e = 0;
-
- if (!hostname_is_valid(domainname) || is_localhost(domainname))
- break;
-
- free(lease->domainname);
- lease->domainname = domainname;
- domainname = NULL;
-
- break;
- }
- case DHCP_OPTION_HOST_NAME:
- {
- _cleanup_free_ char *hostname = NULL;
- char *e;
-
- r = lease_parse_string(option, len, &hostname);
- if (r < 0)
- return r;
-
- e = endswith(hostname, ".");
- if (e)
- *e = 0;
-
- if (!hostname_is_valid(hostname) || is_localhost(hostname))
- break;
-
- free(lease->hostname);
- lease->hostname = hostname;
- hostname = NULL;
-
- break;
- }
- case DHCP_OPTION_ROOT_PATH:
- r = lease_parse_string(option, len, &lease->root_path);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP_OPTION_RENEWAL_T1_TIME:
- lease_parse_u32(option, len, &lease->t1, 1);
-
- break;
-
- case DHCP_OPTION_REBINDING_T2_TIME:
- lease_parse_u32(option, len, &lease->t2, 1);
-
- break;
-
- case DHCP_OPTION_ENABLE_IP_FORWARDING:
- lease_parse_bool(option, len, &lease->ip_forward);
-
- break;
-
- case DHCP_OPTION_ENABLE_IP_FORWARDING_NL:
- lease_parse_bool(option, len, &lease->ip_forward_non_local);
-
- break;
-
- case DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
- r = lease_parse_classless_routes(option, len, &lease->static_route, &lease->static_route_size,
- &lease->static_route_allocated);
- if (r < 0)
- return r;
-
- break;
- }
-
- return 0;
-}
-
-int dhcp_lease_new(sd_dhcp_lease **ret) {
- sd_dhcp_lease *lease;
-
- lease = new0(sd_dhcp_lease, 1);
- if (!lease)
- return -ENOMEM;
-
- lease->router = INADDR_ANY;
- lease->n_ref = REFCNT_INIT;
-
- *ret = lease;
- return 0;
-}
-
-int sd_dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
- _cleanup_free_ char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- struct in_addr address;
- const struct in_addr *addresses;
- const uint8_t *client_id;
- size_t client_id_len;
- const char *string;
- uint16_t mtu;
- struct sd_dhcp_route *routes;
- int r;
-
- assert(lease);
- assert(lease_file);
-
- r = fopen_temporary(lease_file, &f, &temp_path);
- if (r < 0)
- goto finish;
-
- fchmod(fileno(f), 0644);
-
- r = sd_dhcp_lease_get_address(lease, &address);
- if (r < 0)
- goto finish;
-
- fprintf(f,
- "# This is private data. Do not parse.\n"
- "ADDRESS=%s\n", inet_ntoa(address));
-
- r = sd_dhcp_lease_get_netmask(lease, &address);
- if (r < 0)
- goto finish;
-
- fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
-
- r = sd_dhcp_lease_get_router(lease, &address);
- if (r >= 0)
- fprintf(f, "ROUTER=%s\n", inet_ntoa(address));
-
- r = sd_dhcp_lease_get_server_identifier(lease, &address);
- if (r >= 0)
- fprintf(f, "SERVER_ADDRESS=%s\n",
- inet_ntoa(address));
-
- r = sd_dhcp_lease_get_next_server(lease, &address);
- if (r >= 0)
- fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
-
- r = sd_dhcp_lease_get_mtu(lease, &mtu);
- if (r >= 0)
- fprintf(f, "MTU=%" PRIu16 "\n", mtu);
-
- fputs("DNS=", f);
- r = sd_dhcp_lease_get_dns(lease, &addresses);
- if (r >= 0)
- serialize_in_addrs(f, addresses, r);
- fputs("\n", f);
-
- fputs("NTP=", f);
- r = sd_dhcp_lease_get_ntp(lease, &addresses);
- if (r >= 0)
- serialize_in_addrs(f, addresses, r);
- fputs("\n", f);
-
- r = sd_dhcp_lease_get_domainname(lease, &string);
- if (r >= 0)
- fprintf(f, "DOMAINNAME=%s\n", string);
-
- r = sd_dhcp_lease_get_hostname(lease, &string);
- if (r >= 0)
- fprintf(f, "HOSTNAME=%s\n", string);
-
- r = sd_dhcp_lease_get_root_path(lease, &string);
- if (r >= 0)
- fprintf(f, "ROOT_PATH=%s\n", string);
-
- r = sd_dhcp_lease_get_routes(lease, &routes);
- if (r >= 0)
- serialize_dhcp_routes(f, "ROUTES", routes, r);
-
- r = sd_dhcp_lease_get_client_id(lease, &client_id, &client_id_len);
- if (r >= 0) {
- _cleanup_free_ char *client_id_hex;
-
- client_id_hex = hexmem (client_id, client_id_len);
- if (!client_id_hex) {
- r = -ENOMEM;
- goto finish;
- }
- fprintf(f, "CLIENTID=%s\n", client_id_hex);
- }
-
- r = 0;
-
- fflush(f);
-
- if (ferror(f) || rename(temp_path, lease_file) < 0) {
- r = -errno;
- unlink(lease_file);
- unlink(temp_path);
- }
-
-finish:
- if (r < 0)
- log_error_errno(r, "Failed to save lease data %s: %m", lease_file);
-
- return r;
-}
-
-int sd_dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
- _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
- _cleanup_free_ char *address = NULL, *router = NULL, *netmask = NULL,
- *server_address = NULL, *next_server = NULL,
- *dns = NULL, *ntp = NULL, *mtu = NULL,
- *routes = NULL, *client_id_hex = NULL;
- struct in_addr addr;
- int r;
-
- assert(lease_file);
- assert(ret);
-
- r = dhcp_lease_new(&lease);
- if (r < 0)
- return r;
-
- r = parse_env_file(lease_file, NEWLINE,
- "ADDRESS", &address,
- "ROUTER", &router,
- "NETMASK", &netmask,
- "SERVER_IDENTIFIER", &server_address,
- "NEXT_SERVER", &next_server,
- "DNS", &dns,
- "NTP", &ntp,
- "MTU", &mtu,
- "DOMAINNAME", &lease->domainname,
- "HOSTNAME", &lease->hostname,
- "ROOT_PATH", &lease->root_path,
- "ROUTES", &routes,
- "CLIENTID", &client_id_hex,
- NULL);
- if (r < 0) {
- if (r == -ENOENT)
- return 0;
-
- return log_error_errno(r, "Failed to read %s: %m", lease_file);
- }
-
- r = inet_pton(AF_INET, address, &addr);
- if (r < 0)
- return r;
-
- lease->address = addr.s_addr;
-
- if (router) {
- r = inet_pton(AF_INET, router, &addr);
- if (r < 0)
- return r;
-
- lease->router = addr.s_addr;
- }
-
- r = inet_pton(AF_INET, netmask, &addr);
- if (r < 0)
- return r;
-
- lease->subnet_mask = addr.s_addr;
-
- if (server_address) {
- r = inet_pton(AF_INET, server_address, &addr);
- if (r < 0)
- return r;
-
- lease->server_address = addr.s_addr;
- }
-
- if (next_server) {
- r = inet_pton(AF_INET, next_server, &addr);
- if (r < 0)
- return r;
-
- lease->next_server = addr.s_addr;
- }
-
- if (dns) {
- r = deserialize_in_addrs(&lease->dns, dns);
- if (r < 0)
- return r;
-
- lease->dns_size = r;
- }
-
- if (ntp) {
- r = deserialize_in_addrs(&lease->ntp, ntp);
- if (r < 0)
- return r;
-
- lease->ntp_size = r;
- }
-
- if (mtu) {
- uint16_t u;
- if (sscanf(mtu, "%" SCNu16, &u) > 0)
- lease->mtu = u;
- }
-
- if (routes) {
- r = deserialize_dhcp_routes(&lease->static_route, &lease->static_route_size,
- &lease->static_route_allocated, routes);
- if (r < 0)
- return r;
- }
-
- if (client_id_hex) {
- if (strlen (client_id_hex) % 2)
- return -EINVAL;
-
- lease->client_id = unhexmem (client_id_hex, strlen (client_id_hex));
- if (!lease->client_id)
- return -ENOMEM;
- lease->client_id_len = strlen (client_id_hex) / 2;
- }
-
- *ret = lease;
- lease = NULL;
-
- return 0;
-}
-
-int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
- struct in_addr address;
- struct in_addr mask;
- int r;
-
- assert(lease);
-
- address.s_addr = lease->address;
-
- /* fall back to the default subnet masks based on address class */
- r = in_addr_default_subnet_mask(&address, &mask);
- if (r < 0)
- return r;
-
- lease->subnet_mask = mask.s_addr;
-
- return 0;
-}
-
-int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const uint8_t **client_id,
- size_t *client_id_len) {
- assert_return(lease, -EINVAL);
- assert_return(client_id, -EINVAL);
- assert_return(client_id_len, -EINVAL);
-
- *client_id = lease->client_id;
- *client_id_len = lease->client_id_len;
- return 0;
-}
-
-int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const uint8_t *client_id,
- size_t client_id_len) {
- assert_return(lease, -EINVAL);
- assert_return((!client_id && !client_id_len) ||
- (client_id && client_id_len), -EINVAL);
-
- free (lease->client_id);
- lease->client_id = NULL;
- lease->client_id_len = 0;
-
- if (client_id) {
- lease->client_id = memdup (client_id, client_id_len);
- lease->client_id_len = client_id_len;
- }
-
- return 0;
-}
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
deleted file mode 100644
index a0a2320efa..0000000000
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <sys/ioctl.h>
-
-#include "siphash24.h"
-
-#include "sd-dhcp-server.h"
-#include "dhcp-server-internal.h"
-#include "dhcp-internal.h"
-
-#define DHCP_DEFAULT_LEASE_TIME 3600 /* one hour */
-
-int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server,
- struct in_addr *address,
- size_t size) {
- assert_return(server, -EINVAL);
- assert_return(address, -EINVAL);
- assert_return(address->s_addr, -EINVAL);
- assert_return(size, -EINVAL);
- assert_return(server->pool_start == htobe32(INADDR_ANY), -EBUSY);
- assert_return(!server->pool_size, -EBUSY);
- assert_return(!server->bound_leases, -EBUSY);
-
- server->bound_leases = new0(DHCPLease*, size);
- if (!server->bound_leases)
- return -ENOMEM;
-
- server->pool_start = address->s_addr;
- server->pool_size = size;
-
- return 0;
-}
-
-int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address,
- unsigned char prefixlen) {
- assert_return(server, -EINVAL);
- assert_return(address, -EINVAL);
- assert_return(address->s_addr, -EINVAL);
- assert_return(prefixlen <= 32, -ERANGE);
- assert_return(server->address == htobe32(INADDR_ANY), -EBUSY);
- assert_return(server->netmask == htobe32(INADDR_ANY), -EBUSY);
-
- server->address = address->s_addr;
- server->netmask = htobe32(0xfffffffflu << (32 - prefixlen));
-
- return 0;
-}
-
-bool sd_dhcp_server_is_running(sd_dhcp_server *server) {
- assert_return(server, -EINVAL);
-
- return !!server->receive_message;
-}
-
-sd_dhcp_server *sd_dhcp_server_ref(sd_dhcp_server *server) {
- if (server)
- assert_se(REFCNT_INC(server->n_ref) >= 2);
-
- return server;
-}
-
-unsigned long client_id_hash_func(const void *p,
- const uint8_t hash_key[HASH_KEY_SIZE]) {
- uint64_t u;
- const DHCPClientId *id = p;
-
- assert(id);
- assert(id->length);
- assert(id->data);
-
- siphash24((uint8_t*) &u, id->data, id->length, hash_key);
-
- return (unsigned long) u;
-}
-
-int client_id_compare_func(const void *_a, const void *_b) {
- const DHCPClientId *a, *b;
-
- a = _a;
- b = _b;
-
- assert(!a->length || a->data);
- assert(!b->length || b->data);
-
- if (a->length != b->length)
- return a->length < b->length ? -1 : 1;
-
- return memcmp(a->data, b->data, a->length);
-}
-
-static const struct hash_ops client_id_hash_ops = {
- .hash = client_id_hash_func,
- .compare = client_id_compare_func
-};
-
-static void dhcp_lease_free(DHCPLease *lease) {
- if (!lease)
- return;
-
- free(lease->client_id.data);
- free(lease);
-}
-
-sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
- DHCPLease *lease;
-
- if (!server)
- return NULL;
-
- if (REFCNT_DEC(server->n_ref) > 0)
- return NULL;
-
- log_dhcp_server(server, "UNREF");
-
- sd_dhcp_server_stop(server);
-
- sd_event_unref(server->event);
-
- while ((lease = hashmap_steal_first(server->leases_by_client_id)))
- dhcp_lease_free(lease);
- hashmap_free(server->leases_by_client_id);
-
- free(server->bound_leases);
- free(server);
-
- return NULL;
-}
-
-int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) {
- _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
-
- assert_return(ret, -EINVAL);
- assert_return(ifindex > 0, -EINVAL);
-
- server = new0(sd_dhcp_server, 1);
- if (!server)
- return -ENOMEM;
-
- server->n_ref = REFCNT_INIT;
- server->fd_raw = -1;
- server->fd = -1;
- server->address = htobe32(INADDR_ANY);
- server->netmask = htobe32(INADDR_ANY);
- server->index = ifindex;
- server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
-
- *ret = server;
- server = NULL;
-
- return 0;
-}
-
-int sd_dhcp_server_attach_event(sd_dhcp_server *server, sd_event *event,
- int priority) {
- int r;
-
- assert_return(server, -EINVAL);
- assert_return(!server->event, -EBUSY);
-
- if (event)
- server->event = sd_event_ref(event);
- else {
- r = sd_event_default(&server->event);
- if (r < 0)
- return r;
- }
-
- server->event_priority = priority;
-
- return 0;
-}
-
-int sd_dhcp_server_detach_event(sd_dhcp_server *server) {
- assert_return(server, -EINVAL);
-
- server->event = sd_event_unref(server->event);
-
- return 0;
-}
-
-sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
- assert_return(server, NULL);
-
- return server->event;
-}
-
-int sd_dhcp_server_stop(sd_dhcp_server *server) {
- assert_return(server, -EINVAL);
-
- server->receive_message =
- sd_event_source_unref(server->receive_message);
-
- server->fd_raw = safe_close(server->fd_raw);
- server->fd = safe_close(server->fd);
-
- log_dhcp_server(server, "STOPPED");
-
- return 0;
-}
-
-static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
- DHCPPacket *packet, size_t len) {
- union sockaddr_union link = {
- .ll.sll_family = AF_PACKET,
- .ll.sll_protocol = htons(ETH_P_IP),
- .ll.sll_ifindex = server->index,
- .ll.sll_halen = ETH_ALEN,
- };
- int r;
-
- assert(server);
- assert(server->index > 0);
- assert(server->address);
- assert(packet);
- assert(len > sizeof(DHCPPacket));
-
- memcpy(&link.ll.sll_addr, &packet->dhcp.chaddr, ETH_ALEN);
-
- dhcp_packet_append_ip_headers(packet, server->address, DHCP_PORT_SERVER,
- packet->dhcp.yiaddr,
- DHCP_PORT_CLIENT, len);
-
- r = dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
- DHCPMessage *message, size_t len) {
- union sockaddr_union dest = {
- .in.sin_family = AF_INET,
- .in.sin_port = htobe16(DHCP_PORT_CLIENT),
- .in.sin_addr.s_addr = destination,
- };
- struct iovec iov = {
- .iov_base = message,
- .iov_len = len,
- };
- uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))] = {};
- struct msghdr msg = {
- .msg_name = &dest,
- .msg_namelen = sizeof(dest.in),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
- };
- struct cmsghdr *cmsg;
- struct in_pktinfo *pktinfo;
- int r;
-
- assert(server);
- assert(server->fd > 0);
- assert(message);
- assert(len > sizeof(DHCPMessage));
-
- cmsg = CMSG_FIRSTHDR(&msg);
- assert(cmsg);
-
- cmsg->cmsg_level = IPPROTO_IP;
- cmsg->cmsg_type = IP_PKTINFO;
- cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
-
- /* we attach source interface and address info to the message
- rather than binding the socket. This will be mostly useful
- when we gain support for arbitrary number of server addresses
- */
- pktinfo = (struct in_pktinfo*) CMSG_DATA(cmsg);
- assert(pktinfo);
-
- pktinfo->ipi_ifindex = server->index;
- pktinfo->ipi_spec_dst.s_addr = server->address;
-
- r = sendmsg(server->fd, &msg, 0);
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-static bool requested_broadcast(DHCPRequest *req) {
- assert(req);
-
- return req->message->flags & htobe16(0x8000);
-}
-
-int dhcp_server_send_packet(sd_dhcp_server *server,
- DHCPRequest *req, DHCPPacket *packet,
- int type, size_t optoffset) {
- be32_t destination = INADDR_ANY;
- int r;
-
- assert(server);
- assert(req);
- assert(req->max_optlen);
- assert(optoffset <= req->max_optlen);
- assert(packet);
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
- DHCP_OPTION_SERVER_IDENTIFIER,
- 4, &server->address);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &optoffset, 0,
- DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- /* RFC 2131 Section 4.1
-
- If the ’giaddr’ field in a DHCP message from a client is non-zero,
- the server sends any return messages to the ’DHCP server’ port on the
- BOOTP relay agent whose address appears in ’giaddr’. If the ’giaddr’
- field is zero and the ’ciaddr’ field is nonzero, then the server
- unicasts DHCPOFFER and DHCPACK messages to the address in ’ciaddr’.
- If ’giaddr’ is zero and ’ciaddr’ is zero, and the broadcast bit is
- set, then the server broadcasts DHCPOFFER and DHCPACK messages to
- 0xffffffff. If the broadcast bit is not set and ’giaddr’ is zero and
- ’ciaddr’ is zero, then the server unicasts DHCPOFFER and DHCPACK
- messages to the client’s hardware address and ’yiaddr’ address. In
- all cases, when ’giaddr’ is zero, the server broadcasts any DHCPNAK
- messages to 0xffffffff.
-
- Section 4.3.2
-
- If ’giaddr’ is set in the DHCPREQUEST message, the client is on a
- different subnet. The server MUST set the broadcast bit in the
- DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
- client, because the client may not have a correct network address
- or subnet mask, and the client may not be answering ARP requests.
- */
- if (req->message->giaddr) {
- destination = req->message->giaddr;
- if (type == DHCP_NAK)
- packet->dhcp.flags = htobe16(0x8000);
- } else if (req->message->ciaddr && type != DHCP_NAK)
- destination = req->message->ciaddr;
-
- if (destination != INADDR_ANY)
- return dhcp_server_send_udp(server, destination, &packet->dhcp,
- sizeof(DHCPMessage) + optoffset);
- else if (requested_broadcast(req) || type == DHCP_NAK)
- return dhcp_server_send_udp(server, INADDR_BROADCAST,
- &packet->dhcp,
- sizeof(DHCPMessage) + optoffset);
- else
- /* we cannot send UDP packet to specific MAC address when the
- address is not yet configured, so must fall back to raw
- packets */
- return dhcp_server_send_unicast_raw(server, packet,
- sizeof(DHCPPacket) + optoffset);
-}
-
-static int server_message_init(sd_dhcp_server *server, DHCPPacket **ret,
- uint8_t type, size_t *_optoffset,
- DHCPRequest *req) {
- _cleanup_free_ DHCPPacket *packet = NULL;
- size_t optoffset = 0;
- int r;
-
- assert(server);
- assert(ret);
- assert(_optoffset);
- assert(IN_SET(type, DHCP_OFFER, DHCP_ACK, DHCP_NAK));
-
- packet = malloc0(sizeof(DHCPPacket) + req->max_optlen);
- if (!packet)
- return -ENOMEM;
-
- r = dhcp_message_init(&packet->dhcp, BOOTREPLY,
- be32toh(req->message->xid), type, ARPHRD_ETHER,
- req->max_optlen, &optoffset);
- if (r < 0)
- return r;
-
- packet->dhcp.flags = req->message->flags;
- packet->dhcp.giaddr = req->message->giaddr;
- memcpy(&packet->dhcp.chaddr, &req->message->chaddr, ETH_ALEN);
-
- *_optoffset = optoffset;
- *ret = packet;
- packet = NULL;
-
- return 0;
-}
-
-static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
- be32_t address) {
- _cleanup_free_ DHCPPacket *packet = NULL;
- size_t offset;
- be32_t lease_time;
- int r;
-
- r = server_message_init(server, &packet, DHCP_OFFER, &offset, req);
- if (r < 0)
- return r;
-
- packet->dhcp.yiaddr = address;
-
- lease_time = htobe32(req->lifetime);
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4,
- &lease_time);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_ROUTER, 4, &server->address);
- if (r < 0)
- return r;
-
- r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
- be32_t address) {
- _cleanup_free_ DHCPPacket *packet = NULL;
- size_t offset;
- be32_t lease_time;
- int r;
-
- r = server_message_init(server, &packet, DHCP_ACK, &offset, req);
- if (r < 0)
- return r;
-
- packet->dhcp.yiaddr = address;
-
- lease_time = htobe32(req->lifetime);
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_IP_ADDRESS_LEASE_TIME, 4,
- &lease_time);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_SUBNET_MASK, 4, &server->netmask);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
- DHCP_OPTION_ROUTER, 4, &server->address);
- if (r < 0)
- return r;
-
- r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int server_send_nak(sd_dhcp_server *server, DHCPRequest *req) {
- _cleanup_free_ DHCPPacket *packet = NULL;
- size_t offset;
- int r;
-
- r = server_message_init(server, &packet, DHCP_NAK, &offset, req);
- if (r < 0)
- return r;
-
- r = dhcp_server_send_packet(server, req, packet, DHCP_NAK, offset);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
- be32_t gateway, uint8_t chaddr[]) {
- _cleanup_free_ DHCPPacket *packet = NULL;
- size_t optoffset = 0;
- int r;
-
- assert(server);
- assert(address != INADDR_ANY);
- assert(chaddr);
-
- packet = malloc0(sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE);
- if (!packet)
- return -ENOMEM;
-
- r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0,
- DHCP_FORCERENEW, ARPHRD_ETHER,
- DHCP_MIN_OPTIONS_SIZE, &optoffset);
- if (r < 0)
- return r;
-
- r = dhcp_option_append(&packet->dhcp, DHCP_MIN_OPTIONS_SIZE,
- &optoffset, 0, DHCP_OPTION_END, 0, NULL);
- if (r < 0)
- return r;
-
- memcpy(&packet->dhcp.chaddr, chaddr, ETH_ALEN);
-
- r = dhcp_server_send_udp(server, address, &packet->dhcp,
- sizeof(DHCPMessage) + optoffset);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int parse_request(uint8_t code, uint8_t len, const uint8_t *option,
- void *user_data) {
- DHCPRequest *req = user_data;
-
- assert(req);
-
- switch(code) {
- case DHCP_OPTION_IP_ADDRESS_LEASE_TIME:
- if (len == 4)
- req->lifetime = be32toh(*(be32_t*)option);
-
- break;
- case DHCP_OPTION_REQUESTED_IP_ADDRESS:
- if (len == 4)
- req->requested_ip = *(be32_t*)option;
-
- break;
- case DHCP_OPTION_SERVER_IDENTIFIER:
- if (len == 4)
- req->server_id = *(be32_t*)option;
-
- break;
- case DHCP_OPTION_CLIENT_IDENTIFIER:
- if (len >= 2) {
- uint8_t *data;
-
- data = memdup(option, len);
- if (!data)
- return -ENOMEM;
-
- free(req->client_id.data);
- req->client_id.data = data;
- req->client_id.length = len;
- }
-
- break;
- case DHCP_OPTION_MAXIMUM_MESSAGE_SIZE:
- if (len == 2)
- req->max_optlen = be16toh(*(be16_t*)option) -
- - sizeof(DHCPPacket);
-
- break;
- }
-
- return 0;
-}
-
-static void dhcp_request_free(DHCPRequest *req) {
- if (!req)
- return;
-
- free(req->client_id.data);
- free(req);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(DHCPRequest*, dhcp_request_free);
-#define _cleanup_dhcp_request_free_ _cleanup_(dhcp_request_freep)
-
-static int ensure_sane_request(DHCPRequest *req, DHCPMessage *message) {
- assert(req);
- assert(message);
-
- req->message = message;
-
- /* set client id based on MAC address if client did not send an explicit
- one */
- if (!req->client_id.data) {
- uint8_t *data;
-
- data = new0(uint8_t, ETH_ALEN + 1);
- if (!data)
- return -ENOMEM;
-
- req->client_id.length = ETH_ALEN + 1;
- req->client_id.data = data;
- req->client_id.data[0] = 0x01;
- memcpy(&req->client_id.data[1], &message->chaddr, ETH_ALEN);
- }
-
- if (req->max_optlen < DHCP_MIN_OPTIONS_SIZE)
- req->max_optlen = DHCP_MIN_OPTIONS_SIZE;
-
- if (!req->lifetime)
- req->lifetime = DHCP_DEFAULT_LEASE_TIME;
-
- return 0;
-}
-
-static int get_pool_offset(sd_dhcp_server *server, be32_t requested_ip) {
- assert(server);
-
- if (!server->pool_size)
- return -EINVAL;
-
- if (be32toh(requested_ip) < be32toh(server->pool_start) ||
- be32toh(requested_ip) >= be32toh(server->pool_start) +
- + server->pool_size)
- return -EINVAL;
-
- return be32toh(requested_ip) - be32toh(server->pool_start);
-}
-
-int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
- size_t length) {
- _cleanup_dhcp_request_free_ DHCPRequest *req = NULL;
- DHCPLease *existing_lease;
- int type, r;
-
- assert(server);
- assert(message);
-
- if (message->op != BOOTREQUEST ||
- message->htype != ARPHRD_ETHER ||
- message->hlen != ETHER_ADDR_LEN)
- return 0;
-
- req = new0(DHCPRequest, 1);
- if (!req)
- return -ENOMEM;
-
- type = dhcp_option_parse(message, length, parse_request, req);
- if (type < 0)
- return 0;
-
- r = ensure_sane_request(req, message);
- if (r < 0)
- /* this only fails on critical errors */
- return r;
-
- existing_lease = hashmap_get(server->leases_by_client_id,
- &req->client_id);
-
- switch(type) {
- case DHCP_DISCOVER:
- {
- be32_t address = INADDR_ANY;
- unsigned i;
-
- log_dhcp_server(server, "DISCOVER (0x%x)",
- be32toh(req->message->xid));
-
- if (!server->pool_size)
- /* no pool allocated */
- return 0;
-
- /* for now pick a random free address from the pool */
- if (existing_lease)
- address = existing_lease->address;
- else {
- for (i = 0; i < server->pool_size; i++) {
- if (!server->bound_leases[server->next_offer]) {
- address = htobe32(be32toh(server->pool_start) + server->next_offer);
- break;
- } else
- server->next_offer = (server->next_offer + 1) % server->pool_size;
- }
- }
-
- if (address == INADDR_ANY)
- /* no free addresses left */
- return 0;
-
- r = server_send_offer(server, req, address);
- if (r < 0) {
- /* this only fails on critical errors */
- log_dhcp_server(server, "could not send offer: %s",
- strerror(-r));
- return r;
- } else {
- log_dhcp_server(server, "OFFER (0x%x)",
- be32toh(req->message->xid));
- return DHCP_OFFER;
- }
-
- break;
- }
- case DHCP_DECLINE:
- log_dhcp_server(server, "DECLINE (0x%x)",
- be32toh(req->message->xid));
-
- /* TODO: make sure we don't offer this address again */
-
- return 1;
-
- break;
- case DHCP_REQUEST:
- {
- be32_t address;
- bool init_reboot = false;
- int pool_offset;
-
- /* see RFC 2131, section 4.3.2 */
-
- if (req->server_id) {
- log_dhcp_server(server, "REQUEST (selecting) (0x%x)",
- be32toh(req->message->xid));
-
- /* SELECTING */
- if (req->server_id != server->address)
- /* client did not pick us */
- return 0;
-
- if (req->message->ciaddr)
- /* this MUST be zero */
- return 0;
-
- if (!req->requested_ip)
- /* this must be filled in with the yiaddr
- from the chosen OFFER */
- return 0;
-
- address = req->requested_ip;
- } else if (req->requested_ip) {
- log_dhcp_server(server, "REQUEST (init-reboot) (0x%x)",
- be32toh(req->message->xid));
-
- /* INIT-REBOOT */
- if (req->message->ciaddr)
- /* this MUST be zero */
- return 0;
-
- /* TODO: check more carefully if IP is correct */
- address = req->requested_ip;
- init_reboot = true;
- } else {
- log_dhcp_server(server, "REQUEST (rebinding/renewing) (0x%x)",
- be32toh(req->message->xid));
-
- /* REBINDING / RENEWING */
- if (!req->message->ciaddr)
- /* this MUST be filled in with clients IP address */
- return 0;
-
- address = req->message->ciaddr;
- }
-
- pool_offset = get_pool_offset(server, address);
-
- /* verify that the requested address is from the pool, and either
- owned by the current client or free */
- if (pool_offset >= 0 &&
- server->bound_leases[pool_offset] == existing_lease) {
- DHCPLease *lease;
- usec_t time_now = 0;
-
- if (!existing_lease) {
- lease = new0(DHCPLease, 1);
- lease->address = req->requested_ip;
- lease->client_id.data = memdup(req->client_id.data,
- req->client_id.length);
- if (!lease->client_id.data) {
- free(lease);
- return -ENOMEM;
- }
- lease->client_id.length = req->client_id.length;
- memcpy(&lease->chaddr, &req->message->chaddr,
- ETH_ALEN);
- lease->gateway = req->message->giaddr;
- } else
- lease = existing_lease;
-
- r = sd_event_now(server->event,
- clock_boottime_or_monotonic(),
- &time_now);
- if (r < 0)
- time_now = now(clock_boottime_or_monotonic());
- lease->expiration = req->lifetime * USEC_PER_SEC + time_now;
-
- r = server_send_ack(server, req, address);
- if (r < 0) {
- /* this only fails on critical errors */
- log_dhcp_server(server, "could not send ack: %s",
- strerror(-r));
-
- if (!existing_lease)
- dhcp_lease_free(lease);
-
- return r;
- } else {
- log_dhcp_server(server, "ACK (0x%x)",
- be32toh(req->message->xid));
-
- server->bound_leases[pool_offset] = lease;
- hashmap_put(server->leases_by_client_id,
- &lease->client_id, lease);
-
- return DHCP_ACK;
- }
- } else if (init_reboot) {
- r = server_send_nak(server, req);
- if (r < 0) {
- /* this only fails on critical errors */
- log_dhcp_server(server, "could not send nak: %s",
- strerror(-r));
- return r;
- } else {
- log_dhcp_server(server, "NAK (0x%x)",
- be32toh(req->message->xid));
- return DHCP_NAK;
- }
- }
-
- break;
- }
- case DHCP_RELEASE: {
- int pool_offset;
-
- log_dhcp_server(server, "RELEASE (0x%x)",
- be32toh(req->message->xid));
-
- if (!existing_lease)
- return 0;
-
- if (existing_lease->address != req->message->ciaddr)
- return 0;
-
- pool_offset = get_pool_offset(server, req->message->ciaddr);
- if (pool_offset < 0)
- return 0;
-
- if (server->bound_leases[pool_offset] == existing_lease) {
- server->bound_leases[pool_offset] = NULL;
- hashmap_remove(server->leases_by_client_id, existing_lease);
- dhcp_lease_free(existing_lease);
-
- return 1;
- } else
- return 0;
- }
- }
-
- return 0;
-}
-
-static int server_receive_message(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
- _cleanup_free_ DHCPMessage *message = NULL;
- uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))];
- sd_dhcp_server *server = userdata;
- struct iovec iov = {};
- struct msghdr msg = {
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
- };
- struct cmsghdr *cmsg;
- int buflen = 0, len, r;
-
- assert(server);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0)
- return r;
- if (buflen < 0)
- return -EIO;
-
- message = malloc0(buflen);
- if (!message)
- return -ENOMEM;
-
- iov.iov_base = message;
- iov.iov_len = buflen;
-
- len = recvmsg(fd, &msg, 0);
- if (len < buflen)
- return 0;
- else if ((size_t)len < sizeof(DHCPMessage))
- return 0;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == IPPROTO_IP &&
- cmsg->cmsg_type == IP_PKTINFO &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct in_pktinfo))) {
- struct in_pktinfo *info = (struct in_pktinfo*)CMSG_DATA(cmsg);
-
- /* TODO figure out if this can be done as a filter on
- * the socket, like for IPv6 */
- if (server->index != info->ipi_ifindex)
- return 0;
-
- break;
- }
- }
-
- return dhcp_server_handle_message(server, message, (size_t)len);
-}
-
-int sd_dhcp_server_start(sd_dhcp_server *server) {
- int r;
-
- assert_return(server, -EINVAL);
- assert_return(server->event, -EINVAL);
- assert_return(!server->receive_message, -EBUSY);
- assert_return(server->fd_raw == -1, -EBUSY);
- assert_return(server->fd == -1, -EBUSY);
- assert_return(server->address != htobe32(INADDR_ANY), -EUNATCH);
-
- r = socket(AF_PACKET, SOCK_DGRAM | SOCK_NONBLOCK, 0);
- if (r < 0) {
- r = -errno;
- sd_dhcp_server_stop(server);
- return r;
- }
- server->fd_raw = r;
-
- r = dhcp_network_bind_udp_socket(INADDR_ANY, DHCP_PORT_SERVER);
- if (r < 0) {
- sd_dhcp_server_stop(server);
- return r;
- }
- server->fd = r;
-
- r = sd_event_add_io(server->event, &server->receive_message,
- server->fd, EPOLLIN,
- server_receive_message, server);
- if (r < 0) {
- sd_dhcp_server_stop(server);
- return r;
- }
-
- r = sd_event_source_set_priority(server->receive_message,
- server->event_priority);
- if (r < 0) {
- sd_dhcp_server_stop(server);
- return r;
- }
-
- log_dhcp_server(server, "STARTED");
-
- return 0;
-}
-
-int sd_dhcp_server_forcerenew(sd_dhcp_server *server) {
- unsigned i;
- int r = 0;
-
- assert_return(server, -EINVAL);
- assert(server->bound_leases);
-
- for (i = 0; i < server->pool_size; i++) {
- DHCPLease *lease = server->bound_leases[i];
-
- if (!lease)
- continue;
-
- r = server_send_forcerenew(server, lease->address,
- lease->gateway,
- lease->chaddr);
- if (r < 0)
- return r;
- else
- log_dhcp_server(server, "FORCERENEW");
- }
-
- return r;
-}
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
deleted file mode 100644
index 3db1cb09db..0000000000
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <linux/if_infiniband.h>
-
-#include "udev.h"
-#include "udev-util.h"
-#include "util.h"
-#include "refcnt.h"
-
-#include "network-internal.h"
-#include "sd-dhcp6-client.h"
-#include "dhcp6-protocol.h"
-#include "dhcp6-internal.h"
-#include "dhcp6-lease-internal.h"
-#include "dhcp-identifier.h"
-
-#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
-
-struct sd_dhcp6_client {
- RefCount n_ref;
-
- enum DHCP6State state;
- sd_event *event;
- int event_priority;
- int index;
- uint8_t mac_addr[MAX_MAC_ADDR_LEN];
- size_t mac_addr_len;
- uint16_t arp_type;
- DHCP6IA ia_na;
- be32_t transaction_id;
- usec_t transaction_start;
- struct sd_dhcp6_lease *lease;
- int fd;
- bool information_request;
- be16_t *req_opts;
- size_t req_opts_allocated;
- size_t req_opts_len;
- sd_event_source *receive_message;
- usec_t retransmit_time;
- uint8_t retransmit_count;
- sd_event_source *timeout_resend;
- sd_event_source *timeout_resend_expire;
- sd_dhcp6_client_cb_t cb;
- void *userdata;
- struct duid duid;
- size_t duid_len;
-};
-
-static const uint16_t default_req_opts[] = {
- DHCP6_OPTION_DNS_SERVERS,
- DHCP6_OPTION_DOMAIN_LIST,
- DHCP6_OPTION_NTP_SERVER,
-};
-
-const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = {
- [DHCP6_SOLICIT] = "SOLICIT",
- [DHCP6_ADVERTISE] = "ADVERTISE",
- [DHCP6_REQUEST] = "REQUEST",
- [DHCP6_CONFIRM] = "CONFIRM",
- [DHCP6_RENEW] = "RENEW",
- [DHCP6_REBIND] = "REBIND",
- [DHCP6_REPLY] = "REPLY",
- [DHCP6_RELEASE] = "RELEASE",
- [DHCP6_DECLINE] = "DECLINE",
- [DHCP6_RECONFIGURE] = "RECONFIGURE",
- [DHCP6_INFORMATION_REQUEST] = "INFORMATION-REQUEST",
- [DHCP6_RELAY_FORW] = "RELAY-FORW",
- [DHCP6_RELAY_REPL] = "RELAY-REPL",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_type, int);
-
-const char * dhcp6_message_status_table[_DHCP6_STATUS_MAX] = {
- [DHCP6_STATUS_SUCCESS] = "Success",
- [DHCP6_STATUS_UNSPEC_FAIL] = "Unspecified failure",
- [DHCP6_STATUS_NO_ADDRS_AVAIL] = "No addresses available",
- [DHCP6_STATUS_NO_BINDING] = "Binding unavailable",
- [DHCP6_STATUS_NOT_ON_LINK] = "Not on link",
- [DHCP6_STATUS_USE_MULTICAST] = "Use multicast",
-};
-
-DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
-#define _cleanup_dhcp6_client_unref_ _cleanup_(sd_dhcp6_client_unrefp)
-
-#define DHCP6_CLIENT_DONT_DESTROY(client) \
- _cleanup_dhcp6_client_unref_ _unused_ sd_dhcp6_client *_dont_destroy_##client = sd_dhcp6_client_ref(client)
-
-static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
-
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
- sd_dhcp6_client_cb_t cb, void *userdata)
-{
- assert_return(client, -EINVAL);
-
- client->cb = cb;
- client->userdata = userdata;
-
- return 0;
-}
-
-int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index)
-{
- assert_return(client, -EINVAL);
- assert_return(interface_index >= -1, -EINVAL);
-
- client->index = interface_index;
-
- return 0;
-}
-
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type)
-{
- assert_return(client, -EINVAL);
- assert_return(addr, -EINVAL);
- assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
- assert_return(arp_type > 0, -EINVAL);
-
- if (arp_type == ARPHRD_ETHER)
- assert_return(addr_len == ETH_ALEN, -EINVAL);
- else if (arp_type == ARPHRD_INFINIBAND)
- assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
- else
- return -EINVAL;
-
- if (client->mac_addr_len == addr_len &&
- memcmp(&client->mac_addr, addr, addr_len) == 0)
- return 0;
-
- memcpy(&client->mac_addr, addr, addr_len);
- client->mac_addr_len = addr_len;
- client->arp_type = arp_type;
-
- return 0;
-}
-
-static int client_ensure_duid(sd_dhcp6_client *client)
-{
- if (client->duid_len != 0)
- return 0;
- return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
-}
-
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
- size_t duid_len)
-{
- assert_return(client, -EINVAL);
- assert_return(duid, -EINVAL);
- assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
-
- switch (type) {
- case DHCP6_DUID_LLT:
- if (duid_len <= sizeof(client->duid.llt))
- return -EINVAL;
- break;
- case DHCP6_DUID_EN:
- if (duid_len != sizeof(client->duid.en))
- return -EINVAL;
- break;
- case DHCP6_DUID_LL:
- if (duid_len <= sizeof(client->duid.ll))
- return -EINVAL;
- break;
- case DHCP6_DUID_UUID:
- if (duid_len != sizeof(client->duid.uuid))
- return -EINVAL;
- break;
- default:
- /* accept unknown type in order to be forward compatible */
- break;
- }
-
- client->duid.type = htobe16(type);
- memcpy(&client->duid.raw.data, duid, duid_len);
- client->duid_len = duid_len + sizeof(client->duid.type);
-
- return 0;
-}
-
-int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client,
- bool enabled) {
- assert_return(client, -EINVAL);
-
- client->information_request = enabled;
-
- return 0;
-}
-
-int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client,
- bool *enabled) {
- assert_return(client, -EINVAL);
- assert_return(enabled, -EINVAL);
-
- *enabled = client->information_request;
-
- return 0;
-}
-
-int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
- uint16_t option) {
- size_t t;
-
- assert_return(client, -EINVAL);
- assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
-
- switch(option) {
- case DHCP6_OPTION_DNS_SERVERS:
- case DHCP6_OPTION_DOMAIN_LIST:
- case DHCP6_OPTION_SNTP_SERVERS:
- case DHCP6_OPTION_NTP_SERVER:
- break;
-
- default:
- return -EINVAL;
- }
-
- for (t = 0; t < client->req_opts_len; t++)
- if (client->req_opts[t] == htobe16(option))
- return -EEXIST;
-
- if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
- client->req_opts_len + 1))
- return -ENOMEM;
-
- client->req_opts[client->req_opts_len++] = htobe16(option);
-
- return 0;
-}
-
-int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret) {
- assert_return(client, -EINVAL);
- assert_return(ret, -EINVAL);
-
- if (!client->lease)
- return -ENOMSG;
-
- *ret = sd_dhcp6_lease_ref(client->lease);
-
- return 0;
-}
-
-static void client_notify(sd_dhcp6_client *client, int event) {
- if (client->cb)
- client->cb(client, event, client->userdata);
-}
-
-static int client_reset(sd_dhcp6_client *client) {
- assert_return(client, -EINVAL);
-
- client->receive_message =
- sd_event_source_unref(client->receive_message);
-
- client->fd = safe_close(client->fd);
-
- client->transaction_id = 0;
- client->transaction_start = 0;
-
- client->ia_na.timeout_t1 =
- sd_event_source_unref(client->ia_na.timeout_t1);
- client->ia_na.timeout_t2 =
- sd_event_source_unref(client->ia_na.timeout_t2);
-
- client->retransmit_time = 0;
- client->retransmit_count = 0;
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
- client->timeout_resend_expire =
- sd_event_source_unref(client->timeout_resend_expire);
-
- client->state = DHCP6_STATE_STOPPED;
-
- return 0;
-}
-
-static void client_stop(sd_dhcp6_client *client, int error) {
- DHCP6_CLIENT_DONT_DESTROY(client);
-
- assert(client);
-
- client_notify(client, error);
-
- client_reset(client);
-}
-
-static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
- _cleanup_free_ DHCP6Message *message = NULL;
- struct in6_addr all_servers =
- IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
- size_t len, optlen = 512;
- uint8_t *opt;
- int r;
- usec_t elapsed_usec;
- be16_t elapsed_time;
-
- len = sizeof(DHCP6Message) + optlen;
-
- message = malloc0(len);
- if (!message)
- return -ENOMEM;
-
- opt = (uint8_t *)(message + 1);
-
- message->transaction_id = client->transaction_id;
-
- switch(client->state) {
- case DHCP6_STATE_INFORMATION_REQUEST:
- message->type = DHCP6_INFORMATION_REQUEST;
-
- break;
-
- case DHCP6_STATE_SOLICITATION:
- message->type = DHCP6_SOLICIT;
-
- r = dhcp6_option_append(&opt, &optlen,
- DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
- if (r < 0)
- return r;
-
- r = dhcp6_option_append_ia(&opt, &optlen, &client->ia_na);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP6_STATE_REQUEST:
- case DHCP6_STATE_RENEW:
-
- if (client->state == DHCP6_STATE_REQUEST)
- message->type = DHCP6_REQUEST;
- else
- message->type = DHCP6_RENEW;
-
- r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_SERVERID,
- client->lease->serverid_len,
- client->lease->serverid);
- if (r < 0)
- return r;
-
- r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP6_STATE_REBIND:
- message->type = DHCP6_REBIND;
-
- r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP6_STATE_STOPPED:
- case DHCP6_STATE_BOUND:
- return -EINVAL;
- }
-
- r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ORO,
- client->req_opts_len * sizeof(be16_t),
- client->req_opts);
- if (r < 0)
- return r;
-
- assert (client->duid_len);
- r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
- client->duid_len, &client->duid);
- if (r < 0)
- return r;
-
- elapsed_usec = time_now - client->transaction_start;
- if (elapsed_usec < 0xffff * USEC_PER_MSEC * 10)
- elapsed_time = htobe16(elapsed_usec / USEC_PER_MSEC / 10);
- else
- elapsed_time = 0xffff;
-
- r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_ELAPSED_TIME,
- sizeof(elapsed_time), &elapsed_time);
- if (r < 0)
- return r;
-
- r = dhcp6_network_send_udp_socket(client->fd, &all_servers, message,
- len - optlen);
- if (r < 0)
- return r;
-
- log_dhcp6_client(client, "Sent %s",
- dhcp6_message_type_to_string(message->type));
-
- return 0;
-}
-
-static int client_timeout_t2(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp6_client *client = userdata;
-
- assert_return(s, -EINVAL);
- assert_return(client, -EINVAL);
- assert_return(client->lease, -EINVAL);
-
- client->lease->ia.timeout_t2 =
- sd_event_source_unref(client->lease->ia.timeout_t2);
-
- log_dhcp6_client(client, "Timeout T2");
-
- client_start(client, DHCP6_STATE_REBIND);
-
- return 0;
-}
-
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp6_client *client = userdata;
-
- assert_return(s, -EINVAL);
- assert_return(client, -EINVAL);
- assert_return(client->lease, -EINVAL);
-
- client->lease->ia.timeout_t1 =
- sd_event_source_unref(client->lease->ia.timeout_t1);
-
- log_dhcp6_client(client, "Timeout T1");
-
- client_start(client, DHCP6_STATE_RENEW);
-
- return 0;
-}
-
-static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_dhcp6_client *client = userdata;
- DHCP6_CLIENT_DONT_DESTROY(client);
- enum DHCP6State state;
-
- assert(s);
- assert(client);
- assert(client->event);
-
- state = client->state;
-
- client_stop(client, DHCP6_EVENT_RESEND_EXPIRE);
-
- /* RFC 3315, section 18.1.4., says that "...the client may choose to
- use a Solicit message to locate a new DHCP server..." */
- if (state == DHCP6_STATE_REBIND)
- client_start(client, DHCP6_STATE_SOLICITATION);
-
- return 0;
-}
-
-static usec_t client_timeout_compute_random(usec_t val) {
- return val - val / 10 +
- (random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
-}
-
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
- void *userdata) {
- int r = 0;
- sd_dhcp6_client *client = userdata;
- usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
- usec_t max_retransmit_duration = 0;
- uint8_t max_retransmit_count = 0;
- char time_string[FORMAT_TIMESPAN_MAX];
- uint32_t expire = 0;
-
- assert(s);
- assert(client);
- assert(client->event);
-
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
-
- switch (client->state) {
- case DHCP6_STATE_INFORMATION_REQUEST:
- init_retransmit_time = DHCP6_INF_TIMEOUT;
- max_retransmit_time = DHCP6_INF_MAX_RT;
-
- break;
-
- case DHCP6_STATE_SOLICITATION:
-
- if (client->retransmit_count && client->lease) {
- client_start(client, DHCP6_STATE_REQUEST);
- return 0;
- }
-
- init_retransmit_time = DHCP6_SOL_TIMEOUT;
- max_retransmit_time = DHCP6_SOL_MAX_RT;
-
- break;
-
- case DHCP6_STATE_REQUEST:
- init_retransmit_time = DHCP6_REQ_TIMEOUT;
- max_retransmit_time = DHCP6_REQ_MAX_RT;
- max_retransmit_count = DHCP6_REQ_MAX_RC;
-
- break;
-
- case DHCP6_STATE_RENEW:
- init_retransmit_time = DHCP6_REN_TIMEOUT;
- max_retransmit_time = DHCP6_REN_MAX_RT;
-
- /* RFC 3315, section 18.1.3. says max retransmit duration will
- be the remaining time until T2. Instead of setting MRD,
- wait for T2 to trigger with the same end result */
-
- break;
-
- case DHCP6_STATE_REBIND:
- init_retransmit_time = DHCP6_REB_TIMEOUT;
- max_retransmit_time = DHCP6_REB_MAX_RT;
-
- if (!client->timeout_resend_expire) {
- r = dhcp6_lease_ia_rebind_expire(&client->lease->ia,
- &expire);
- if (r < 0) {
- client_stop(client, r);
- return 0;
- }
- max_retransmit_duration = expire * USEC_PER_SEC;
- }
-
- break;
-
- case DHCP6_STATE_STOPPED:
- case DHCP6_STATE_BOUND:
- return 0;
- }
-
- if (max_retransmit_count &&
- client->retransmit_count >= max_retransmit_count) {
- client_stop(client, DHCP6_EVENT_RETRANS_MAX);
- return 0;
- }
-
- r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- goto error;
-
- r = client_send_message(client, time_now);
- if (r >= 0)
- client->retransmit_count++;
-
- if (!client->retransmit_time) {
- client->retransmit_time =
- client_timeout_compute_random(init_retransmit_time);
-
- if (client->state == DHCP6_STATE_SOLICITATION)
- client->retransmit_time += init_retransmit_time / 10;
-
- } else {
- if (max_retransmit_time &&
- client->retransmit_time > max_retransmit_time / 2)
- client->retransmit_time = client_timeout_compute_random(max_retransmit_time);
- else
- client->retransmit_time += client_timeout_compute_random(client->retransmit_time);
- }
-
- log_dhcp6_client(client, "Next retransmission in %s",
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- client->retransmit_time, 0));
-
- r = sd_event_add_time(client->event, &client->timeout_resend,
- clock_boottime_or_monotonic(),
- time_now + client->retransmit_time,
- 10 * USEC_PER_MSEC, client_timeout_resend,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer");
- if (r < 0)
- goto error;
-
- if (max_retransmit_duration && !client->timeout_resend_expire) {
-
- log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs",
- max_retransmit_duration / USEC_PER_SEC);
-
- r = sd_event_add_time(client->event,
- &client->timeout_resend_expire,
- clock_boottime_or_monotonic(),
- time_now + max_retransmit_duration,
- USEC_PER_SEC,
- client_timeout_resend_expire, client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->timeout_resend_expire,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer");
- if (r < 0)
- goto error;
- }
-
-error:
- if (r < 0)
- client_stop(client, r);
-
- return 0;
-}
-
-static int client_ensure_iaid(sd_dhcp6_client *client) {
- int r;
-
- assert(client);
-
- if (client->ia_na.id)
- return 0;
-
- r = dhcp_identifier_set_iaid(client->index, client->mac_addr, client->mac_addr_len, &client->ia_na.id);
- if (r < 0)
- return r;
-
- return 0;
-}
-
-static int client_parse_message(sd_dhcp6_client *client,
- DHCP6Message *message, size_t len,
- sd_dhcp6_lease *lease) {
- int r;
- uint8_t *optval, *option, *id = NULL;
- uint16_t optcode, status;
- size_t optlen, id_len;
- bool clientid = false;
- be32_t iaid_lease;
-
- option = (uint8_t *)message + sizeof(DHCP6Message);
- len -= sizeof(DHCP6Message);
-
- while ((r = dhcp6_option_parse(&option, &len, &optcode, &optlen,
- &optval)) >= 0) {
- switch (optcode) {
- case DHCP6_OPTION_CLIENTID:
- if (clientid) {
- log_dhcp6_client(client, "%s contains multiple clientids",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
- if (optlen != client->duid_len ||
- memcmp(&client->duid, optval, optlen) != 0) {
- log_dhcp6_client(client, "%s DUID does not match",
- dhcp6_message_type_to_string(message->type));
-
- return -EINVAL;
- }
- clientid = true;
-
- break;
-
- case DHCP6_OPTION_SERVERID:
- r = dhcp6_lease_get_serverid(lease, &id, &id_len);
- if (r >= 0 && id) {
- log_dhcp6_client(client, "%s contains multiple serverids",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
- r = dhcp6_lease_set_serverid(lease, optval, optlen);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP6_OPTION_PREFERENCE:
- if (optlen != 1)
- return -EINVAL;
-
- r = dhcp6_lease_set_preference(lease, *optval);
- if (r < 0)
- return r;
-
- break;
-
- case DHCP6_OPTION_STATUS_CODE:
- if (optlen < 2)
- return -EINVAL;
-
- status = optval[0] << 8 | optval[1];
- if (status) {
- log_dhcp6_client(client, "%s Status %s",
- dhcp6_message_type_to_string(message->type),
- dhcp6_message_status_to_string(status));
- return -EINVAL;
- }
-
- break;
-
- case DHCP6_OPTION_IA_NA:
- if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
- log_dhcp6_client(client, "Information request ignoring IA NA option");
-
- break;
- }
-
- r = dhcp6_option_parse_ia(&optval, &optlen, optcode,
- &lease->ia);
- if (r < 0 && r != -ENOMSG)
- return r;
-
- r = dhcp6_lease_get_iaid(lease, &iaid_lease);
- if (r < 0)
- return r;
-
- if (client->ia_na.id != iaid_lease) {
- log_dhcp6_client(client, "%s has wrong IAID",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
- break;
-
- case DHCP6_OPTION_RAPID_COMMIT:
- r = dhcp6_lease_set_rapid_commit(lease);
- if (r < 0)
- return r;
-
- break;
- }
- }
-
- if (r == -ENOMSG)
- r = 0;
-
- if (r < 0 || !clientid) {
- log_dhcp6_client(client, "%s has incomplete options",
- dhcp6_message_type_to_string(message->type));
- return -EINVAL;
- }
-
- if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {
- r = dhcp6_lease_get_serverid(lease, &id, &id_len);
- if (r < 0)
- log_dhcp6_client(client, "%s has no server id",
- dhcp6_message_type_to_string(message->type));
- }
-
- return r;
-}
-
-static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply,
- size_t len)
-{
- int r;
- _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
- bool rapid_commit;
-
- if (reply->type != DHCP6_REPLY)
- return 0;
-
- r = dhcp6_lease_new(&lease);
- if (r < 0)
- return -ENOMEM;
-
- r = client_parse_message(client, reply, len, lease);
- if (r < 0)
- return r;
-
- if (client->state == DHCP6_STATE_SOLICITATION) {
- r = dhcp6_lease_get_rapid_commit(lease, &rapid_commit);
- if (r < 0)
- return r;
-
- if (!rapid_commit)
- return 0;
- }
-
- if (client->lease) {
- dhcp6_lease_clear_timers(&client->lease->ia);
- client->lease = sd_dhcp6_lease_unref(client->lease);
- }
-
- if (client->state != DHCP6_STATE_INFORMATION_REQUEST) {
- client->lease = lease;
- lease = NULL;
- }
-
- return DHCP6_STATE_BOUND;
-}
-
-static int client_receive_advertise(sd_dhcp6_client *client,
- DHCP6Message *advertise, size_t len) {
- int r;
- _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
- uint8_t pref_advertise = 0, pref_lease = 0;
-
- if (advertise->type != DHCP6_ADVERTISE)
- return 0;
-
- r = dhcp6_lease_new(&lease);
- if (r < 0)
- return r;
-
- r = client_parse_message(client, advertise, len, lease);
- if (r < 0)
- return r;
-
- r = dhcp6_lease_get_preference(lease, &pref_advertise);
- if (r < 0)
- return r;
-
- r = dhcp6_lease_get_preference(client->lease, &pref_lease);
-
- if (r < 0 || pref_advertise > pref_lease) {
- sd_dhcp6_lease_unref(client->lease);
- client->lease = lease;
- lease = NULL;
- r = 0;
- }
-
- if (pref_advertise == 255 || client->retransmit_count > 1)
- r = DHCP6_STATE_REQUEST;
-
- return r;
-}
-
-static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
- void *userdata) {
- sd_dhcp6_client *client = userdata;
- DHCP6_CLIENT_DONT_DESTROY(client);
- _cleanup_free_ DHCP6Message *message;
- int r, buflen, len;
-
- assert(s);
- assert(client);
- assert(client->event);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0 || buflen <= 0)
- buflen = DHCP6_MIN_OPTIONS_SIZE;
-
- message = malloc0(buflen);
- if (!message)
- return -ENOMEM;
-
- len = read(fd, message, buflen);
- if ((size_t)len < sizeof(DHCP6Message)) {
- log_dhcp6_client(client, "could not receive message from UDP socket: %m");
- return 0;
- }
-
- switch(message->type) {
- case DHCP6_SOLICIT:
- case DHCP6_REQUEST:
- case DHCP6_CONFIRM:
- case DHCP6_RENEW:
- case DHCP6_REBIND:
- case DHCP6_RELEASE:
- case DHCP6_DECLINE:
- case DHCP6_INFORMATION_REQUEST:
- case DHCP6_RELAY_FORW:
- case DHCP6_RELAY_REPL:
- return 0;
-
- case DHCP6_ADVERTISE:
- case DHCP6_REPLY:
- case DHCP6_RECONFIGURE:
- break;
-
- default:
- log_dhcp6_client(client, "unknown message type %d",
- message->type);
- return 0;
- }
-
- if (client->transaction_id != (message->transaction_id &
- htobe32(0x00ffffff)))
- return 0;
-
- switch (client->state) {
- case DHCP6_STATE_INFORMATION_REQUEST:
- r = client_receive_reply(client, message, len);
- if (r < 0)
- return 0;
-
- client_notify(client, DHCP6_EVENT_INFORMATION_REQUEST);
-
- client_start(client, DHCP6_STATE_STOPPED);
-
- break;
-
- case DHCP6_STATE_SOLICITATION:
- r = client_receive_advertise(client, message, len);
-
- if (r == DHCP6_STATE_REQUEST) {
- client_start(client, r);
-
- break;
- }
-
- /* fall through for Soliciation Rapid Commit option check */
- case DHCP6_STATE_REQUEST:
- case DHCP6_STATE_RENEW:
- case DHCP6_STATE_REBIND:
-
- r = client_receive_reply(client, message, len);
- if (r < 0)
- return 0;
-
- if (r == DHCP6_STATE_BOUND) {
-
- r = client_start(client, DHCP6_STATE_BOUND);
- if (r < 0) {
- client_stop(client, r);
- return 0;
- }
-
- client_notify(client, DHCP6_EVENT_IP_ACQUIRE);
- }
-
- break;
-
- case DHCP6_STATE_BOUND:
-
- break;
-
- case DHCP6_STATE_STOPPED:
- return 0;
- }
-
- if (r >= 0) {
- log_dhcp6_client(client, "Recv %s",
- dhcp6_message_type_to_string(message->type));
- }
-
- return 0;
-}
-
-static int client_start(sd_dhcp6_client *client, enum DHCP6State state)
-{
- int r;
- usec_t timeout, time_now;
- char time_string[FORMAT_TIMESPAN_MAX];
-
- assert_return(client, -EINVAL);
- assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
- assert_return(client->state != state, -EINVAL);
-
- client->timeout_resend_expire =
- sd_event_source_unref(client->timeout_resend_expire);
- client->timeout_resend = sd_event_source_unref(client->timeout_resend);
- client->retransmit_time = 0;
- client->retransmit_count = 0;
-
- if (client->state == DHCP6_STATE_STOPPED) {
- time_now = now(clock_boottime_or_monotonic());
- } else {
- r = sd_event_now(client->event, clock_boottime_or_monotonic(),
- &time_now);
- if (r < 0)
- return r;
- }
-
- switch (state) {
- case DHCP6_STATE_STOPPED:
- if (client->state == DHCP6_STATE_INFORMATION_REQUEST) {
- client->state = DHCP6_STATE_STOPPED;
-
- return 0;
- }
-
- /* fall through */
- case DHCP6_STATE_SOLICITATION:
- client->state = DHCP6_STATE_SOLICITATION;
-
- break;
-
- case DHCP6_STATE_INFORMATION_REQUEST:
- case DHCP6_STATE_REQUEST:
- case DHCP6_STATE_RENEW:
- case DHCP6_STATE_REBIND:
-
- client->state = state;
-
- break;
-
- case DHCP6_STATE_BOUND:
-
- if (client->lease->ia.lifetime_t1 == 0xffffffff ||
- client->lease->ia.lifetime_t2 == 0xffffffff) {
-
- log_dhcp6_client(client, "infinite T1 0x%08x or T2 0x%08x",
- be32toh(client->lease->ia.lifetime_t1),
- be32toh(client->lease->ia.lifetime_t2));
-
- return 0;
- }
-
- timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t1) * USEC_PER_SEC);
-
- log_dhcp6_client(client, "T1 expires in %s",
- format_timespan(time_string,
- FORMAT_TIMESPAN_MAX,
- timeout, 0));
-
- r = sd_event_add_time(client->event,
- &client->lease->ia.timeout_t1,
- clock_boottime_or_monotonic(), time_now + timeout,
- 10 * USEC_PER_SEC, client_timeout_t1,
- client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->lease->ia.timeout_t1,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->lease->ia.timeout_t1, "dhcp6-t1-timeout");
- if (r < 0)
- return r;
-
- timeout = client_timeout_compute_random(be32toh(client->lease->ia.lifetime_t2) * USEC_PER_SEC);
-
- log_dhcp6_client(client, "T2 expires in %s",
- format_timespan(time_string,
- FORMAT_TIMESPAN_MAX,
- timeout, 0));
-
- r = sd_event_add_time(client->event,
- &client->lease->ia.timeout_t2,
- clock_boottime_or_monotonic(), time_now + timeout,
- 10 * USEC_PER_SEC, client_timeout_t2,
- client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->lease->ia.timeout_t2,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->lease->ia.timeout_t2, "dhcp6-t2-timeout");
- if (r < 0)
- return r;
-
- client->state = state;
-
- return 0;
- }
-
- client->transaction_id = random_u32() & htobe32(0x00ffffff);
- client->transaction_start = time_now;
-
- r = sd_event_add_time(client->event, &client->timeout_resend,
- clock_boottime_or_monotonic(), 0, 0, client_timeout_resend,
- client);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(client->timeout_resend,
- client->event_priority);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout");
- if (r < 0)
- return r;
-
- return 0;
-}
-
-int sd_dhcp6_client_stop(sd_dhcp6_client *client)
-{
- client_stop(client, DHCP6_EVENT_STOP);
-
- return 0;
-}
-
-int sd_dhcp6_client_start(sd_dhcp6_client *client)
-{
- int r = 0;
- enum DHCP6State state = DHCP6_STATE_SOLICITATION;
-
- assert_return(client, -EINVAL);
- assert_return(client->event, -EINVAL);
- assert_return(client->index > 0, -EINVAL);
-
- r = client_reset(client);
- if (r < 0)
- return r;
-
- r = client_ensure_iaid(client);
- if (r < 0)
- return r;
-
- r = client_ensure_duid(client);
- if (r < 0)
- return r;
-
- r = dhcp6_network_bind_udp_socket(client->index, NULL);
- if (r < 0)
- return r;
-
- client->fd = r;
-
- r = sd_event_add_io(client->event, &client->receive_message,
- client->fd, EPOLLIN, client_receive_message,
- client);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(client->receive_message,
- client->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(client->receive_message,
- "dhcp6-receive-message");
- if (r < 0)
- goto error;
-
- if (client->information_request)
- state = DHCP6_STATE_INFORMATION_REQUEST;
-
- log_dhcp6_client(client, "Started in %s mode",
- client->information_request? "Information request":
- "Managed");
-
- return client_start(client, state);
-
-error:
- client_reset(client);
- return r;
-}
-
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event,
- int priority)
-{
- int r;
-
- assert_return(client, -EINVAL);
- assert_return(!client->event, -EBUSY);
-
- if (event)
- client->event = sd_event_ref(event);
- else {
- r = sd_event_default(&client->event);
- if (r < 0)
- return 0;
- }
-
- client->event_priority = priority;
-
- return 0;
-}
-
-int sd_dhcp6_client_detach_event(sd_dhcp6_client *client) {
- assert_return(client, -EINVAL);
-
- client->event = sd_event_unref(client->event);
-
- return 0;
-}
-
-sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
- if (!client)
- return NULL;
-
- return client->event;
-}
-
-sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client) {
- if (client)
- assert_se(REFCNT_INC(client->n_ref) >= 2);
-
- return client;
-}
-
-sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
- if (client && REFCNT_DEC(client->n_ref) == 0) {
- client_reset(client);
-
- sd_dhcp6_client_detach_event(client);
-
- free(client->req_opts);
- free(client);
-
- return NULL;
- }
-
- return client;
-}
-
-int sd_dhcp6_client_new(sd_dhcp6_client **ret)
-{
- _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
- size_t t;
-
- assert_return(ret, -EINVAL);
-
- client = new0(sd_dhcp6_client, 1);
- if (!client)
- return -ENOMEM;
-
- client->n_ref = REFCNT_INIT;
-
- client->ia_na.type = DHCP6_OPTION_IA_NA;
-
- client->index = -1;
-
- client->fd = -1;
-
- client->req_opts_len = ELEMENTSOF(default_req_opts);
-
- client->req_opts = new0(be16_t, client->req_opts_len);
- if (!client->req_opts)
- return -ENOMEM;
-
- for (t = 0; t < client->req_opts_len; t++)
- client->req_opts[t] = htobe16(default_req_opts[t]);
-
- *ret = client;
- client = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c
deleted file mode 100644
index 2442269a3f..0000000000
--- a/src/libsystemd-network/sd-dhcp6-lease.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-
-#include "util.h"
-
-#include "dhcp6-lease-internal.h"
-
-int dhcp6_lease_clear_timers(DHCP6IA *ia) {
- assert_return(ia, -EINVAL);
-
- ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
- ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
-
- return 0;
-}
-
-int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
- DHCP6Address *addr;
- uint32_t valid = 0, t;
-
- assert_return(ia, -EINVAL);
- assert_return(expire, -EINVAL);
-
- LIST_FOREACH(addresses, addr, ia->addresses) {
- t = be32toh(addr->iaaddr.lifetime_valid);
- if (valid < t)
- valid = t;
- }
-
- t = be32toh(ia->lifetime_t2);
- if (t > valid)
- return -EINVAL;
-
- *expire = valid - t;
-
- return 0;
-}
-
-DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
- DHCP6Address *address;
-
- if (!ia)
- return NULL;
-
- dhcp6_lease_clear_timers(ia);
-
- while (ia->addresses) {
- address = ia->addresses;
-
- LIST_REMOVE(addresses, ia->addresses, address);
-
- free(address);
- }
-
- return NULL;
-}
-
-int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
- size_t len) {
- assert_return(lease, -EINVAL);
- assert_return(id, -EINVAL);
-
- free(lease->serverid);
-
- lease->serverid = memdup(id, len);
- if (!lease->serverid)
- return -EINVAL;
-
- lease->serverid_len = len;
-
- return 0;
-}
-
-int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
- assert_return(lease, -EINVAL);
- assert_return(id, -EINVAL);
- assert_return(len, -EINVAL);
-
- *id = lease->serverid;
- *len = lease->serverid_len;
-
- return 0;
-}
-
-int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
- assert_return(lease, -EINVAL);
-
- lease->preference = preference;
-
- return 0;
-}
-
-int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
- assert_return(preference, -EINVAL);
-
- if (!lease)
- return -EINVAL;
-
- *preference = lease->preference;
-
- return 0;
-}
-
-int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
- assert_return(lease, -EINVAL);
-
- lease->rapid_commit = true;
-
- return 0;
-}
-
-int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
- assert_return(lease, -EINVAL);
- assert_return(rapid_commit, -EINVAL);
-
- *rapid_commit = lease->rapid_commit;
-
- return 0;
-}
-
-int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
- assert_return(lease, -EINVAL);
- assert_return(iaid, -EINVAL);
-
- *iaid = lease->ia.id;
-
- return 0;
-}
-
-int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
- uint32_t *lifetime_preferred,
- uint32_t *lifetime_valid) {
- assert_return(lease, -EINVAL);
- assert_return(addr, -EINVAL);
- assert_return(lifetime_preferred, -EINVAL);
- assert_return(lifetime_valid, -EINVAL);
-
- if (!lease->addr_iter)
- return -ENOMSG;
-
- memcpy(addr, &lease->addr_iter->iaaddr.address,
- sizeof(struct in6_addr));
- *lifetime_preferred =
- be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
- *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);
-
- lease->addr_iter = lease->addr_iter->addresses_next;
-
- return 0;
-}
-
-void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
- if (lease)
- lease->addr_iter = lease->ia.addresses;
-}
-
-sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
- if (lease)
- assert_se(REFCNT_INC(lease->n_ref) >= 2);
-
- return lease;
-}
-
-sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
- if (lease && REFCNT_DEC(lease->n_ref) == 0) {
- free(lease->serverid);
- dhcp6_lease_free_ia(&lease->ia);
-
- free(lease);
- }
-
- return NULL;
-}
-
-int dhcp6_lease_new(sd_dhcp6_lease **ret) {
- sd_dhcp6_lease *lease;
-
- lease = new0(sd_dhcp6_lease, 1);
- if (!lease)
- return -ENOMEM;
-
- lease->n_ref = REFCNT_INIT;
-
- LIST_HEAD_INIT(lease->ia.addresses);
-
- *ret = lease;
- return 0;
-}
diff --git a/src/libsystemd-network/sd-icmp6-nd.c b/src/libsystemd-network/sd-icmp6-nd.c
deleted file mode 100644
index 2f867e8562..0000000000
--- a/src/libsystemd-network/sd-icmp6-nd.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/icmp6.h>
-#include <netinet/ip6.h>
-#include <string.h>
-#include <stdbool.h>
-#include <netinet/in.h>
-#include <sys/ioctl.h>
-
-#include "socket-util.h"
-#include "refcnt.h"
-#include "async.h"
-
-#include "dhcp6-internal.h"
-#include "sd-icmp6-nd.h"
-
-#define ICMP6_ROUTER_SOLICITATION_INTERVAL 4 * USEC_PER_SEC
-#define ICMP6_MAX_ROUTER_SOLICITATIONS 3
-
-enum icmp6_nd_state {
- ICMP6_NEIGHBOR_DISCOVERY_IDLE = 0,
- ICMP6_ROUTER_SOLICITATION_SENT = 10,
- ICMP6_ROUTER_ADVERTISMENT_LISTEN = 11,
-};
-
-#define IP6_MIN_MTU (unsigned)1280
-#define ICMP6_ND_RECV_SIZE (IP6_MIN_MTU - sizeof(struct ip6_hdr))
-#define ICMP6_OPT_LEN_UNITS 8
-
-typedef struct ICMP6Prefix ICMP6Prefix;
-
-struct ICMP6Prefix {
- RefCount n_ref;
-
- LIST_FIELDS(ICMP6Prefix, prefixes);
-
- uint8_t len;
- sd_event_source *timeout_valid;
- struct in6_addr addr;
-};
-
-struct sd_icmp6_nd {
- RefCount n_ref;
-
- enum icmp6_nd_state state;
- sd_event *event;
- int event_priority;
- int index;
- struct ether_addr mac_addr;
- uint32_t mtu;
- ICMP6Prefix *expired_prefix;
- LIST_HEAD(ICMP6Prefix, prefixes);
- int fd;
- sd_event_source *recv;
- sd_event_source *timeout;
- int nd_sent;
- sd_icmp6_nd_callback_t callback;
- void *userdata;
-};
-
-#define log_icmp6_nd(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
-
-static ICMP6Prefix *icmp6_prefix_unref(ICMP6Prefix *prefix) {
- if (prefix && REFCNT_DEC(prefix->n_ref) <= 0) {
- prefix->timeout_valid =
- sd_event_source_unref(prefix->timeout_valid);
-
- free(prefix);
- }
-
- return NULL;
-}
-
-static int icmp6_prefix_new(ICMP6Prefix **ret) {
- _cleanup_free_ ICMP6Prefix *prefix = NULL;
-
- assert(ret);
-
- prefix = new0(ICMP6Prefix, 1);
- if (!prefix)
- return -ENOMEM;
-
- prefix->n_ref = REFCNT_INIT;
- LIST_INIT(prefixes, prefix);
-
- *ret = prefix;
- prefix = NULL;
-
- return 0;
-}
-
-static void icmp6_nd_notify(sd_icmp6_nd *nd, int event)
-{
- if (nd->callback)
- nd->callback(nd, event, nd->userdata);
-}
-
-int sd_icmp6_nd_set_callback(sd_icmp6_nd *nd, sd_icmp6_nd_callback_t callback,
- void *userdata) {
- assert(nd);
-
- nd->callback = callback;
- nd->userdata = userdata;
-
- return 0;
-}
-
-int sd_icmp6_nd_set_index(sd_icmp6_nd *nd, int interface_index) {
- assert(nd);
- assert(interface_index >= -1);
-
- nd->index = interface_index;
-
- return 0;
-}
-
-int sd_icmp6_nd_set_mac(sd_icmp6_nd *nd, const struct ether_addr *mac_addr) {
- assert(nd);
-
- if (mac_addr)
- memcpy(&nd->mac_addr, mac_addr, sizeof(nd->mac_addr));
- else
- zero(nd->mac_addr);
-
- return 0;
-
-}
-
-int sd_icmp6_nd_attach_event(sd_icmp6_nd *nd, sd_event *event, int priority) {
- int r;
-
- assert_return(nd, -EINVAL);
- assert_return(!nd->event, -EBUSY);
-
- if (event)
- nd->event = sd_event_ref(event);
- else {
- r = sd_event_default(&nd->event);
- if (r < 0)
- return 0;
- }
-
- nd->event_priority = priority;
-
- return 0;
-}
-
-int sd_icmp6_nd_detach_event(sd_icmp6_nd *nd) {
- assert_return(nd, -EINVAL);
-
- nd->event = sd_event_unref(nd->event);
-
- return 0;
-}
-
-sd_event *sd_icmp6_nd_get_event(sd_icmp6_nd *nd) {
- assert(nd);
-
- return nd->event;
-}
-
-sd_icmp6_nd *sd_icmp6_nd_ref(sd_icmp6_nd *nd) {
- assert (nd);
-
- assert_se(REFCNT_INC(nd->n_ref) >= 2);
-
- return nd;
-}
-
-static int icmp6_nd_init(sd_icmp6_nd *nd) {
- assert(nd);
-
- nd->recv = sd_event_source_unref(nd->recv);
- nd->fd = asynchronous_close(nd->fd);
- nd->timeout = sd_event_source_unref(nd->timeout);
-
- return 0;
-}
-
-sd_icmp6_nd *sd_icmp6_nd_unref(sd_icmp6_nd *nd) {
- if (nd && REFCNT_DEC(nd->n_ref) == 0) {
- ICMP6Prefix *prefix, *p;
-
- icmp6_nd_init(nd);
- sd_icmp6_nd_detach_event(nd);
-
- LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) {
- LIST_REMOVE(prefixes, nd->prefixes, prefix);
-
- prefix = icmp6_prefix_unref(prefix);
- }
-
- free(nd);
- }
-
- return NULL;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_icmp6_nd*, sd_icmp6_nd_unref);
-#define _cleanup_sd_icmp6_nd_free_ _cleanup_(sd_icmp6_nd_unrefp)
-
-int sd_icmp6_nd_new(sd_icmp6_nd **ret) {
- _cleanup_sd_icmp6_nd_free_ sd_icmp6_nd *nd = NULL;
-
- assert(ret);
-
- nd = new0(sd_icmp6_nd, 1);
- if (!nd)
- return -ENOMEM;
-
- nd->n_ref = REFCNT_INIT;
-
- nd->index = -1;
- nd->fd = -1;
-
- LIST_HEAD_INIT(nd->prefixes);
-
- *ret = nd;
- nd = NULL;
-
- return 0;
-}
-
-int sd_icmp6_ra_get_mtu(sd_icmp6_nd *nd, uint32_t *mtu) {
- assert_return(nd, -EINVAL);
- assert_return(mtu, -EINVAL);
-
- if (nd->mtu == 0)
- return -ENOMSG;
-
- *mtu = nd->mtu;
-
- return 0;
-}
-
-static int icmp6_ra_prefix_timeout(sd_event_source *s, uint64_t usec,
- void *userdata) {
- sd_icmp6_nd *nd = userdata;
- ICMP6Prefix *prefix, *p;
-
- assert(nd);
-
- LIST_FOREACH_SAFE(prefixes, prefix, p, nd->prefixes) {
- if (prefix->timeout_valid != s)
- continue;
-
- log_icmp6_nd(nd, "Prefix expired "SD_ICMP6_ADDRESS_FORMAT_STR"/%d",
- SD_ICMP6_ADDRESS_FORMAT_VAL(prefix->addr),
- prefix->len);
-
- LIST_REMOVE(prefixes, nd->prefixes, prefix);
-
- nd->expired_prefix = prefix;
- icmp6_nd_notify(nd,
- ICMP6_EVENT_ROUTER_ADVERTISMENT_PREFIX_EXPIRED);
- nd->expired_prefix = NULL;
-
- prefix = icmp6_prefix_unref(prefix);
-
- break;
- }
-
- return 0;
-}
-
-static int icmp6_ra_prefix_set_timeout(sd_icmp6_nd *nd,
- ICMP6Prefix *prefix,
- usec_t valid) {
- usec_t time_now;
- int r;
-
- assert_return(prefix, -EINVAL);
-
- r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- return r;
-
- prefix->timeout_valid = sd_event_source_unref(prefix->timeout_valid);
-
- r = sd_event_add_time(nd->event, &prefix->timeout_valid,
- clock_boottime_or_monotonic(), time_now + valid,
- USEC_PER_SEC, icmp6_ra_prefix_timeout, nd);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(prefix->timeout_valid,
- nd->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(prefix->timeout_valid,
- "icmp6-prefix-timeout");
-
-error:
- if (r < 0)
- prefix->timeout_valid =
- sd_event_source_unref(prefix->timeout_valid);
-
- return r;
-}
-
-static int icmp6_prefix_match(const struct in6_addr *prefix, uint8_t prefixlen,
- const struct in6_addr *addr,
- uint8_t addr_prefixlen) {
- uint8_t bytes, mask, len;
-
- assert_return(prefix, -EINVAL);
- assert_return(addr, -EINVAL);
-
- len = MIN(prefixlen, addr_prefixlen);
-
- bytes = len / 8;
- mask = 0xff << (8 - len % 8);
-
- if (memcmp(prefix, addr, bytes) != 0 ||
- (prefix->s6_addr[bytes] & mask) != (addr->s6_addr[bytes] & mask))
- return -EADDRNOTAVAIL;
-
- return 0;
-}
-
-static int icmp6_ra_prefix_match(ICMP6Prefix *head, const struct in6_addr *addr,
- uint8_t addr_len, ICMP6Prefix **result) {
- ICMP6Prefix *prefix;
-
- LIST_FOREACH(prefixes, prefix, head) {
- if (icmp6_prefix_match(&prefix->addr, prefix->len, addr,
- addr_len) >= 0) {
- *result = prefix;
- return 0;
- }
- }
-
- return -EADDRNOTAVAIL;
-}
-
-int sd_icmp6_prefix_match(struct in6_addr *prefix, uint8_t prefixlen,
- struct in6_addr *addr) {
- return icmp6_prefix_match(prefix, prefixlen, addr,
- sizeof(addr->s6_addr) * 8);
-}
-
-int sd_icmp6_ra_get_prefixlen(sd_icmp6_nd *nd, const struct in6_addr *addr,
- uint8_t *prefixlen) {
- int r;
- ICMP6Prefix *prefix;
-
- assert_return(nd, -EINVAL);
- assert_return(addr, -EINVAL);
- assert_return(prefixlen, -EINVAL);
-
- r = icmp6_ra_prefix_match(nd->prefixes, addr,
- sizeof(addr->s6_addr) * 8, &prefix);
- if (r < 0)
- return r;
-
- *prefixlen = prefix->len;
-
- return 0;
-}
-
-int sd_icmp6_ra_get_expired_prefix(sd_icmp6_nd *nd, struct in6_addr **addr,
- uint8_t *prefixlen)
-{
- assert_return(nd, -EINVAL);
- assert_return(addr, -EINVAL);
- assert_return(prefixlen, -EINVAL);
-
- if (!nd->expired_prefix)
- return -EADDRNOTAVAIL;
-
- *addr = &nd->expired_prefix->addr;
- *prefixlen = nd->expired_prefix->len;
-
- return 0;
-}
-
-static int icmp6_ra_prefix_update(sd_icmp6_nd *nd, ssize_t len,
- const struct nd_opt_prefix_info *prefix_opt) {
- int r;
- ICMP6Prefix *prefix;
- uint32_t lifetime;
- char time_string[FORMAT_TIMESPAN_MAX];
-
- assert_return(nd, -EINVAL);
- assert_return(prefix_opt, -EINVAL);
-
- if (len < prefix_opt->nd_opt_pi_len)
- return -ENOMSG;
-
- if (!(prefix_opt->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK))
- return 0;
-
- lifetime = be32toh(prefix_opt->nd_opt_pi_valid_time);
-
- r = icmp6_ra_prefix_match(nd->prefixes,
- &prefix_opt->nd_opt_pi_prefix,
- prefix_opt->nd_opt_pi_prefix_len, &prefix);
-
- if (r < 0 && r != -EADDRNOTAVAIL)
- return r;
-
- /* if router advertisment prefix valid timeout is zero, the timeout
- callback will be called immediately to clean up the prefix */
-
- if (r == -EADDRNOTAVAIL) {
- r = icmp6_prefix_new(&prefix);
- if (r < 0)
- return r;
-
- prefix->len = prefix_opt->nd_opt_pi_prefix_len;
-
- memcpy(&prefix->addr, &prefix_opt->nd_opt_pi_prefix,
- sizeof(prefix->addr));
-
- log_icmp6_nd(nd, "New prefix "SD_ICMP6_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s",
- SD_ICMP6_ADDRESS_FORMAT_VAL(prefix->addr),
- prefix->len, lifetime,
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- lifetime * USEC_PER_SEC, 0));
-
- LIST_PREPEND(prefixes, nd->prefixes, prefix);
-
- } else {
- if (prefix->len != prefix_opt->nd_opt_pi_prefix_len) {
- uint8_t prefixlen;
-
- prefixlen = MIN(prefix->len, prefix_opt->nd_opt_pi_prefix_len);
-
- log_icmp6_nd(nd, "Prefix length mismatch %d/%d using %d",
- prefix->len,
- prefix_opt->nd_opt_pi_prefix_len,
- prefixlen);
-
- prefix->len = prefixlen;
- }
-
- log_icmp6_nd(nd, "Update prefix "SD_ICMP6_ADDRESS_FORMAT_STR"/%d lifetime %d expires in %s",
- SD_ICMP6_ADDRESS_FORMAT_VAL(prefix->addr),
- prefix->len, lifetime,
- format_timespan(time_string, FORMAT_TIMESPAN_MAX,
- lifetime * USEC_PER_SEC, 0));
- }
-
- r = icmp6_ra_prefix_set_timeout(nd, prefix, lifetime * USEC_PER_SEC);
-
- return r;
-}
-
-static int icmp6_ra_parse(sd_icmp6_nd *nd, struct nd_router_advert *ra,
- ssize_t len) {
- void *opt;
- struct nd_opt_hdr *opt_hdr;
-
- assert_return(nd, -EINVAL);
- assert_return(ra, -EINVAL);
-
- len -= sizeof(*ra);
- if (len < ICMP6_OPT_LEN_UNITS) {
- log_icmp6_nd(nd, "Router Advertisement below minimum length");
-
- return -ENOMSG;
- }
-
- opt = ra + 1;
- opt_hdr = opt;
-
- while (len != 0 && len >= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS) {
- struct nd_opt_mtu *opt_mtu;
- uint32_t mtu;
- struct nd_opt_prefix_info *opt_prefix;
-
- if (opt_hdr->nd_opt_len == 0)
- return -ENOMSG;
-
- switch (opt_hdr->nd_opt_type) {
- case ND_OPT_MTU:
- opt_mtu = opt;
-
- mtu = be32toh(opt_mtu->nd_opt_mtu_mtu);
-
- if (mtu != nd->mtu) {
- nd->mtu = MAX(mtu, IP6_MIN_MTU);
-
- log_icmp6_nd(nd, "Router Advertisement link MTU %d using %d",
- mtu, nd->mtu);
- }
-
- break;
-
- case ND_OPT_PREFIX_INFORMATION:
- opt_prefix = opt;
-
- icmp6_ra_prefix_update(nd, len, opt_prefix);
-
- break;
- }
-
- len -= opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS;
- opt = (void *)((char *)opt +
- opt_hdr->nd_opt_len * ICMP6_OPT_LEN_UNITS);
- opt_hdr = opt;
- }
-
- if (len > 0)
- log_icmp6_nd(nd, "Router Advertisement contains %zd bytes of trailing garbage", len);
-
- return 0;
-}
-
-static int icmp6_router_advertisment_recv(sd_event_source *s, int fd,
- uint32_t revents, void *userdata)
-{
- sd_icmp6_nd *nd = userdata;
- int r, buflen = 0;
- ssize_t len;
- _cleanup_free_ struct nd_router_advert *ra = NULL;
- int event = ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE;
-
- assert(s);
- assert(nd);
- assert(nd->event);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0 || buflen <= 0)
- buflen = ICMP6_ND_RECV_SIZE;
-
- ra = malloc(buflen);
- if (!ra)
- return -ENOMEM;
-
- len = read(fd, ra, buflen);
- if (len < 0) {
- log_icmp6_nd(nd, "Could not receive message from UDP socket: %m");
- return 0;
- }
-
- if (ra->nd_ra_type != ND_ROUTER_ADVERT)
- return 0;
-
- if (ra->nd_ra_code != 0)
- return 0;
-
- nd->timeout = sd_event_source_unref(nd->timeout);
-
- nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN;
-
- if (ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER )
- event = ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER;
-
- if (ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED)
- event = ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED;
-
- log_icmp6_nd(nd, "Received Router Advertisement flags %s/%s",
- ra->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED? "MANAGED": "none",
- ra->nd_ra_flags_reserved & ND_RA_FLAG_OTHER? "OTHER": "none");
-
- if (event != ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE) {
- r = icmp6_ra_parse(nd, ra, len);
- if (r < 0) {
- log_icmp6_nd(nd, "Could not parse Router Advertisement: %s",
- strerror(-r));
- return 0;
- }
- }
-
- icmp6_nd_notify(nd, event);
-
- return 0;
-}
-
-static int icmp6_router_solicitation_timeout(sd_event_source *s, uint64_t usec,
- void *userdata)
-{
- sd_icmp6_nd *nd = userdata;
- uint64_t time_now, next_timeout;
- struct ether_addr unset = { };
- struct ether_addr *addr = NULL;
- int r;
-
- assert(s);
- assert(nd);
- assert(nd->event);
-
- nd->timeout = sd_event_source_unref(nd->timeout);
-
- if (nd->nd_sent >= ICMP6_MAX_ROUTER_SOLICITATIONS) {
- icmp6_nd_notify(nd, ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT);
- nd->state = ICMP6_ROUTER_ADVERTISMENT_LISTEN;
- } else {
- if (memcmp(&nd->mac_addr, &unset, sizeof(struct ether_addr)))
- addr = &nd->mac_addr;
-
- r = dhcp_network_icmp6_send_router_solicitation(nd->fd, addr);
- if (r < 0)
- log_icmp6_nd(nd, "Error sending Router Solicitation");
- else {
- nd->state = ICMP6_ROUTER_SOLICITATION_SENT;
- log_icmp6_nd(nd, "Sent Router Solicitation");
- }
-
- nd->nd_sent++;
-
- r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0) {
- icmp6_nd_notify(nd, r);
- return 0;
- }
-
- next_timeout = time_now + ICMP6_ROUTER_SOLICITATION_INTERVAL;
-
- r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
- next_timeout, 0,
- icmp6_router_solicitation_timeout, nd);
- if (r < 0) {
- icmp6_nd_notify(nd, r);
- return 0;
- }
-
- r = sd_event_source_set_priority(nd->timeout,
- nd->event_priority);
- if (r < 0) {
- icmp6_nd_notify(nd, r);
- return 0;
- }
-
- r = sd_event_source_set_description(nd->timeout, "icmp6-timeout");
- if (r < 0) {
- icmp6_nd_notify(nd, r);
- return 0;
- }
- }
-
- return 0;
-}
-
-int sd_icmp6_nd_stop(sd_icmp6_nd *nd) {
- assert_return(nd, -EINVAL);
- assert_return(nd->event, -EINVAL);
-
- log_icmp6_nd(client, "Stop ICMPv6");
-
- icmp6_nd_init(nd);
-
- nd->state = ICMP6_NEIGHBOR_DISCOVERY_IDLE;
-
- return 0;
-}
-
-int sd_icmp6_router_solicitation_start(sd_icmp6_nd *nd) {
- int r;
-
- assert(nd);
- assert(nd->event);
-
- if (nd->state != ICMP6_NEIGHBOR_DISCOVERY_IDLE)
- return -EINVAL;
-
- if (nd->index < 1)
- return -EINVAL;
-
- r = dhcp_network_icmp6_bind_router_solicitation(nd->index);
- if (r < 0)
- return r;
-
- nd->fd = r;
-
- r = sd_event_add_io(nd->event, &nd->recv, nd->fd, EPOLLIN,
- icmp6_router_advertisment_recv, nd);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(nd->recv, nd->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(nd->recv, "icmp6-receive-message");
- if (r < 0)
- goto error;
-
- r = sd_event_add_time(nd->event, &nd->timeout, clock_boottime_or_monotonic(),
- 0, 0, icmp6_router_solicitation_timeout, nd);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_priority(nd->timeout, nd->event_priority);
- if (r < 0)
- goto error;
-
- r = sd_event_source_set_description(nd->timeout, "icmp6-timeout");
-error:
- if (r < 0)
- icmp6_nd_init(nd);
- else
- log_icmp6_nd(client, "Start Router Solicitation");
-
- return r;
-}
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
deleted file mode 100644
index 02f2f9e0a9..0000000000
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Axis Communications AB. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <arpa/inet.h>
-
-#include "util.h"
-#include "siphash24.h"
-#include "list.h"
-#include "refcnt.h"
-
-#include "ipv4ll-internal.h"
-#include "sd-ipv4ll.h"
-
-/* Constants from the RFC */
-#define PROBE_WAIT 1
-#define PROBE_NUM 3
-#define PROBE_MIN 1
-#define PROBE_MAX 2
-#define ANNOUNCE_WAIT 2
-#define ANNOUNCE_NUM 2
-#define ANNOUNCE_INTERVAL 2
-#define MAX_CONFLICTS 10
-#define RATE_LIMIT_INTERVAL 60
-#define DEFEND_INTERVAL 10
-
-#define IPV4LL_NETWORK 0xA9FE0000L
-#define IPV4LL_NETMASK 0xFFFF0000L
-
-typedef enum IPv4LLTrigger{
- IPV4LL_TRIGGER_NULL,
- IPV4LL_TRIGGER_PACKET,
- IPV4LL_TRIGGER_TIMEOUT,
- _IPV4LL_TRIGGER_MAX,
- _IPV4LL_TRIGGER_INVALID = -1
-} IPv4LLTrigger;
-
-typedef enum IPv4LLState {
- IPV4LL_STATE_INIT,
- IPV4LL_STATE_WAITING_PROBE,
- IPV4LL_STATE_PROBING,
- IPV4LL_STATE_WAITING_ANNOUNCE,
- IPV4LL_STATE_ANNOUNCING,
- IPV4LL_STATE_RUNNING,
- IPV4LL_STATE_STOPPED,
- _IPV4LL_STATE_MAX,
- _IPV4LL_STATE_INVALID = -1
-} IPv4LLState;
-
-struct sd_ipv4ll {
- RefCount n_ref;
-
- IPv4LLState state;
- int index;
- int fd;
- union sockaddr_union link;
- int iteration;
- int conflict;
- sd_event_source *receive_message;
- sd_event_source *timer;
- usec_t next_wakeup;
- usec_t defend_window;
- int next_wakeup_valid;
- be32_t address;
- struct random_data *random_data;
- char *random_data_state;
- /* External */
- be32_t claimed_address;
- struct ether_addr mac_addr;
- sd_event *event;
- int event_priority;
- sd_ipv4ll_cb_t cb;
- void* userdata;
-};
-
-static void ipv4ll_run_state_machine(sd_ipv4ll *ll, IPv4LLTrigger trigger, void *trigger_data);
-
-static void ipv4ll_set_state(sd_ipv4ll *ll, IPv4LLState st, int reset_counter) {
-
- assert(ll);
- assert(st < _IPV4LL_STATE_MAX);
-
- if (st == ll->state && !reset_counter) {
- ll->iteration++;
- } else {
- ll->state = st;
- ll->iteration = 0;
- }
-}
-
-static sd_ipv4ll *ipv4ll_client_notify(sd_ipv4ll *ll, int event) {
- assert(ll);
-
- if (ll->cb) {
- ll = sd_ipv4ll_ref(ll);
- ll->cb(ll, event, ll->userdata);
- ll = sd_ipv4ll_unref(ll);
- }
-
- return ll;
-}
-
-static sd_ipv4ll *ipv4ll_stop(sd_ipv4ll *ll, int event) {
- assert(ll);
-
- ll->receive_message = sd_event_source_unref(ll->receive_message);
- ll->fd = safe_close(ll->fd);
-
- ll->timer = sd_event_source_unref(ll->timer);
-
- log_ipv4ll(ll, "STOPPED");
-
- ll = ipv4ll_client_notify(ll, event);
-
- if (ll) {
- ll->claimed_address = 0;
- ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);
- }
-
- return ll;
-}
-
-static int ipv4ll_pick_address(sd_ipv4ll *ll, be32_t *address) {
- be32_t addr;
- int r;
- int32_t random;
-
- assert(ll);
- assert(address);
- assert(ll->random_data);
-
- do {
- r = random_r(ll->random_data, &random);
- if (r < 0)
- return r;
- addr = htonl((random & 0x0000FFFF) | IPV4LL_NETWORK);
- } while (addr == ll->address ||
- (ntohl(addr) & IPV4LL_NETMASK) != IPV4LL_NETWORK ||
- (ntohl(addr) & 0x0000FF00) == 0x0000 ||
- (ntohl(addr) & 0x0000FF00) == 0xFF00);
-
- *address = addr;
- return 0;
-}
-
-static int ipv4ll_timer(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_ipv4ll *ll = (sd_ipv4ll*)userdata;
-
- assert(ll);
-
- ll->next_wakeup_valid = 0;
- ipv4ll_run_state_machine(ll, IPV4LL_TRIGGER_TIMEOUT, NULL);
-
- return 0;
-}
-
-static void ipv4ll_set_next_wakeup(sd_ipv4ll *ll, int sec, int random_sec) {
- usec_t next_timeout = 0;
- usec_t time_now = 0;
-
- assert(sec >= 0);
- assert(random_sec >= 0);
- assert(ll);
-
- next_timeout = sec * USEC_PER_SEC;
-
- if (random_sec)
- next_timeout += random_u32() % (random_sec * USEC_PER_SEC);
-
- if (sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now) < 0)
- time_now = now(clock_boottime_or_monotonic());
-
- ll->next_wakeup = time_now + next_timeout;
- ll->next_wakeup_valid = 1;
-}
-
-static bool ipv4ll_arp_conflict (sd_ipv4ll *ll, struct ether_arp *arp) {
- assert(ll);
- assert(arp);
-
- if (memcmp(arp->arp_spa, &ll->address, sizeof(ll->address)) == 0 &&
- memcmp(arp->arp_sha, &ll->mac_addr, ETH_ALEN) != 0)
- return true;
-
- return false;
-}
-
-static bool ipv4ll_arp_probe_conflict (sd_ipv4ll *ll, struct ether_arp *arp) {
- assert(ll);
- assert(arp);
-
- if (ipv4ll_arp_conflict(ll, arp))
- return true;
-
- if (memcmp(arp->arp_tpa, &ll->address, sizeof(ll->address)) == 0 &&
- memcmp(arp->arp_sha, &ll->mac_addr, ETH_ALEN))
- return true;
-
- return false;
-}
-
-static void ipv4ll_run_state_machine(sd_ipv4ll *ll, IPv4LLTrigger trigger, void *trigger_data) {
- struct ether_arp out_packet;
- int out_packet_ready = 0;
- int r = 0;
-
- assert(ll);
- assert(trigger < _IPV4LL_TRIGGER_MAX);
-
- if (ll->state == IPV4LL_STATE_INIT) {
-
- log_ipv4ll(ll, "PROBE");
- ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1);
- ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT);
-
- } else if ((ll->state == IPV4LL_STATE_WAITING_PROBE && trigger == IPV4LL_TRIGGER_TIMEOUT) ||
- (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < PROBE_NUM-2)) {
-
- /* Send a probe */
- arp_packet_probe(&out_packet, ll->address, &ll->mac_addr);
- out_packet_ready = 1;
- ipv4ll_set_state(ll, IPV4LL_STATE_PROBING, 0);
-
- ipv4ll_set_next_wakeup(ll, PROBE_MIN, (PROBE_MAX-PROBE_MIN));
-
- } else if (ll->state == IPV4LL_STATE_PROBING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration >= PROBE_NUM-2) {
-
- /* Send the last probe */
- arp_packet_probe(&out_packet, ll->address, &ll->mac_addr);
- out_packet_ready = 1;
- ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_ANNOUNCE, 1);
-
- ipv4ll_set_next_wakeup(ll, ANNOUNCE_WAIT, 0);
-
- } else if ((ll->state == IPV4LL_STATE_WAITING_ANNOUNCE && trigger == IPV4LL_TRIGGER_TIMEOUT) ||
- (ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT && ll->iteration < ANNOUNCE_NUM-1)) {
-
- /* Send announcement packet */
- arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr);
- out_packet_ready = 1;
- ipv4ll_set_state(ll, IPV4LL_STATE_ANNOUNCING, 0);
-
- ipv4ll_set_next_wakeup(ll, ANNOUNCE_INTERVAL, 0);
-
- if (ll->iteration == 0) {
- log_ipv4ll(ll, "ANNOUNCE");
- ll->claimed_address = ll->address;
- ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_BIND);
- if (!ll || ll->state == IPV4LL_STATE_STOPPED)
- goto out;
-
- ll->conflict = 0;
- }
-
- } else if ((ll->state == IPV4LL_STATE_ANNOUNCING && trigger == IPV4LL_TRIGGER_TIMEOUT &&
- ll->iteration >= ANNOUNCE_NUM-1)) {
-
- ipv4ll_set_state(ll, IPV4LL_STATE_RUNNING, 0);
- ll->next_wakeup_valid = 0;
-
- } else if (trigger == IPV4LL_TRIGGER_PACKET) {
-
- int conflicted = 0;
- usec_t time_now;
- struct ether_arp* in_packet = (struct ether_arp*)trigger_data;
-
- assert(in_packet);
-
- if (IN_SET(ll->state, IPV4LL_STATE_ANNOUNCING, IPV4LL_STATE_RUNNING)) {
-
- if (ipv4ll_arp_conflict(ll, in_packet)) {
-
- r = sd_event_now(ll->event, clock_boottime_or_monotonic(), &time_now);
- if (r < 0)
- goto out;
-
- /* Defend address */
- if (time_now > ll->defend_window) {
- ll->defend_window = time_now + DEFEND_INTERVAL * USEC_PER_SEC;
- arp_packet_announcement(&out_packet, ll->address, &ll->mac_addr);
- out_packet_ready = 1;
- } else
- conflicted = 1;
- }
-
- } else if (IN_SET(ll->state, IPV4LL_STATE_WAITING_PROBE,
- IPV4LL_STATE_PROBING,
- IPV4LL_STATE_WAITING_ANNOUNCE)) {
-
- conflicted = ipv4ll_arp_probe_conflict(ll, in_packet);
- }
-
- if (conflicted) {
- log_ipv4ll(ll, "CONFLICT");
- ll = ipv4ll_client_notify(ll, IPV4LL_EVENT_CONFLICT);
- if (!ll || ll->state == IPV4LL_STATE_STOPPED)
- goto out;
-
- ll->claimed_address = 0;
-
- /* Pick a new address */
- r = ipv4ll_pick_address(ll, &ll->address);
- if (r < 0)
- goto out;
- ll->conflict++;
- ll->defend_window = 0;
- ipv4ll_set_state(ll, IPV4LL_STATE_WAITING_PROBE, 1);
-
- if (ll->conflict >= MAX_CONFLICTS) {
- log_ipv4ll(ll, "MAX_CONFLICTS");
- ipv4ll_set_next_wakeup(ll, RATE_LIMIT_INTERVAL, PROBE_WAIT);
- } else
- ipv4ll_set_next_wakeup(ll, 0, PROBE_WAIT);
-
- }
- }
-
- if (out_packet_ready) {
- r = arp_network_send_raw_socket(ll->fd, &ll->link, &out_packet);
- if (r < 0) {
- log_ipv4ll(ll, "failed to send arp packet out");
- goto out;
- }
- }
-
- if (ll->next_wakeup_valid) {
- ll->timer = sd_event_source_unref(ll->timer);
- r = sd_event_add_time(ll->event, &ll->timer, clock_boottime_or_monotonic(),
- ll->next_wakeup, 0, ipv4ll_timer, ll);
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_priority(ll->timer, ll->event_priority);
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_description(ll->timer, "ipv4ll-timer");
- if (r < 0)
- goto out;
- }
-
-out:
- if (r < 0 && ll)
- ipv4ll_stop(ll, r);
-}
-
-static int ipv4ll_receive_message(sd_event_source *s, int fd,
- uint32_t revents, void *userdata) {
- int r;
- struct ether_arp arp;
- sd_ipv4ll *ll = (sd_ipv4ll*)userdata;
-
- assert(ll);
-
- r = read(fd, &arp, sizeof(struct ether_arp));
- if (r < (int) sizeof(struct ether_arp))
- return 0;
-
- r = arp_packet_verify_headers(&arp);
- if (r < 0)
- return 0;
-
- ipv4ll_run_state_machine(ll, IPV4LL_TRIGGER_PACKET, &arp);
-
- return 0;
-}
-
-int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index) {
- assert_return(ll, -EINVAL);
- assert_return(interface_index > 0, -EINVAL);
- assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
- IPV4LL_STATE_STOPPED), -EBUSY);
-
- ll->index = interface_index;
-
- return 0;
-}
-
-int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr) {
- bool need_restart = false;
-
- assert_return(ll, -EINVAL);
- assert_return(addr, -EINVAL);
-
- if (memcmp(&ll->mac_addr, addr, ETH_ALEN) == 0)
- return 0;
-
- if (!IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED)) {
- log_ipv4ll(ll, "Changing MAC address on running IPv4LL "
- "client, restarting");
- ll = ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
- need_restart = true;
- }
-
- if (!ll)
- return 0;
-
- memcpy(&ll->mac_addr, addr, ETH_ALEN);
-
- if (need_restart)
- sd_ipv4ll_start(ll);
-
- return 0;
-}
-
-int sd_ipv4ll_detach_event(sd_ipv4ll *ll) {
- assert_return(ll, -EINVAL);
-
- ll->event = sd_event_unref(ll->event);
-
- return 0;
-}
-
-int sd_ipv4ll_attach_event(sd_ipv4ll *ll, sd_event *event, int priority) {
- int r;
-
- assert_return(ll, -EINVAL);
- assert_return(!ll->event, -EBUSY);
-
- if (event)
- ll->event = sd_event_ref(event);
- else {
- r = sd_event_default(&ll->event);
- if (r < 0) {
- ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
- return r;
- }
- }
-
- ll->event_priority = priority;
-
- return 0;
-}
-
-int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata) {
- assert_return(ll, -EINVAL);
-
- ll->cb = cb;
- ll->userdata = userdata;
-
- return 0;
-}
-
-int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address){
- assert_return(ll, -EINVAL);
- assert_return(address, -EINVAL);
-
- if (ll->claimed_address == 0) {
- return -ENOENT;
- }
-
- address->s_addr = ll->claimed_address;
- return 0;
-}
-
-int sd_ipv4ll_set_address_seed (sd_ipv4ll *ll, uint8_t seed[8]) {
- unsigned int entropy;
- int r;
-
- assert_return(ll, -EINVAL);
- assert_return(seed, -EINVAL);
-
- entropy = *seed;
-
- free(ll->random_data);
- free(ll->random_data_state);
-
- ll->random_data = new0(struct random_data, 1);
- ll->random_data_state = new0(char, 128);
-
- if (!ll->random_data || !ll->random_data_state) {
- r = -ENOMEM;
- goto error;
- }
-
- r = initstate_r((unsigned int)entropy, ll->random_data_state, 128, ll->random_data);
- if (r < 0)
- goto error;
-
-error:
- if (r < 0){
- free(ll->random_data);
- free(ll->random_data_state);
- ll->random_data = NULL;
- ll->random_data_state = NULL;
- }
- return r;
-}
-
-bool sd_ipv4ll_is_running(sd_ipv4ll *ll) {
- assert_return(ll, -EINVAL);
-
- return !IN_SET(ll->state, IPV4LL_STATE_INIT, IPV4LL_STATE_STOPPED);
-}
-
-#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
-
-int sd_ipv4ll_start (sd_ipv4ll *ll) {
- int r;
-
- assert_return(ll, -EINVAL);
- assert_return(ll->event, -EINVAL);
- assert_return(ll->index > 0, -EINVAL);
- assert_return(IN_SET(ll->state, IPV4LL_STATE_INIT,
- IPV4LL_STATE_STOPPED), -EBUSY);
-
- ll->state = IPV4LL_STATE_INIT;
-
- r = arp_network_bind_raw_socket(ll->index, &ll->link);
-
- if (r < 0)
- goto out;
-
- ll->fd = r;
- ll->conflict = 0;
- ll->defend_window = 0;
- ll->claimed_address = 0;
-
- if (!ll->random_data) {
- uint8_t seed[8];
-
- /* Fallback to mac */
- siphash24(seed, &ll->mac_addr.ether_addr_octet,
- ETH_ALEN, HASH_KEY.bytes);
-
- r = sd_ipv4ll_set_address_seed(ll, seed);
- if (r < 0)
- goto out;
- }
-
- if (ll->address == 0) {
- r = ipv4ll_pick_address(ll, &ll->address);
- if (r < 0)
- goto out;
- }
-
- ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1);
-
- r = sd_event_add_io(ll->event, &ll->receive_message, ll->fd,
- EPOLLIN, ipv4ll_receive_message, ll);
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_priority(ll->receive_message, ll->event_priority);
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_description(ll->receive_message, "ipv4ll-receive-message");
- if (r < 0)
- goto out;
-
- r = sd_event_add_time(ll->event,
- &ll->timer,
- clock_boottime_or_monotonic(),
- now(clock_boottime_or_monotonic()), 0,
- ipv4ll_timer, ll);
-
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_priority(ll->timer, ll->event_priority);
- if (r < 0)
- goto out;
-
- r = sd_event_source_set_description(ll->timer, "ipv4ll-timer");
-out:
- if (r < 0)
- ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
-
- return 0;
-}
-
-int sd_ipv4ll_stop(sd_ipv4ll *ll) {
- ipv4ll_stop(ll, IPV4LL_EVENT_STOP);
- if (ll)
- ipv4ll_set_state(ll, IPV4LL_STATE_STOPPED, 1);
-
- return 0;
-}
-
-sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
- if (ll)
- assert_se(REFCNT_INC(ll->n_ref) >= 2);
-
- return ll;
-}
-
-sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
- if (ll && REFCNT_DEC(ll->n_ref) == 0) {
- ll->receive_message =
- sd_event_source_unref(ll->receive_message);
- ll->fd = safe_close(ll->fd);
-
- ll->timer = sd_event_source_unref(ll->timer);
-
- sd_ipv4ll_detach_event(ll);
-
- free(ll->random_data);
- free(ll->random_data_state);
- free(ll);
-
- return NULL;
- }
-
- return ll;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_ipv4ll*, sd_ipv4ll_unref);
-#define _cleanup_ipv4ll_free_ _cleanup_(sd_ipv4ll_unrefp)
-
-int sd_ipv4ll_new(sd_ipv4ll **ret) {
- _cleanup_ipv4ll_free_ sd_ipv4ll *ll = NULL;
-
- assert_return(ret, -EINVAL);
-
- ll = new0(sd_ipv4ll, 1);
- if (!ll)
- return -ENOMEM;
-
- ll->n_ref = REFCNT_INIT;
- ll->state = IPV4LL_STATE_INIT;
- ll->index = -1;
- ll->fd = -1;
-
- *ret = ll;
- ll = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c
deleted file mode 100644
index fddda97f52..0000000000
--- a/src/libsystemd-network/sd-lldp.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <arpa/inet.h>
-
-#include "siphash24.h"
-#include "hashmap.h"
-
-#include "lldp-tlv.h"
-#include "lldp-port.h"
-#include "sd-lldp.h"
-#include "prioq.h"
-#include "lldp-internal.h"
-#include "lldp-util.h"
-
-typedef enum LLDPAgentRXState {
- LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL = 4,
- LLDP_AGENT_RX_DELETE_AGED_INFO,
- LLDP_AGENT_RX_LLDP_INITIALIZE,
- LLDP_AGENT_RX_WAIT_FOR_FRAME,
- LLDP_AGENT_RX_RX_FRAME,
- LLDP_AGENT_RX_DELETE_INFO,
- LLDP_AGENT_RX_UPDATE_INFO,
- _LLDP_AGENT_RX_STATE_MAX,
- _LLDP_AGENT_RX_INVALID = -1,
-} LLDPAgentRXState;
-
-/* Section 10.5.2.2 Reception counters */
-struct lldp_agent_statistics {
- uint64_t stats_ageouts_total;
- uint64_t stats_frames_discarded_total;
- uint64_t stats_frames_in_errors_total;
- uint64_t stats_frames_in_total;
- uint64_t stats_tlvs_discarded_total;
- uint64_t stats_tlvs_unrecognized_total;
-};
-
-struct sd_lldp {
- lldp_port *port;
-
- Prioq *by_expiry;
- Hashmap *neighbour_mib;
-
- sd_lldp_cb_t cb;
-
- void *userdata;
-
- LLDPAgentRXState rx_state;
- lldp_agent_statistics statistics;
-};
-
-static unsigned long chassis_id_hash_func(const void *p,
- const uint8_t hash_key[HASH_KEY_SIZE]) {
- uint64_t u;
- const lldp_chassis_id *id = p;
-
- assert(id);
-
- siphash24((uint8_t *) &u, id->data, id->length, hash_key);
-
- return (unsigned long) u;
-}
-
-static int chassis_id_compare_func(const void *_a, const void *_b) {
- const lldp_chassis_id *a, *b;
-
- a = _a;
- b = _b;
-
- assert(!a->length || a->data);
- assert(!b->length || b->data);
-
- if (a->type != b->type)
- return -1;
-
- if (a->length != b->length)
- return a->length < b->length ? -1 : 1;
-
- return memcmp(a->data, b->data, a->length);
-}
-
-static const struct hash_ops chassis_id_hash_ops = {
- .hash = chassis_id_hash_func,
- .compare = chassis_id_compare_func
-};
-
-static void lldp_mib_delete_objects(sd_lldp *lldp);
-static void lldp_set_state(sd_lldp *lldp, LLDPAgentRXState state);
-static void lldp_run_state_machine(sd_lldp *ll);
-
-static int lldp_receive_frame(sd_lldp *lldp, tlv_packet *tlv) {
- int r;
-
- assert(lldp);
- assert(tlv);
-
- /* Remove expired packets */
- if (prioq_size(lldp->by_expiry) > 0) {
-
- lldp_set_state(lldp, LLDP_AGENT_RX_DELETE_INFO);
-
- lldp_mib_delete_objects(lldp);
- }
-
- r = lldp_mib_add_objects(lldp->by_expiry, lldp->neighbour_mib, tlv);
- if (r < 0)
- goto out;
-
- lldp_set_state(lldp, LLDP_AGENT_RX_UPDATE_INFO);
-
- log_lldp("Packet added. MIB size: %d , PQ size: %d",
- hashmap_size(lldp->neighbour_mib),
- prioq_size(lldp->by_expiry));
-
- lldp->statistics.stats_frames_in_total ++;
-
- return 0;
-
- out:
- if (r < 0)
- log_lldp("Receive frame failed: %s", strerror(-r));
-
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
-
- return 0;
-}
-
-/* 10.3.2 LLDPDU validation: rxProcessFrame() */
-int lldp_handle_packet(tlv_packet *tlv, uint16_t length) {
- uint16_t type, len, i, l, t;
- bool chassis_id = false;
- bool malformed = false;
- bool port_id = false;
- bool ttl = false;
- bool end = false;
- lldp_port *port;
- uint8_t *p, *q;
- sd_lldp *lldp;
- int r;
-
- assert(tlv);
- assert(length > 0);
-
- port = (lldp_port *) tlv->userdata;
- lldp = (sd_lldp *) port->userdata;
-
- if (lldp->port->status == LLDP_PORT_STATUS_DISABLED) {
- log_lldp("Port is disabled : %s . Dropping ...",
- lldp->port->ifname);
- goto out;
- }
-
- lldp_set_state(lldp, LLDP_AGENT_RX_RX_FRAME);
-
- p = tlv->pdu;
- p += sizeof(struct ether_header);
-
- for (i = 1, l = 0; l <= length; i++) {
-
- memcpy(&t, p, sizeof(uint16_t));
-
- type = ntohs(t) >> 9;
- len = ntohs(t) & 0x01ff;
-
- if (type == LLDP_TYPE_END) {
- if (len != 0) {
- log_lldp("TLV type end is not length 0. Length:%d received . Dropping ...",
- len);
-
- malformed = true;
- goto out;
- }
-
- end = true;
-
- break;
- } else if (type >=_LLDP_TYPE_MAX) {
- log_lldp("TLV type not recognized %d . Dropping ...",
- type);
-
- malformed = true;
- goto out;
- }
-
- /* skip type and lengh encoding */
- p += 2;
- q = p;
-
- p += len;
- l += (len + 2);
-
- if (i <= 3) {
- if (i != type) {
- log_lldp("TLV missing or out of order. Dropping ...");
-
- malformed = true;
- goto out;
- }
- }
-
- switch(type) {
- case LLDP_TYPE_CHASSIS_ID:
-
- if (len < 2) {
- log_lldp("Received malformed Chassis ID TLV len = %d. Dropping",
- len);
-
- malformed = true;
- goto out;
- }
-
- if (chassis_id) {
- log_lldp("Duplicate Chassis ID TLV found. Dropping ...");
-
- malformed = true;
- goto out;
- }
-
- /* Look what subtype it has */
- if (*q == LLDP_CHASSIS_SUBTYPE_RESERVED ||
- *q > LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED) {
- log_lldp("Unknown subtype: %d found in Chassis ID TLV . Dropping ...",
- *q);
-
- malformed = true;
- goto out;
-
- }
-
- chassis_id = true;
-
- break;
- case LLDP_TYPE_PORT_ID:
-
- if (len < 2) {
- log_lldp("Received malformed Port ID TLV len = %d. Dropping",
- len);
-
- malformed = true;
- goto out;
- }
-
- if (port_id) {
- log_lldp("Duplicate Port ID TLV found. Dropping ...");
-
- malformed = true;
- goto out;
- }
-
- /* Look what subtype it has */
- if (*q == LLDP_PORT_SUBTYPE_RESERVED ||
- *q > LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED) {
- log_lldp("Unknown subtype: %d found in Port ID TLV . Dropping ...",
- *q);
-
- malformed = true;
- goto out;
-
- }
-
- port_id = true;
-
- break;
- case LLDP_TYPE_TTL:
-
- if(len != 2) {
- log_lldp(
- "Received invalid lenth: %d TTL TLV. Dropping ...",
- len);
-
- malformed = true;
- goto out;
- }
-
- if (ttl) {
- log_lldp("Duplicate TTL TLV found. Dropping ...");
-
- malformed = true;
- goto out;
- }
-
- ttl = true;
-
- break;
- default:
-
- if (len == 0) {
- log_lldp("TLV type = %d's, length 0 received . Dropping ...",
- type);
-
- malformed = true;
- goto out;
- }
- break;
- }
- }
-
- if(!chassis_id || !port_id || !ttl || !end) {
- log_lldp( "One or more mandotory TLV missing . Dropping ...");
-
- malformed = true;
- goto out;
-
- }
-
- r = tlv_packet_parse_pdu(tlv, length);
- if (r < 0) {
- log_lldp( "Failed to parse the TLV. Dropping ...");
-
- malformed = true;
- goto out;
- }
-
- return lldp_receive_frame(lldp, tlv);
-
- out:
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
-
- if (malformed) {
- lldp->statistics.stats_frames_discarded_total ++;
- lldp->statistics.stats_frames_in_errors_total ++;
- }
-
- tlv_packet_free(tlv);
-
- return 0;
-}
-
-static int ttl_expiry_item_prioq_compare_func(const void *a, const void *b) {
- const lldp_neighbour_port *p = a, *q = b;
-
- if (p->until < q->until)
- return -1;
-
- if (p->until > q->until)
- return 1;
-
- return 0;
-}
-
-static void lldp_set_state(sd_lldp *lldp, LLDPAgentRXState state) {
-
- assert(lldp);
- assert(state < _LLDP_AGENT_RX_STATE_MAX);
-
- lldp->rx_state = state;
-
- lldp_run_state_machine(lldp);
-}
-
-static void lldp_run_state_machine(sd_lldp *lldp) {
-
- if (lldp->rx_state == LLDP_AGENT_RX_UPDATE_INFO)
- if (lldp->cb)
- lldp->cb(lldp, LLDP_AGENT_RX_UPDATE_INFO, lldp->userdata);
-}
-
-/* 10.5.5.2.1 mibDeleteObjects ()
- * The mibDeleteObjects () procedure deletes all information in the LLDP remote
- * systems MIB associated with the MSAP identifier if an LLDPDU is received with
- * an rxTTL value of zero (see 10.3.2) or the timing counter rxInfoTTL expires. */
-
-static void lldp_mib_delete_objects(sd_lldp *lldp) {
- lldp_neighbour_port *p;
- usec_t t = 0;
-
- /* Remove all entries that are past their TTL */
- for (;;) {
-
- if (prioq_size(lldp->by_expiry) <= 0)
- break;
-
- p = prioq_peek(lldp->by_expiry);
- if (!p)
- break;
-
- if (t <= 0)
- t = now(CLOCK_BOOTTIME);
-
- if (p->until > t)
- break;
-
- lldp_neighbour_port_remove_and_free(p);
-
- lldp->statistics.stats_ageouts_total ++;
- }
-}
-
-static void lldp_mib_objects_flush(sd_lldp *lldp) {
- lldp_neighbour_port *p, *q;
- lldp_chassis *c;
-
- assert(lldp);
- assert(lldp->neighbour_mib);
- assert(lldp->by_expiry);
-
- /* Drop all packets */
- while ((c = hashmap_steal_first(lldp->neighbour_mib))) {
-
- LIST_FOREACH_SAFE(port, p, q, c->ports) {
- lldp_neighbour_port_remove_and_free(p);
- }
- }
-
- assert(hashmap_size(lldp->neighbour_mib) == 0);
- assert(prioq_size(lldp->by_expiry) == 0);
-}
-
-int sd_lldp_save(sd_lldp *lldp, const char *lldp_file) {
- _cleanup_free_ char *temp_path = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- uint8_t *mac, *port_id, type;
- lldp_neighbour_port *p;
- uint16_t data = 0, length = 0;
- char buf[LINE_MAX];
- lldp_chassis *c;
- usec_t time;
- Iterator i;
- int r;
-
- assert(lldp);
- assert(lldp_file);
-
- r = fopen_temporary(lldp_file, &f, &temp_path);
- if (r < 0)
- goto finish;
-
- fchmod(fileno(f), 0644);
-
- HASHMAP_FOREACH(c, lldp->neighbour_mib, i) {
- LIST_FOREACH(port, p, c->ports) {
- _cleanup_free_ char *s = NULL;
- char *k, *t;
-
- r = lldp_read_chassis_id(p->packet, &type, &length, &mac);
- if (r < 0)
- continue;
-
- sprintf(buf, "'_Chassis=%02x:%02x:%02x:%02x:%02x:%02x' '_CType=%d' ",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], type);
-
- s = strdup(buf);
- if (!s)
- return -ENOMEM;
-
- r = lldp_read_port_id(p->packet, &type, &length, &port_id);
- if (r < 0)
- continue;
-
- if (type != LLDP_PORT_SUBTYPE_MAC_ADDRESS) {
- k = strndup((char *) port_id, length -1);
- if (!k)
- return -ENOMEM;
-
- sprintf(buf, "'_Port=%s' '_PType=%d' ", k , type);
- free(k);
- } else {
- mac = port_id;
- sprintf(buf, "'_Port=%02x:%02x:%02x:%02x:%02x:%02x' '_PType=%d' ",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], type);
- }
-
- k = strappend(s, buf);
- if (!k)
- return -ENOMEM;
-
- free(s);
- s = k;
-
- time = now(CLOCK_BOOTTIME);
-
- /* Don't write expired packets */
- if (time - p->until <= 0)
- continue;
-
- sprintf(buf, "'_TTL="USEC_FMT"' ", p->until);
-
- k = strappend(s, buf);
- if (!k)
- return -ENOMEM;
-
- free(s);
- s = k;
-
- r = lldp_read_system_name(p->packet, &length, &k);
- if (r < 0)
- k = strappend(s, "'_NAME=N/A' ");
- else {
- t = strndup(k, length);
- if (!t)
- return -ENOMEM;
-
- k = strjoin(s, "'_NAME=", t, "' ", NULL);
- free(t);
- }
-
- if (!k)
- return -ENOMEM;
-
- free(s);
- s = k;
-
- (void) lldp_read_system_capability(p->packet, &data);
-
- sprintf(buf, "'_CAP=%x'", data);
-
- k = strappend(s, buf);
- if (!k)
- return -ENOMEM;
-
- free(s);
- s = k;
-
- fprintf(f, "%s\n", s);
- }
- }
- r = 0;
-
- fflush(f);
-
- if (ferror(f) || rename(temp_path, lldp_file) < 0) {
- r = -errno;
- unlink(lldp_file);
- unlink(temp_path);
- }
-
- finish:
- if (r < 0)
- log_error("Failed to save lldp data %s: %s", lldp_file, strerror(-r));
-
- return r;
-}
-
-int sd_lldp_start(sd_lldp *lldp) {
- int r;
-
- assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
-
- lldp->port->status = LLDP_PORT_STATUS_ENABLED;
-
- lldp_set_state(lldp, LLDP_AGENT_RX_LLDP_INITIALIZE);
-
- r = lldp_port_start(lldp->port);
- if (r < 0) {
- log_lldp("Failed to start Port : %s , %s",
- lldp->port->ifname,
- strerror(-r));
-
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL);
-
- return r;
- }
-
- lldp_set_state(lldp, LLDP_AGENT_RX_WAIT_FOR_FRAME);
-
- return 0;
-}
-
-int sd_lldp_stop(sd_lldp *lldp) {
- int r;
-
- assert_return(lldp, -EINVAL);
- assert_return(lldp->port, -EINVAL);
-
- lldp->port->status = LLDP_PORT_STATUS_DISABLED;
-
- r = lldp_port_stop(lldp->port);
- if (r < 0)
- return r;
-
- lldp_mib_objects_flush(lldp);
-
- return 0;
-}
-
-int sd_lldp_attach_event(sd_lldp *lldp, sd_event *event, int priority) {
- int r;
-
- assert_return(lldp, -EINVAL);
- assert_return(!lldp->port->event, -EBUSY);
-
- if (event)
- lldp->port->event = sd_event_ref(event);
- else {
- r = sd_event_default(&lldp->port->event);
- if (r < 0)
- return r;
- }
-
- lldp->port->event_priority = priority;
-
- return 0;
-}
-
-int sd_lldp_detach_event(sd_lldp *lldp) {
-
- assert_return(lldp, -EINVAL);
-
- lldp->port->event = sd_event_unref(lldp->port->event);
-
- return 0;
-}
-
-int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_cb_t cb, void *userdata) {
- assert_return(lldp, -EINVAL);
-
- lldp->cb = cb;
- lldp->userdata = userdata;
-
- return 0;
-}
-
-void sd_lldp_free(sd_lldp *lldp) {
-
- if (!lldp)
- return;
-
- /* Drop all packets */
- lldp_mib_objects_flush(lldp);
-
- lldp_port_free(lldp->port);
-
- hashmap_free(lldp->neighbour_mib);
- prioq_free(lldp->by_expiry);
-
- free(lldp);
-}
-
-int sd_lldp_new(int ifindex,
- const char *ifname,
- const struct ether_addr *mac,
- sd_lldp **ret) {
- _cleanup_lldp_free_ sd_lldp *lldp = NULL;
- int r;
-
- assert_return(ret, -EINVAL);
- assert_return(ifindex > 0, -EINVAL);
- assert_return(ifname, -EINVAL);
- assert_return(mac, -EINVAL);
-
- lldp = new0(sd_lldp, 1);
- if (!lldp)
- return -ENOMEM;
-
- r = lldp_port_new(ifindex, ifname, mac, lldp, &lldp->port);
- if (r < 0)
- return r;
-
- lldp->neighbour_mib = hashmap_new(&chassis_id_hash_ops);
- if (!lldp->neighbour_mib)
- return -ENOMEM;
-
- r = prioq_ensure_allocated(&lldp->by_expiry,
- ttl_expiry_item_prioq_compare_func);
- if (r < 0)
- return r;
-
- lldp->rx_state = LLDP_AGENT_RX_WAIT_PORT_OPERATIONAL;
-
- *ret = lldp;
- lldp = NULL;
-
- return 0;
-}
diff --git a/src/libsystemd-network/sd-pppoe.c b/src/libsystemd-network/sd-pppoe.c
deleted file mode 100644
index 601f3bd400..0000000000
--- a/src/libsystemd-network/sd-pppoe.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-/* See RFC 2516 */
-
-#include <sys/ioctl.h>
-#include <linux/ppp_defs.h>
-#include <linux/ppp-ioctl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <linux/if_pppox.h>
-
-#include "sd-pppoe.h"
-
-#include "event-util.h"
-
-#include "util.h"
-#include "socket-util.h"
-#include "async.h"
-#include "refcnt.h"
-#include "utf8.h"
-
-#define PPPOE_MAX_PACKET_SIZE 1484
-#define PPPOE_MAX_PADR_RESEND 16
-
-/* TODO: move this to socket-util.h without getting into
- * a mess with the includes */
-union sockaddr_union_pppox {
- struct sockaddr sa;
- struct sockaddr_pppox pppox;
-};
-
-typedef enum PPPoEState {
- PPPOE_STATE_INITIALIZING,
- PPPOE_STATE_REQUESTING,
- PPPOE_STATE_RUNNING,
- PPPOE_STATE_STOPPED,
- _PPPOE_STATE_MAX,
- _PPPOE_STATE_INVALID = -1,
-} PPPoEState;
-
-typedef struct PPPoETags {
- char *service_name;
- char *ac_name;
- uint8_t *host_uniq;
- size_t host_uniq_len;
- uint8_t *cookie;
- size_t cookie_len;
-} PPPoETags;
-
-struct sd_pppoe {
- RefCount n_ref;
-
- PPPoEState state;
- uint64_t host_uniq;
-
- int ifindex;
- char *ifname;
-
- sd_event *event;
- int event_priority;
- int fd;
- sd_event_source *io;
- sd_event_source *timeout;
- int padr_resend_count;
-
- char *service_name;
- struct ether_addr peer_mac;
- be16_t session_id;
-
- int pppoe_fd;
- int channel;
-
- sd_pppoe_cb_t cb;
- void *userdata;
-
- PPPoETags tags;
-};
-
-#define PPPOE_PACKET_LENGTH(header) \
- be16toh((header)->length)
-
-#define PPPOE_PACKET_TAIL(packet) \
- (struct pppoe_tag*)((uint8_t*)(packet) + sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
-
-#define PPPOE_TAG_LENGTH(tag) \
- be16toh((tag)->tag_len)
-
-#define PPPOE_TAG_TYPE(tag) \
- (tag)->tag_type
-
-#define PPPOE_TAG_NEXT(tag) \
- (struct pppoe_tag *)((uint8_t *)(tag) + sizeof(struct pppoe_tag) + PPPOE_TAG_LENGTH(tag))
-
-#define PPPOE_TAGS_FOREACH(tag, header) \
- for (tag = (header)->tag; \
- ((uint8_t *)(tag) + sizeof(struct pppoe_tag) < (uint8_t*)PPPOE_PACKET_TAIL(header)) && \
- (PPPOE_TAG_NEXT(tag) <= PPPOE_PACKET_TAIL(header)) && \
- (tag >= (header)->tag) && \
- (PPPOE_TAG_TYPE(tag) != PTT_EOL); \
- tag = PPPOE_TAG_NEXT(tag))
-
-static void pppoe_tags_clear(PPPoETags *tags) {
- free(tags->service_name);
- free(tags->ac_name);
- free(tags->host_uniq);
- free(tags->cookie);
-
- zero(*tags);
-}
-
-int sd_pppoe_set_ifindex(sd_pppoe *ppp, int ifindex) {
- assert_return(ppp, -EINVAL);
- assert_return(ifindex > 0, -EINVAL);
-
- ppp->ifindex = ifindex;
-
- return 0;
-}
-
-int sd_pppoe_set_ifname(sd_pppoe *ppp, const char *ifname) {
- char *name;
-
- assert_return(ppp, -EINVAL);
- assert_return(ifname, -EINVAL);
-
- if (strlen(ifname) > IFNAMSIZ)
- return -EINVAL;
-
- name = strdup(ifname);
- if (!name)
- return -ENOMEM;
-
- free(ppp->ifname);
- ppp->ifname = name;
-
- return 0;
-}
-
-int sd_pppoe_set_service_name(sd_pppoe *ppp, const char *service_name) {
- _cleanup_free_ char *name = NULL;
-
- assert_return(ppp, -EINVAL);
-
- if (service_name) {
- name = strdup(service_name);
- if (!name)
- return -ENOMEM;
- }
-
- free(ppp->service_name);
- ppp->service_name = name;
- name = NULL;
-
- return 0;
-}
-
-int sd_pppoe_attach_event(sd_pppoe *ppp, sd_event *event, int priority) {
- int r;
-
- assert_return(ppp, -EINVAL);
- assert_return(!ppp->event, -EBUSY);
-
- if (event)
- ppp->event = sd_event_ref(event);
- else {
- r = sd_event_default(&ppp->event);
- if (r < 0)
- return r;
- }
-
- ppp->event_priority = priority;
-
- return 0;
-}
-
-int sd_pppoe_detach_event(sd_pppoe *ppp) {
- assert_return(ppp, -EINVAL);
-
- ppp->event = sd_event_unref(ppp->event);
-
- return 0;
-}
-
-sd_pppoe *sd_pppoe_ref(sd_pppoe *ppp) {
- if (ppp)
- assert_se(REFCNT_INC(ppp->n_ref) >= 2);
-
- return ppp;
-}
-
-sd_pppoe *sd_pppoe_unref(sd_pppoe *ppp) {
- if (ppp && REFCNT_DEC(ppp->n_ref) <= 0) {
- pppoe_tags_clear(&ppp->tags);
- free(ppp->ifname);
- free(ppp->service_name);
- sd_pppoe_stop(ppp);
- sd_pppoe_detach_event(ppp);
-
- free(ppp);
- }
-
- return NULL;
-}
-
-int sd_pppoe_new (sd_pppoe **ret) {
- sd_pppoe *ppp;
-
- assert_return(ret, -EINVAL);
-
- ppp = new0(sd_pppoe, 1);
- if (!ppp)
- return -ENOMEM;
-
- ppp->n_ref = REFCNT_INIT;
- ppp->state = _PPPOE_STATE_INVALID;
- ppp->ifindex = -1;
- ppp->fd = -1;
- ppp->pppoe_fd = -1;
- ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
-
- *ret = ppp;
-
- return 0;
-}
-
-int sd_pppoe_get_channel(sd_pppoe *ppp, int *channel) {
- assert_return(ppp, -EINVAL);
- assert_return(channel, -EINVAL);
- assert_return(ppp->pppoe_fd != -1, -EUNATCH);
- assert_return(ppp->state == PPPOE_STATE_RUNNING, -EUNATCH);
-
- *channel = ppp->channel;
-
- return 0;
-}
-
-int sd_pppoe_set_callback(sd_pppoe *ppp, sd_pppoe_cb_t cb, void *userdata) {
- assert_return(ppp, -EINVAL);
-
- ppp->cb = cb;
- ppp->userdata = userdata;
-
- return 0;
-}
-
-static void pppoe_tag_append(struct pppoe_hdr *packet, size_t packet_size, be16_t tag_type, const void *tag_data, uint16_t tag_len) {
- struct pppoe_tag *tag;
-
- assert(packet);
- assert(sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len <= packet_size);
- assert(!(!tag_data ^ !tag_len));
-
- tag = PPPOE_PACKET_TAIL(packet);
-
- tag->tag_len = htobe16(tag_len);
- tag->tag_type = tag_type;
- if (tag_data)
- memcpy(tag->tag_data, tag_data, tag_len);
-
- packet->length = htobe16(PPPOE_PACKET_LENGTH(packet) + sizeof(struct pppoe_tag) + tag_len);
-}
-
-static int pppoe_send(sd_pppoe *ppp, uint8_t code) {
- union sockaddr_union link = {
- .ll = {
- .sll_family = AF_PACKET,
- .sll_protocol = htons(ETH_P_PPP_DISC),
- .sll_halen = ETH_ALEN,
- },
- };
- _cleanup_free_ struct pppoe_hdr *packet = NULL;
- int r;
-
- assert(ppp);
- assert(ppp->fd != -1);
- assert(IN_SET(code, PADI_CODE, PADR_CODE, PADT_CODE));
-
- link.ll.sll_ifindex = ppp->ifindex;
- if (code == PADI_CODE)
- memset(&link.ll.sll_addr, 0xff, ETH_ALEN);
- else
- memcpy(&link.ll.sll_addr, &ppp->peer_mac, ETH_ALEN);
-
- packet = malloc0(PPPOE_MAX_PACKET_SIZE);
- if (!packet)
- return -ENOMEM;
-
- packet->ver = 0x1;
- packet->type = 0x1;
- packet->code = code;
- if (code == PADT_CODE)
- packet->sid = ppp->session_id;
-
- /* Service-Name */
- pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_SRV_NAME,
- ppp->service_name, ppp->service_name ? strlen(ppp->service_name) : 0);
-
- /* AC-Cookie */
- if (code == PADR_CODE && ppp->tags.cookie)
- pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_AC_COOKIE,
- ppp->tags.cookie, ppp->tags.cookie_len);
-
- /* Host-Uniq */
- if (code != PADT_CODE) {
- ppp->host_uniq = random_u64();
-
- pppoe_tag_append(packet, PPPOE_MAX_PACKET_SIZE, PTT_HOST_UNIQ,
- &ppp->host_uniq, sizeof(ppp->host_uniq));
- }
-
- r = sendto(ppp->fd, packet, sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet),
- 0, &link.sa, sizeof(link.ll));
- if (r < 0)
- return -errno;
-
- return 0;
-}
-
-static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata);
-
-static int pppoe_arm_timeout(sd_pppoe *ppp) {
- _cleanup_event_source_unref_ sd_event_source *timeout = NULL;
- usec_t next_timeout = 0;
- int r;
-
- assert(ppp);
-
- r = sd_event_now(ppp->event, clock_boottime_or_monotonic(), &next_timeout);
- if (r == -ENODATA)
- next_timeout = now(clock_boottime_or_monotonic());
- else if (r < 0)
- return r;
-
- next_timeout += 500 * USEC_PER_MSEC;
-
- r = sd_event_add_time(ppp->event, &timeout, clock_boottime_or_monotonic(), next_timeout,
- 10 * USEC_PER_MSEC, pppoe_timeout, ppp);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(timeout, ppp->event_priority);
- if (r < 0)
- return r;
-
- sd_event_source_unref(ppp->timeout);
- ppp->timeout = timeout;
- timeout = NULL;
-
- return 0;
-}
-
-static int pppoe_send_initiation(sd_pppoe *ppp) {
- int r;
-
- r = pppoe_send(ppp, PADI_CODE);
- if (r < 0)
- return r;
-
- log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
- ppp->service_name ? : "");
-
- pppoe_arm_timeout(ppp);
-
- return r;
-}
-
-static int pppoe_send_request(sd_pppoe *ppp) {
- int r;
-
- r = pppoe_send(ppp, PADR_CODE);
- if (r < 0)
- return r;
-
- log_debug("PPPoE: sent REQUEST");
-
- ppp->padr_resend_count --;
-
- pppoe_arm_timeout(ppp);
-
- return 0;
-}
-
-static int pppoe_send_terminate(sd_pppoe *ppp) {
- int r;
-
- r = pppoe_send(ppp, PADT_CODE);
- if (r < 0)
- return r;
-
- log_debug("PPPoE: sent TERMINATE");
-
- return 0;
-}
-
-static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
- sd_pppoe *ppp = userdata;
- int r;
-
- assert(ppp);
-
- switch (ppp->state) {
- case PPPOE_STATE_INITIALIZING:
- r = pppoe_send_initiation(ppp);
- if (r < 0)
- log_warning_errno(r, "PPPoE: sending PADI failed: %m");
-
- break;
- case PPPOE_STATE_REQUESTING:
- if (ppp->padr_resend_count <= 0) {
- log_debug("PPPoE: PADR timed out, restarting PADI");
-
- r = pppoe_send_initiation(ppp);
- if (r < 0)
- log_warning_errno(r, "PPPoE: sending PADI failed: %m");
-
- ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND;
- ppp->state = PPPOE_STATE_INITIALIZING;
- } else {
- r = pppoe_send_request(ppp);
- if (r < 0)
- log_warning_errno(r, "PPPoE: sending PADR failed: %m");
- }
-
- break;
- default:
- assert_not_reached("timeout in invalid state");
- }
-
- return 0;
-}
-
-static int pppoe_tag_parse_binary(struct pppoe_tag *tag, uint8_t **ret, size_t *length) {
- uint8_t *data;
-
- assert(ret);
- assert(length);
-
- data = memdup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
- if (!data)
- return -ENOMEM;
-
- free(*ret);
- *ret = data;
- *length = PPPOE_TAG_LENGTH(tag);
-
- return 0;
-}
-
-static int pppoe_tag_parse_string(struct pppoe_tag *tag, char **ret) {
- char *string;
-
- assert(ret);
-
- string = strndup(tag->tag_data, PPPOE_TAG_LENGTH(tag));
- if (!string)
- return -ENOMEM;
-
- free(*ret);
- *ret = string;
-
- return 0;
-}
-
-static int pppoe_payload_parse(PPPoETags *tags, struct pppoe_hdr *header) {
- struct pppoe_tag *tag;
- int r;
-
- assert(tags);
-
- pppoe_tags_clear(tags);
-
- PPPOE_TAGS_FOREACH(tag, header) {
- switch (PPPOE_TAG_TYPE(tag)) {
- case PTT_SRV_NAME:
- r = pppoe_tag_parse_string(tag, &tags->service_name);
- if (r < 0)
- return r;
-
- break;
- case PTT_AC_NAME:
- r = pppoe_tag_parse_string(tag, &tags->ac_name);
- if (r < 0)
- return r;
-
- break;
- case PTT_HOST_UNIQ:
- r = pppoe_tag_parse_binary(tag, &tags->host_uniq, &tags->host_uniq_len);
- if (r < 0)
- return r;
-
- break;
- case PTT_AC_COOKIE:
- r = pppoe_tag_parse_binary(tag, &tags->cookie, &tags->cookie_len);
- if (r < 0)
- return r;
-
- break;
- case PTT_SRV_ERR:
- case PTT_SYS_ERR:
- case PTT_GEN_ERR:
- {
- _cleanup_free_ char *error = NULL;
-
- /* TODO: do something more sensible with the error messages */
- r = pppoe_tag_parse_string(tag, &error);
- if (r < 0)
- return r;
-
- if (strlen(error) > 0 && utf8_is_valid(error))
- log_debug("PPPoE: error - '%s'", error);
- else
- log_debug("PPPoE: error");
-
- break;
- }
- default:
- log_debug("PPPoE: ignoring unknown PPPoE tag type: 0x%.2x", PPPOE_TAG_TYPE(tag));
- }
- }
-
- return 0;
-}
-
-static int pppoe_open_pppoe_socket(sd_pppoe *ppp) {
- int s;
-
- assert(ppp);
- assert(ppp->pppoe_fd == -1);
-
- s = socket(AF_PPPOX, SOCK_STREAM, 0);
- if (s < 0)
- return -errno;
-
- ppp->pppoe_fd = s;
-
- return 0;
-}
-
-static int pppoe_connect_pppoe_socket(sd_pppoe *ppp) {
- union sockaddr_union_pppox link = {
- .pppox = {
- .sa_family = AF_PPPOX,
- .sa_protocol = PX_PROTO_OE,
- },
- };
- int r, channel;
-
- assert(ppp);
- assert(ppp->pppoe_fd != -1);
- assert(ppp->session_id);
- assert(ppp->ifname);
-
- link.pppox.sa_addr.pppoe.sid = ppp->session_id;
- memcpy(link.pppox.sa_addr.pppoe.dev, ppp->ifname, strlen(ppp->ifname));
- memcpy(link.pppox.sa_addr.pppoe.remote, &ppp->peer_mac, ETH_ALEN);
-
- r = connect(ppp->pppoe_fd, &link.sa, sizeof(link.pppox));
- if (r < 0)
- return r;
-
- r = ioctl(ppp->pppoe_fd, PPPIOCGCHAN, &channel);
- if (r < 0)
- return -errno;
-
- ppp->channel = channel;
-
- return 0;
-}
-
-static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct ether_addr *mac) {
- int r;
-
- assert(packet);
-
- if (packet->ver != 0x1 || packet->type != 0x1)
- return 0;
-
- r = pppoe_payload_parse(&ppp->tags, packet);
- if (r < 0)
- return 0;
-
- switch (ppp->state) {
- case PPPOE_STATE_INITIALIZING:
- if (packet->code != PADO_CODE)
- return 0;
-
- if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
- memcmp(ppp->tags.host_uniq, &ppp->host_uniq, sizeof(ppp->host_uniq)) != 0)
- return 0;
-
- log_debug("PPPoE: got OFFER (Peer: "
- "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx; "
- "Service-Name: '%s'; AC-Name: '%s')",
- mac->ether_addr_octet[0],
- mac->ether_addr_octet[1],
- mac->ether_addr_octet[2],
- mac->ether_addr_octet[3],
- mac->ether_addr_octet[4],
- mac->ether_addr_octet[5],
- ppp->tags.service_name ? : "",
- ppp->tags.ac_name ? : "");
-
- memcpy(&ppp->peer_mac, mac, ETH_ALEN);
-
- r = pppoe_open_pppoe_socket(ppp);
- if (r < 0) {
- log_warning("PPPoE: could not open socket");
- return r;
- }
-
- r = pppoe_send_request(ppp);
- if (r < 0)
- return 0;
-
- ppp->state = PPPOE_STATE_REQUESTING;
-
- break;
- case PPPOE_STATE_REQUESTING:
- if (packet->code != PADS_CODE)
- return 0;
-
- if (ppp->tags.host_uniq_len != sizeof(ppp->host_uniq) ||
- memcmp(ppp->tags.host_uniq, &ppp->host_uniq,
- sizeof(ppp->host_uniq)) != 0)
- return 0;
-
- if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
- return 0;
-
- ppp->session_id = packet->sid;
-
- log_debug("PPPoE: got CONFIRMATION (Session ID: %"PRIu16")",
- be16toh(ppp->session_id));
-
- r = pppoe_connect_pppoe_socket(ppp);
- if (r < 0) {
- log_warning("PPPoE: could not connect socket");
- return r;
- }
-
- ppp->state = PPPOE_STATE_RUNNING;
-
- ppp->timeout = sd_event_source_unref(ppp->timeout);
- assert(ppp->cb);
- ppp->cb(ppp, PPPOE_EVENT_RUNNING, ppp->userdata);
-
- break;
- case PPPOE_STATE_RUNNING:
- if (packet->code != PADT_CODE)
- return 0;
-
- if (memcmp(&ppp->peer_mac, mac, ETH_ALEN) != 0)
- return 0;
-
- if (ppp->session_id != packet->sid)
- return 0;
-
- log_debug("PPPoE: got TERMINATE");
-
- ppp->state = PPPOE_STATE_STOPPED;
-
- assert(ppp->cb);
- ppp->cb(ppp, PPPOE_EVENT_STOPPED, ppp->userdata);
-
- break;
- case PPPOE_STATE_STOPPED:
- break;
- default:
- assert_not_reached("PPPoE: invalid state when receiving message");
- }
-
- return 0;
-}
-
-static int pppoe_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- sd_pppoe *ppp = userdata;
- _cleanup_free_ struct pppoe_hdr *packet = NULL;
- union sockaddr_union link = {};
- socklen_t addrlen = sizeof(link);
- int buflen = 0, len, r;
-
- assert(ppp);
- assert(fd != -1);
-
- r = ioctl(fd, FIONREAD, &buflen);
- if (r < 0)
- return r;
-
- if (buflen < 0)
- /* this can't be right */
- return -EIO;
-
- packet = malloc0(buflen);
- if (!packet)
- return -ENOMEM;
-
- len = recvfrom(fd, packet, buflen, 0, &link.sa, &addrlen);
- if (len < 0) {
- log_warning_errno(r, "PPPoE: could not receive message from raw socket: %m");
- return 0;
- } else if ((size_t)len < sizeof(struct pppoe_hdr))
- return 0;
- else if ((size_t)len != sizeof(struct pppoe_hdr) + PPPOE_PACKET_LENGTH(packet))
- return 0;
-
- if (link.ll.sll_halen != ETH_ALEN)
- /* not ethernet? */
- return 0;
-
- r = pppoe_handle_message(ppp, packet, (struct ether_addr*)&link.ll.sll_addr);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-int sd_pppoe_start(sd_pppoe *ppp) {
- union sockaddr_union link = {
- .ll = {
- .sll_family = AF_PACKET,
- .sll_protocol = htons(ETH_P_PPP_DISC),
- },
- };
- _cleanup_close_ int s = -1;
- _cleanup_event_source_unref_ sd_event_source *io = NULL;
- int r;
-
- assert_return(ppp, -EINVAL);
- assert_return(ppp->fd == -1, -EBUSY);
- assert_return(!ppp->io, -EBUSY);
- assert_return(ppp->ifindex > 0, -EUNATCH);
- assert_return(ppp->ifname, -EUNATCH);
- assert_return(ppp->event, -EUNATCH);
- assert_return(ppp->cb, -EUNATCH);
-
- s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
- if (s < 0)
- return -errno;
-
- link.ll.sll_ifindex = ppp->ifindex;
-
- r = bind(s, &link.sa, sizeof(link.ll));
- if (r < 0)
- return r;
-
- r = sd_event_add_io(ppp->event, &io,
- s, EPOLLIN, pppoe_receive_message,
- ppp);
- if (r < 0)
- return r;
-
- r = sd_event_source_set_priority(io, ppp->event_priority);
- if (r < 0)
- return r;
-
- ppp->fd = s;
- s = -1;
- ppp->io = io;
- io = NULL;
-
- r = pppoe_send_initiation(ppp);
- if (r < 0)
- return r;
-
- ppp->state = PPPOE_STATE_INITIALIZING;
-
- return 0;
-}
-
-int sd_pppoe_stop(sd_pppoe *ppp) {
- assert_return(ppp, -EINVAL);
-
- if (ppp->state == PPPOE_STATE_RUNNING)
- pppoe_send_terminate(ppp);
-
- ppp->io = sd_event_source_unref(ppp->io);
- ppp->timeout = sd_event_source_unref(ppp->timeout);
- ppp->fd = asynchronous_close(ppp->fd);
- ppp->pppoe_fd = asynchronous_close(ppp->pppoe_fd);
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
deleted file mode 100644
index d341210887..0000000000
--- a/src/libsystemd-network/test-dhcp-client.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-#include <stdio.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "util.h"
-#include "sd-event.h"
-#include "event-util.h"
-
-#include "dhcp-identifier.h"
-#include "dhcp-protocol.h"
-#include "dhcp-internal.h"
-#include "sd-dhcp-client.h"
-
-static uint8_t mac_addr[] = {'A', 'B', 'C', '1', '2', '3'};
-
-typedef int (*test_callback_recv_t)(size_t size, DHCPMessage *dhcp);
-
-static bool verbose = true;
-static int test_fd[2];
-static test_callback_recv_t callback_recv;
-static be32_t xid;
-static sd_event_source *test_hangcheck;
-
-static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec,
- void *userdata)
-{
- assert_not_reached("Test case should have completed in 2 seconds");
-
- return 0;
-}
-
-static void test_request_basic(sd_event *e)
-{
- int r;
-
- sd_dhcp_client *client;
-
- 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_request_option(NULL, 0) == -EINVAL);
- assert_se(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
- assert_se(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
-
- assert_se(sd_dhcp_client_set_index(client, 15) == 0);
- assert_se(sd_dhcp_client_set_index(client, -42) == -EINVAL);
- assert_se(sd_dhcp_client_set_index(client, -1) == -EINVAL);
- assert_se(sd_dhcp_client_set_index(client, 0) == -EINVAL);
- assert_se(sd_dhcp_client_set_index(client, 1) == 0);
-
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_SUBNET_MASK) == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_ROUTER) == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_HOST_NAME) == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_DOMAIN_NAME_SERVER)
- == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_NTP_SERVER) == -EEXIST);
-
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_PAD) == -EINVAL);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_END) == -EINVAL);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_OVERLOAD) == -EINVAL);
- assert_se(sd_dhcp_client_set_request_option(client,
- DHCP_OPTION_PARAMETER_REQUEST_LIST)
- == -EINVAL);
-
- assert_se(sd_dhcp_client_set_request_option(client, 33) == 0);
- assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
- assert_se(sd_dhcp_client_set_request_option(client, 44) == 0);
- assert_se(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
-
- sd_dhcp_client_unref(client);
-}
-
-static void test_checksum(void)
-{
- uint8_t buf[20] = {
- 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
- 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff
- };
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
-}
-
-static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
- void *user_data)
-{
- switch(code) {
- case DHCP_OPTION_CLIENT_IDENTIFIER:
- {
- uint32_t iaid;
- struct duid duid;
- size_t duid_len;
-
- assert_se(dhcp_identifier_set_duid_en(&duid, &duid_len) >= 0);
- assert_se(dhcp_identifier_set_iaid(42, mac_addr, ETH_ALEN, &iaid) >= 0);
-
- assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
- assert_se(len == 19);
- assert_se(option[0] == 0xff);
-
- assert_se(memcmp(&option[1], &iaid, sizeof(iaid)) == 0);
- assert_se(memcmp(&option[5], &duid, duid_len) == 0);
- break;
- }
-
- default:
- break;
- }
-
- return 0;
-}
-
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
- const void *packet, size_t len)
-{
- size_t size;
- _cleanup_free_ DHCPPacket *discover;
- uint16_t ip_check, udp_check;
-
- assert_se(s >= 0);
- assert_se(packet);
-
- size = sizeof(DHCPPacket);
- assert_se(len > size);
-
- discover = memdup(packet, len);
-
- assert_se(discover->ip.ttl == IPDEFTTL);
- assert_se(discover->ip.protocol == IPPROTO_UDP);
- assert_se(discover->ip.saddr == INADDR_ANY);
- assert_se(discover->ip.daddr == INADDR_BROADCAST);
- assert_se(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
- assert_se(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
-
- ip_check = discover->ip.check;
-
- discover->ip.ttl = 0;
- discover->ip.check = discover->udp.len;
-
- udp_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip.ttl, len - 8);
- assert_se(udp_check == 0xffff);
-
- discover->ip.ttl = IPDEFTTL;
- discover->ip.check = ip_check;
-
- ip_check = ~dhcp_packet_checksum((uint8_t*)&discover->ip, sizeof(discover->ip));
- assert_se(ip_check == 0xffff);
-
- assert_se(discover->dhcp.xid);
- assert_se(memcmp(discover->dhcp.chaddr, &mac_addr, ETH_ALEN) == 0);
-
- size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
-
- assert_se(callback_recv);
- callback_recv(size, &discover->dhcp);
-
- return 575;
-}
-
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
- uint32_t id, const uint8_t *addr,
- size_t addr_len, uint16_t arp_type)
-{
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
- return -errno;
-
- return test_fd[0];
-}
-
-int dhcp_network_bind_udp_socket(be32_t address, uint16_t port)
-{
- int fd;
-
- fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
- if (fd < 0)
- return -errno;
-
- return fd;
-}
-
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
- const void *packet, size_t len)
-{
- return 0;
-}
-
-static int test_discover_message_verify(size_t size, struct DHCPMessage *dhcp)
-{
- int res;
-
- res = dhcp_option_parse(dhcp, size, check_options, NULL);
- assert_se(res == DHCP_DISCOVER);
-
- if (verbose)
- printf(" recv DHCP Discover 0x%08x\n", be32toh(dhcp->xid));
-
- return 0;
-}
-
-static void test_discover_message(sd_event *e)
-{
- 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, ETH_ALEN, ARPHRD_ETHER) >= 0);
-
- assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
-
- callback_recv = test_discover_message_verify;
-
- res = sd_dhcp_client_start(client);
-
- assert_se(res == 0 || res == -EINPROGRESS);
-
- sd_event_run(e, (uint64_t) -1);
-
- sd_dhcp_client_stop(client);
- sd_dhcp_client_unref(client);
-
- test_fd[1] = safe_close(test_fd[1]);
-
- callback_recv = NULL;
-}
-
-static uint8_t test_addr_acq_offer[] = {
- 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
- 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
- 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
- 0x6f, 0x95, 0x2f, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
- 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x02, 0x36,
- 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
- 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
- 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
- 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
- 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static uint8_t test_addr_acq_ack[] = {
- 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x11, 0xb3, 0x84, 0xc0, 0xa8, 0x02, 0x01,
- 0xc0, 0xa8, 0x02, 0xbf, 0x00, 0x43, 0x00, 0x44,
- 0x01, 0x34, 0x00, 0x00, 0x02, 0x01, 0x06, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, 0x02, 0xbf,
- 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36,
- 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x33, 0x04, 0x00,
- 0x00, 0x02, 0x58, 0x01, 0x04, 0xff, 0xff, 0xff,
- 0x00, 0x2a, 0x04, 0xc0, 0xa8, 0x02, 0x01, 0x0f,
- 0x09, 0x6c, 0x61, 0x62, 0x2e, 0x69, 0x6e, 0x74,
- 0x72, 0x61, 0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
- void *userdata) {
- sd_event *e = userdata;
- sd_dhcp_lease *lease;
- struct in_addr addr;
-
- assert_se(client);
- assert_se(event == DHCP_EVENT_IP_ACQUIRE);
-
- assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
- assert_se(lease);
-
- assert_se(sd_dhcp_lease_get_address(lease, &addr) >= 0);
- assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[44],
- sizeof(addr.s_addr)) == 0);
-
- assert_se(sd_dhcp_lease_get_netmask(lease, &addr) >= 0);
- assert_se(memcmp(&addr.s_addr, &test_addr_acq_ack[285],
- sizeof(addr.s_addr)) == 0);
-
- 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_dhcp_lease_unref(lease);
- sd_event_exit(e, 0);
-}
-
-static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
- uint16_t udp_check = 0;
- uint8_t *msg_bytes = (uint8_t *)request;
- int res;
-
- res = dhcp_option_parse(request, size, check_options, NULL);
- assert_se(res == DHCP_REQUEST);
- assert_se(xid == request->xid);
-
- assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
-
- 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_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;
- uint8_t *msg_bytes = (uint8_t *)discover;
- int res;
-
- res = dhcp_option_parse(discover, size, check_options, NULL);
- assert_se(res == DHCP_DISCOVER);
-
- assert_se(msg_bytes[size - 1] == DHCP_OPTION_END);
-
- 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_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(" sent DHCP Offer\n");
-
- return 0;
-}
-
-static void test_addr_acq(sd_event *e) {
- usec_t time_now = now(clock_boottime_or_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, ETH_ALEN, ARPHRD_ETHER) >= 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_time(e, &test_hangcheck,
- clock_boottime_or_monotonic(),
- time_now + 2 * USEC_PER_SEC, 0,
- test_dhcp_hangcheck, NULL) >= 0);
-
- res = sd_dhcp_client_start(client);
- assert_se(res == 0 || res == -EINPROGRESS);
-
- assert_se(sd_event_loop(e) >= 0);
-
- test_hangcheck = sd_event_source_unref(test_hangcheck);
-
- assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
- assert_se(sd_dhcp_client_stop(client) >= 0);
- sd_dhcp_client_unref(client);
-
- test_fd[1] = safe_close(test_fd[1]);
-
- callback_recv = NULL;
- xid = 0;
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_event_unref_ sd_event *e;
-
- log_set_max_level(LOG_DEBUG);
- log_parse_environment();
- log_open();
-
- assert_se(sd_event_new(&e) >= 0);
-
- test_request_basic(e);
- test_checksum();
-
- test_discover_message(e);
- test_addr_acq(e);
-
-#ifdef VALGRIND
- /* Make sure the async_close thread has finished.
- * valgrind would report some of the phread_* structures
- * as not cleaned up properly. */
- sleep(1);
-#endif
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-dhcp-option.c b/src/libsystemd-network/test-dhcp-option.c
deleted file mode 100644
index a63a4ea738..0000000000
--- a/src/libsystemd-network/test-dhcp-option.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <string.h>
-
-#include "util.h"
-#include "macro.h"
-
-#include "dhcp-protocol.h"
-#include "dhcp-internal.h"
-
-struct option_desc {
- uint8_t sname[64];
- int snamelen;
- uint8_t file[128];
- int filelen;
- uint8_t options[128];
- int len;
- bool success;
- int filepos;
- int snamepos;
- int pos;
-};
-
-static bool verbose = false;
-
-static struct option_desc option_tests[] = {
- { {}, 0, {}, 0, { 42, 5, 65, 66, 67, 68, 69 }, 7, false, },
- { {}, 0, {}, 0, { 42, 5, 65, 66, 67, 68, 69, 0, 0,
- DHCP_OPTION_MESSAGE_TYPE, 1, DHCP_ACK }, 12, true, },
- { {}, 0, {}, 0, { 8, 255, 70, 71, 72 }, 5, false, },
- { {}, 0, {}, 0, { 0x35, 0x01, 0x05, 0x36, 0x04, 0x01, 0x00, 0xa8,
- 0xc0, 0x33, 0x04, 0x00, 0x01, 0x51, 0x80, 0x01,
- 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, 0x04, 0xc0,
- 0xa8, 0x00, 0x01, 0x06, 0x04, 0xc0, 0xa8, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, },
- 40, true, },
- { {}, 0, {}, 0, { DHCP_OPTION_MESSAGE_TYPE, 1, DHCP_OFFER,
- 42, 3, 0, 0, 0 }, 8, true, },
- { {}, 0, {}, 0, { 42, 2, 1, 2, 44 }, 5, false, },
-
- { {}, 0,
- { 222, 3, 1, 2, 3, DHCP_OPTION_MESSAGE_TYPE, 1, DHCP_NAK }, 8,
- { DHCP_OPTION_OVERLOAD, 1, DHCP_OVERLOAD_FILE }, 3, true, },
-
- { { 1, 4, 1, 2, 3, 4, DHCP_OPTION_MESSAGE_TYPE, 1, DHCP_ACK }, 9,
- { 222, 3, 1, 2, 3 }, 5,
- { DHCP_OPTION_OVERLOAD, 1,
- DHCP_OVERLOAD_FILE|DHCP_OVERLOAD_SNAME }, 3, true, },
-};
-
-static const char *dhcp_type(int type) {
- switch(type) {
- case DHCP_DISCOVER:
- return "DHCPDISCOVER";
- case DHCP_OFFER:
- return "DHCPOFFER";
- case DHCP_REQUEST:
- return "DHCPREQUEST";
- case DHCP_DECLINE:
- return "DHCPDECLINE";
- case DHCP_ACK:
- return "DHCPACK";
- case DHCP_NAK:
- return "DHCPNAK";
- case DHCP_RELEASE:
- return "DHCPRELEASE";
- default:
- return "unknown";
- }
-}
-
-static void test_invalid_buffer_length(void) {
- DHCPMessage message;
-
- assert_se(dhcp_option_parse(&message, 0, NULL, NULL) == -EINVAL);
- assert_se(dhcp_option_parse(&message, sizeof(DHCPMessage) - 1, NULL, NULL)
- == -EINVAL);
-}
-
-static void test_message_init(void) {
- _cleanup_free_ DHCPMessage *message = NULL;
- size_t optlen = 4, optoffset;
- size_t len = sizeof(DHCPMessage) + optlen;
- uint8_t *magic;
-
- message = malloc0(len);
-
- assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678,
- DHCP_DISCOVER, ARPHRD_ETHER, optlen, &optoffset) >= 0);
-
- assert_se(message->xid == htobe32(0x12345678));
- assert_se(message->op == BOOTREQUEST);
-
- magic = (uint8_t*)&message->magic;
-
- assert_se(magic[0] == 99);
- assert_se(magic[1] == 130);
- assert_se(magic[2] == 83);
- assert_se(magic[3] == 99);
-
- assert_se(dhcp_option_parse(message, len, NULL, NULL) >= 0);
-}
-
-static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
- uint8_t *file, uint8_t filelen,
- uint8_t *sname, uint8_t snamelen) {
- DHCPMessage *message;
- size_t len = sizeof(DHCPMessage) + optlen;
-
- message = malloc0(len);
- assert_se(message);
-
- if (options && optlen)
- memcpy(&message->options, options, optlen);
-
- if (file && filelen <= 128)
- memcpy(&message->file, file, filelen);
-
- if (sname && snamelen <= 64)
- memcpy(&message->sname, sname, snamelen);
-
- return message;
-}
-
-static void test_ignore_opts(uint8_t *descoption, int *descpos, int *desclen) {
- assert(*descpos >= 0);
-
- while (*descpos < *desclen) {
- switch(descoption[*descpos]) {
- case DHCP_OPTION_PAD:
- *descpos += 1;
- break;
-
- case DHCP_OPTION_MESSAGE_TYPE:
- case DHCP_OPTION_OVERLOAD:
- *descpos += 3;
- break;
-
- default:
- return;
- }
- }
-}
-
-static int test_options_cb(uint8_t code, uint8_t len, const uint8_t *option, void *user_data) {
- struct option_desc *desc = user_data;
- uint8_t *descoption = NULL;
- int *desclen = NULL, *descpos = NULL;
- uint8_t optcode = 0;
- uint8_t optlen = 0;
- uint8_t i;
-
- assert_se((!desc && !code && !len) || desc);
-
- if (!desc)
- return -EINVAL;
-
- assert_se(code != DHCP_OPTION_PAD);
- assert_se(code != DHCP_OPTION_END);
- assert_se(code != DHCP_OPTION_MESSAGE_TYPE);
- assert_se(code != DHCP_OPTION_OVERLOAD);
-
- while (desc->pos >= 0 || desc->filepos >= 0 || desc->snamepos >= 0) {
-
- if (desc->pos >= 0) {
- descoption = &desc->options[0];
- desclen = &desc->len;
- descpos = &desc->pos;
- } else if (desc->filepos >= 0) {
- descoption = &desc->file[0];
- desclen = &desc->filelen;
- descpos = &desc->filepos;
- } else if (desc->snamepos >= 0) {
- descoption = &desc->sname[0];
- desclen = &desc->snamelen;
- descpos = &desc->snamepos;
- }
-
- assert_se(descoption && desclen && descpos);
-
- if (*desclen)
- test_ignore_opts(descoption, descpos, desclen);
-
- if (*descpos < *desclen)
- break;
-
- if (*descpos == *desclen)
- *descpos = -1;
- }
-
- assert_se(descpos);
- assert_se(*descpos != -1);
-
- optcode = descoption[*descpos];
- optlen = descoption[*descpos + 1];
-
- if (verbose)
- printf("DHCP code %2d(%2d) len %2d(%2d) ", code, optcode,
- len, optlen);
-
- assert_se(code == optcode);
- assert_se(len == optlen);
-
- for (i = 0; i < len; i++) {
-
- if (verbose)
- printf("0x%02x(0x%02x) ", option[i],
- descoption[*descpos + 2 + i]);
-
- assert_se(option[i] == descoption[*descpos + 2 + i]);
- }
-
- if (verbose)
- printf("\n");
-
- *descpos += optlen + 2;
-
- test_ignore_opts(descoption, descpos, desclen);
-
- if (desc->pos != -1 && desc->pos == desc->len)
- desc->pos = -1;
-
- if (desc->filepos != -1 && desc->filepos == desc->filelen)
- desc->filepos = -1;
-
- if (desc->snamepos != -1 && desc->snamepos == desc->snamelen)
- desc->snamepos = -1;
-
- return 0;
-}
-
-static void test_options(struct option_desc *desc) {
- uint8_t *options = NULL;
- uint8_t *file = NULL;
- uint8_t *sname = NULL;
- int optlen = 0;
- int filelen = 0;
- int snamelen = 0;
- int buflen = 0;
- _cleanup_free_ DHCPMessage *message = NULL;
- int res;
-
- if (desc) {
- file = &desc->file[0];
- filelen = desc->filelen;
- if (!filelen)
- desc->filepos = -1;
-
- sname = &desc->sname[0];
- snamelen = desc->snamelen;
- if (!snamelen)
- desc->snamepos = -1;
-
- options = &desc->options[0];
- optlen = desc->len;
- desc->pos = 0;
- }
- message = create_message(options, optlen, file, filelen,
- sname, snamelen);
-
- buflen = sizeof(DHCPMessage) + optlen;
-
- if (!desc) {
- assert_se((res = dhcp_option_parse(message, buflen,
- test_options_cb,
- NULL)) == -ENOMSG);
- } else if (desc->success) {
- assert_se((res = dhcp_option_parse(message, buflen,
- test_options_cb,
- desc)) >= 0);
- assert_se(desc->pos == -1 && desc->filepos == -1 &&
- desc->snamepos == -1);
- } else
- assert_se((res = dhcp_option_parse(message, buflen,
- test_options_cb,
- desc)) < 0);
-
- if (verbose)
- printf("DHCP type %s\n", dhcp_type(res));
-}
-
-static uint8_t options[64] = {
- 'A', 'B', 'C', 'D',
- 160, 2, 0x11, 0x12,
- 0,
- 31, 8, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
- 0,
- 55, 3, 0x51, 0x52, 0x53,
- 17, 7, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 255
-};
-
-static void test_option_set(void) {
- _cleanup_free_ DHCPMessage *result = NULL;
- size_t offset = 0, len, pos;
- unsigned i;
-
- result = malloc0(sizeof(DHCPMessage) + 11);
- assert_se(result);
-
- result->options[0] = 'A';
- result->options[1] = 'B';
- result->options[2] = 'C';
- result->options[3] = 'D';
-
- assert_se(dhcp_option_append(result, 0, &offset, 0, DHCP_OPTION_PAD,
- 0, NULL) == -ENOBUFS);
- assert_se(offset == 0);
-
- offset = 4;
- assert_se(dhcp_option_append(result, 5, &offset, 0, DHCP_OPTION_PAD,
- 0, NULL) == -ENOBUFS);
- assert_se(offset == 4);
- assert_se(dhcp_option_append(result, 6, &offset, 0, DHCP_OPTION_PAD,
- 0, NULL) >= 0);
- assert_se(offset == 5);
-
- offset = pos = 4;
- len = 11;
- while (pos < len && options[pos] != DHCP_OPTION_END) {
- assert_se(dhcp_option_append(result, len, &offset, DHCP_OVERLOAD_SNAME,
- options[pos],
- options[pos + 1],
- &options[pos + 2]) >= 0);
-
- if (options[pos] == DHCP_OPTION_PAD)
- pos++;
- else
- pos += 2 + options[pos + 1];
-
- if (pos < len)
- assert_se(offset == pos);
- }
-
- for (i = 0; i < 9; i++) {
- if (verbose)
- printf("%2u: 0x%02x(0x%02x) (options)\n", i, result->options[i],
- options[i]);
- assert_se(result->options[i] == options[i]);
- }
-
- if (verbose)
- printf("%2d: 0x%02x(0x%02x) (options)\n", 9, result->options[9],
- DHCP_OPTION_END);
-
- assert_se(result->options[9] == DHCP_OPTION_END);
-
- if (verbose)
- printf("%2d: 0x%02x(0x%02x) (options)\n", 10, result->options[10],
- DHCP_OPTION_PAD);
-
- assert_se(result->options[10] == DHCP_OPTION_PAD);
-
- for (i = 0; i < pos - 8; i++) {
- if (verbose)
- printf("%2u: 0x%02x(0x%02x) (sname)\n", i, result->sname[i],
- options[i + 9]);
- assert_se(result->sname[i] == options[i + 9]);
- }
-
- if (verbose)
- printf ("\n");
-}
-
-int main(int argc, char *argv[]) {
- unsigned i;
-
- test_invalid_buffer_length();
- test_message_init();
-
- test_options(NULL);
-
- for (i = 0; i < ELEMENTSOF(option_tests); i++)
- test_options(&option_tests[i]);
-
- test_option_set();
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
deleted file mode 100644
index 9f60ab761e..0000000000
--- a/src/libsystemd-network/test-dhcp-server.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2013 Intel Corporation. All rights reserved.
- Copyright (C) 2014 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <errno.h>
-
-#include "sd-event.h"
-#include "event-util.h"
-
-#include "sd-dhcp-server.h"
-#include "dhcp-server-internal.h"
-
-static int test_basic(sd_event *event) {
- _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
- struct in_addr address_lo = {
- .s_addr = htonl(INADDR_LOOPBACK),
- };
- struct in_addr address_any = {
- .s_addr = htonl(INADDR_ANY),
- };
- int r;
-
- /* attach to loopback interface */
- assert_se(sd_dhcp_server_new(&server, 1) >= 0);
- assert_se(server);
-
- assert_se(sd_dhcp_server_attach_event(server, event, 0) >= 0);
- assert_se(sd_dhcp_server_attach_event(server, event, 0) == -EBUSY);
- assert_se(sd_dhcp_server_get_event(server) == event);
- assert_se(sd_dhcp_server_detach_event(server) >= 0);
- assert_se(!sd_dhcp_server_get_event(server));
- assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
- assert_se(sd_dhcp_server_attach_event(server, NULL, 0) == -EBUSY);
-
- assert_se(sd_dhcp_server_ref(server) == server);
- assert_se(!sd_dhcp_server_unref(server));
-
- assert_se(sd_dhcp_server_start(server) == -EUNATCH);
- assert_se(sd_dhcp_server_set_address(server, &address_any, 28) == -EINVAL);
- assert_se(sd_dhcp_server_set_address(server, &address_lo, 38) == -ERANGE);
- assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0);
- assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) == -EBUSY);
-
- assert_se(sd_dhcp_server_set_lease_pool(server, &address_any, 1) == -EINVAL);
- assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 0) == -EINVAL);
- assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) >= 0);
- assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) == -EBUSY);
-
- r = sd_dhcp_server_start(server);
-
- if (r == -EPERM)
- return EXIT_TEST_SKIP;
- assert_se(r >= 0);
-
- assert_se(sd_dhcp_server_start(server) == -EBUSY);
- assert_se(sd_dhcp_server_stop(server) >= 0);
- assert_se(sd_dhcp_server_stop(server) >= 0);
- assert_se(sd_dhcp_server_start(server) >= 0);
-
- return 0;
-}
-
-static void test_message_handler(void) {
- _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
- struct {
- DHCPMessage message;
- struct {
- uint8_t code;
- uint8_t length;
- uint8_t type;
- } _packed_ option_type;
- struct {
- uint8_t code;
- uint8_t length;
- be32_t address;
- } _packed_ option_requested_ip;
- struct {
- uint8_t code;
- uint8_t length;
- be32_t address;
- } _packed_ option_server_id;
- struct {
- uint8_t code;
- uint8_t length;
- uint8_t id[7];
- } _packed_ option_client_id;
- uint8_t end;
- } _packed_ test = {
- .message.op = BOOTREQUEST,
- .message.htype = ARPHRD_ETHER,
- .message.hlen = ETHER_ADDR_LEN,
- .message.xid = htobe32(0x12345678),
- .message.chaddr = { 'A', 'B', 'C', 'D', 'E', 'F' },
- .option_type.code = DHCP_OPTION_MESSAGE_TYPE,
- .option_type.length = 1,
- .option_type.type = DHCP_DISCOVER,
- .end = DHCP_OPTION_END,
- };
- struct in_addr address_lo = {
- .s_addr = htonl(INADDR_LOOPBACK),
- };
-
- assert_se(sd_dhcp_server_new(&server, 1) >= 0);
- assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0);
- assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
- assert_se(sd_dhcp_server_start(server) >= 0);
-
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 10) >= 0);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.end = 0;
- /* TODO, shouldn't this fail? */
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
- test.end = DHCP_OPTION_END;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.option_type.code = 0;
- test.option_type.length = 0;
- test.option_type.type = 0;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.option_type.code = DHCP_OPTION_MESSAGE_TYPE;
- test.option_type.length = 1;
- test.option_type.type = DHCP_DISCOVER;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.message.op = 0;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.message.op = BOOTREQUEST;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.message.htype = 0;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.message.htype = ARPHRD_ETHER;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.message.hlen = 0;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.message.hlen = ETHER_ADDR_LEN;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
-
- test.option_type.type = DHCP_REQUEST;
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.option_requested_ip.code = DHCP_OPTION_REQUESTED_IP_ADDRESS;
- test.option_requested_ip.length = 4;
- test.option_requested_ip.address = htobe32(0x12345678);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_NAK);
- test.option_server_id.code = DHCP_OPTION_SERVER_IDENTIFIER;
- test.option_server_id.length = 4;
- test.option_server_id.address = htobe32(INADDR_LOOPBACK);
- test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
-
- test.option_server_id.address = htobe32(0x12345678);
- test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.option_server_id.address = htobe32(INADDR_LOOPBACK);
- test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
- test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
-
- test.option_client_id.code = DHCP_OPTION_CLIENT_IDENTIFIER;
- test.option_client_id.length = 7;
- test.option_client_id.id[0] = 0x01;
- test.option_client_id.id[1] = 'A';
- test.option_client_id.id[2] = 'B';
- test.option_client_id.id[3] = 'C';
- test.option_client_id.id[4] = 'D';
- test.option_client_id.id[5] = 'E';
- test.option_client_id.id[6] = 'F';
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
-
- test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
- assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
-}
-
-static void test_client_id_hash(void) {
- DHCPClientId a = {
- .length = 4,
- }, b = {
- .length = 4,
- };
- uint8_t hash_key[HASH_KEY_SIZE] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
- };
-
- a.data = (uint8_t*)strdup("abcd");
- b.data = (uint8_t*)strdup("abcd");
-
- assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
- a.length = 3;
- assert_se(client_id_compare_func(&a, &b) != 0);
- a.length = 4;
- assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
-
- b.length = 3;
- assert_se(client_id_compare_func(&a, &b) != 0);
- b.length = 4;
- assert_se(client_id_compare_func(&a, &b) == 0);
- assert_se(client_id_hash_func(&a, hash_key) == client_id_hash_func(&b, hash_key));
-
- free(b.data);
- b.data = (uint8_t*)strdup("abce");
- assert_se(client_id_compare_func(&a, &b) != 0);
-
- free(a.data);
- free(b.data);
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_event_unref_ sd_event *e;
- int r;
-
- log_set_max_level(LOG_DEBUG);
- log_parse_environment();
- log_open();
-
- assert_se(sd_event_new(&e) >= 0);
-
- r = test_basic(e);
- if (r != 0)
- return r;
-
- test_message_handler();
- test_client_id_hash();
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
deleted file mode 100644
index 9386f31ce4..0000000000
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <net/ethernet.h>
-
-#include "socket-util.h"
-#include "macro.h"
-#include "sd-event.h"
-#include "event-util.h"
-#include "virt.h"
-
-#include "sd-dhcp6-client.h"
-#include "dhcp6-protocol.h"
-#include "dhcp6-internal.h"
-#include "dhcp6-lease-internal.h"
-
-static struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
-};
-
-static bool verbose = true;
-
-static sd_event_source *hangcheck;
-static int test_dhcp_fd[2];
-static int test_index = 42;
-static int test_client_message_num;
-static be32_t test_iaid = 0;
-static uint8_t test_duid[14] = { };
-
-static int test_client_basic(sd_event *e) {
- sd_dhcp6_client *client;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(sd_dhcp6_client_new(&client) >= 0);
- assert_se(client);
-
- assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
-
- assert_se(sd_dhcp6_client_set_index(client, 15) == 0);
- assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL);
- assert_se(sd_dhcp6_client_set_index(client, -1) == 0);
- assert_se(sd_dhcp6_client_set_index(client, 42) >= 0);
-
- assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
- sizeof (mac_addr),
- ARPHRD_ETHER) >= 0);
-
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL);
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_NTP_SERVER) == -EEXIST);
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_SNTP_SERVERS) == 0);
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
- assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
-
- assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0);
-
- assert_se(sd_dhcp6_client_detach_event(client) >= 0);
- assert_se(!sd_dhcp6_client_unref(client));
-
- return 0;
-}
-
-static int test_option(sd_event *e) {
- uint8_t packet[] = {
- 'F', 'O', 'O',
- 0x00, DHCP6_OPTION_ORO, 0x00, 0x07,
- 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 0x00, DHCP6_OPTION_VENDOR_CLASS, 0x00, 0x09,
- '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'B', 'A', 'R',
- };
- uint8_t result[] = {
- 'F', 'O', 'O',
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 'B', 'A', 'R',
- };
- uint16_t optcode;
- size_t optlen;
- uint8_t *optval, *buf, *out;
- size_t zero = 0, pos = 3;
- size_t buflen = sizeof(packet), outlen = sizeof(result);
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(buflen == outlen);
-
- assert_se(dhcp6_option_parse(&buf, &zero, &optcode, &optlen,
- &optval) == -ENOMSG);
-
- buflen -= 3;
- buf = &packet[3];
- outlen -= 3;
- out = &result[3];
-
- assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
- &optval) >= 0);
- pos += 4 + optlen;
- assert_se(buf == &packet[pos]);
- assert_se(optcode == DHCP6_OPTION_ORO);
- assert_se(optlen == 7);
- assert_se(buflen + pos == sizeof(packet));
-
- assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
- optval) >= 0);
- assert_se(out == &result[pos]);
- assert_se(*out == 0x00);
-
- assert_se(dhcp6_option_parse(&buf, &buflen, &optcode, &optlen,
- &optval) >= 0);
- pos += 4 + optlen;
- assert_se(buf == &packet[pos]);
- assert_se(optcode == DHCP6_OPTION_VENDOR_CLASS);
- assert_se(optlen == 9);
- assert_se(buflen + pos == sizeof(packet));
-
- assert_se(dhcp6_option_append(&out, &outlen, optcode, optlen,
- optval) >= 0);
- assert_se(out == &result[pos]);
- assert_se(*out == 'B');
-
- assert_se(memcmp(packet, result, sizeof(packet)) == 0);
-
- return 0;
-}
-
-static uint8_t msg_advertise[198] = {
- 0x02, 0x0f, 0xb4, 0xe5, 0x00, 0x01, 0x00, 0x0e,
- 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b, 0xf3, 0x30,
- 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x03,
- 0x00, 0x5e, 0x0e, 0xcf, 0xa3, 0x7d, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05,
- 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
- 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3, 0x09, 0x3c,
- 0x55, 0xad, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00,
- 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x00,
- 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x28,
- 0x65, 0x73, 0x29, 0x20, 0x72, 0x65, 0x6e, 0x65,
- 0x77, 0x65, 0x64, 0x2e, 0x20, 0x47, 0x72, 0x65,
- 0x65, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66,
- 0x72, 0x6f, 0x6d, 0x20, 0x70, 0x6c, 0x61, 0x6e,
- 0x65, 0x74, 0x20, 0x45, 0x61, 0x72, 0x74, 0x68,
- 0x00, 0x17, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8,
- 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b,
- 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
- 0x72, 0x61, 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20,
- 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x19,
- 0x40, 0x5c, 0x53, 0x78, 0x2b, 0xcb, 0xb3, 0x6d,
- 0x53, 0x00, 0x07, 0x00, 0x01, 0x00
-};
-
-static uint8_t msg_reply[173] = {
- 0x07, 0xf7, 0x4e, 0x57, 0x00, 0x02, 0x00, 0x0e,
- 0x00, 0x01, 0x00, 0x01, 0x19, 0x40, 0x5c, 0x53,
- 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, 0x00, 0x01,
- 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x6b,
- 0xf3, 0x30, 0x3c, 0x97, 0x0e, 0xcf, 0xa3, 0x7d,
- 0x00, 0x03, 0x00, 0x4a, 0x0e, 0xcf, 0xa3, 0x7d,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x78,
- 0x00, 0x05, 0x00, 0x18, 0x20, 0x01, 0x0d, 0xb8,
- 0xde, 0xad, 0xbe, 0xef, 0x78, 0xee, 0x1c, 0xf3,
- 0x09, 0x3c, 0x55, 0xad, 0x00, 0x00, 0x00, 0x96,
- 0x00, 0x00, 0x00, 0xb4, 0x00, 0x0d, 0x00, 0x1e,
- 0x00, 0x00, 0x41, 0x6c, 0x6c, 0x20, 0x61, 0x64,
- 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20,
- 0x77, 0x65, 0x72, 0x65, 0x20, 0x61, 0x73, 0x73,
- 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x00, 0x17,
- 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad,
- 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x18, 0x00, 0x0b, 0x03, 0x6c,
- 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, 0x72, 0x61,
- 0x00, 0x00, 0x1f, 0x00, 0x10, 0x20, 0x01, 0x0d,
- 0xb8, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01
-};
-
-static int test_advertise_option(sd_event *e) {
- _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
- DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
- uint8_t *optval, *opt = msg_advertise + sizeof(DHCP6Message);
- uint16_t optcode;
- size_t optlen, len = sizeof(msg_advertise) - sizeof(DHCP6Message);
- be32_t val;
- uint8_t preference = 255;
- struct in6_addr addr;
- uint32_t lt_pref, lt_valid;
- int r;
- bool opt_clientid = false;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(dhcp6_lease_new(&lease) >= 0);
-
- assert_se(advertise->type == DHCP6_ADVERTISE);
- assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
- 0x0fb4e5);
-
- while ((r = dhcp6_option_parse(&opt, &len, &optcode, &optlen,
- &optval)) >= 0) {
-
- switch(optcode) {
- case DHCP6_OPTION_CLIENTID:
- assert_se(optlen == 14);
-
- opt_clientid = true;
- break;
-
- case DHCP6_OPTION_IA_NA:
- assert_se(optlen == 94);
- assert_se(!memcmp(optval, &msg_advertise[26], optlen));
-
- val = htobe32(0x0ecfa37d);
- assert_se(!memcmp(optval, &val, sizeof(val)));
-
- val = htobe32(80);
- assert_se(!memcmp(optval + 4, &val, sizeof(val)));
-
- val = htobe32(120);
- assert_se(!memcmp(optval + 8, &val, sizeof(val)));
-
- assert_se(dhcp6_option_parse_ia(&optval, &optlen,
- optcode,
- &lease->ia) >= 0);
-
- break;
-
- case DHCP6_OPTION_SERVERID:
- assert_se(optlen == 14);
- assert_se(!memcmp(optval, &msg_advertise[179], optlen));
-
- assert_se(dhcp6_lease_set_serverid(lease, optval,
- optlen) >= 0);
- break;
-
- case DHCP6_OPTION_PREFERENCE:
- assert_se(optlen == 1);
- assert_se(!*optval);
-
- assert_se(dhcp6_lease_set_preference(lease,
- *optval) >= 0);
- break;
-
- case DHCP6_OPTION_ELAPSED_TIME:
- assert_se(optlen == 2);
-
- break;
-
- default:
- break;
- }
- }
-
-
- assert_se(r == -ENOMSG);
-
- assert_se(opt_clientid);
-
- sd_dhcp6_lease_reset_address_iter(lease);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) >= 0);
- assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
- assert_se(lt_pref == 150);
- assert_se(lt_valid == 180);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) == -ENOMSG);
-
- sd_dhcp6_lease_reset_address_iter(lease);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) >= 0);
- assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) == -ENOMSG);
- sd_dhcp6_lease_reset_address_iter(lease);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) >= 0);
- assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) == -ENOMSG);
-
- assert_se(dhcp6_lease_get_serverid(lease, &opt, &len) >= 0);
- assert_se(len == 14);
- assert_se(!memcmp(opt, &msg_advertise[179], len));
-
- assert_se(dhcp6_lease_get_preference(lease, &preference) >= 0);
- assert_se(preference == 0);
-
- return 0;
-}
-
-static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
- assert_not_reached("Test case should have completed in 2 seconds");
-
- return 0;
-}
-
-int detect_vm(const char **id) {
- return 1;
-}
-
-int detect_container(const char **id) {
- return 1;
-}
-
-int detect_virtualization(const char **id) {
- return 1;
-}
-
-static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
- void *userdata) {
- sd_event *e = userdata;
-
- assert_se(e);
- assert_se(event == DHCP6_EVENT_IP_ACQUIRE);
-
- assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EBUSY);
-
- if (verbose)
- printf(" got DHCPv6 event %d\n", event);
-
- sd_event_exit(e, 0);
-}
-
-static int test_client_send_reply(DHCP6Message *request) {
- DHCP6Message reply;
-
- reply.transaction_id = request->transaction_id;
- reply.type = DHCP6_REPLY;
-
- memcpy(msg_reply, &reply.transaction_id, 4);
-
- memcpy(&msg_reply[26], test_duid, sizeof(test_duid));
-
- memcpy(&msg_reply[44], &test_iaid, sizeof(test_iaid));
-
- assert_se(write(test_dhcp_fd[1], msg_reply, sizeof(msg_reply))
- == sizeof(msg_reply));
-
- return 0;
-}
-
-static int test_client_verify_request(DHCP6Message *request, uint8_t *option,
- size_t len) {
- _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
- uint8_t *optval;
- uint16_t optcode;
- size_t optlen;
- bool found_clientid = false, found_iana = false, found_serverid = false,
- found_elapsed_time = false;
- int r;
- struct in6_addr addr;
- be32_t val;
- uint32_t lt_pref, lt_valid;
-
- assert_se(request->type == DHCP6_REQUEST);
-
- assert_se(dhcp6_lease_new(&lease) >= 0);
-
- while ((r = dhcp6_option_parse(&option, &len,
- &optcode, &optlen, &optval)) >= 0) {
- switch(optcode) {
- case DHCP6_OPTION_CLIENTID:
- assert_se(!found_clientid);
- found_clientid = true;
-
- assert_se(!memcmp(optval, &test_duid,
- sizeof(test_duid)));
-
- break;
-
- case DHCP6_OPTION_IA_NA:
- assert_se(!found_iana);
- found_iana = true;
-
-
- assert_se(optlen == 40);
- assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
-
- val = htobe32(80);
- assert_se(!memcmp(optval + 4, &val, sizeof(val)));
-
- val = htobe32(120);
- assert_se(!memcmp(optval + 8, &val, sizeof(val)));
-
- assert_se(!dhcp6_option_parse_ia(&optval, &optlen,
- optcode, &lease->ia));
-
- break;
-
- case DHCP6_OPTION_SERVERID:
- assert_se(!found_serverid);
- found_serverid = true;
-
- assert_se(optlen == 14);
- assert_se(!memcmp(&msg_advertise[179], optval, optlen));
-
- break;
-
- case DHCP6_OPTION_ELAPSED_TIME:
- assert_se(!found_elapsed_time);
- found_elapsed_time = true;
-
- assert_se(optlen == 2);
-
- break;
- }
- }
-
- assert_se(r == -ENOMSG);
- assert_se(found_clientid && found_iana && found_serverid &&
- found_elapsed_time);
-
- sd_dhcp6_lease_reset_address_iter(lease);
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) >= 0);
- assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
- assert_se(lt_pref == 150);
- assert_se(lt_valid == 180);
-
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) == -ENOMSG);
-
- return 0;
-}
-
-static int test_client_send_advertise(DHCP6Message *solicit)
-{
- DHCP6Message advertise;
-
- advertise.transaction_id = solicit->transaction_id;
- advertise.type = DHCP6_ADVERTISE;
-
- memcpy(msg_advertise, &advertise.transaction_id, 4);
-
- memcpy(&msg_advertise[8], test_duid, sizeof(test_duid));
-
- memcpy(&msg_advertise[26], &test_iaid, sizeof(test_iaid));
-
- assert_se(write(test_dhcp_fd[1], msg_advertise, sizeof(msg_advertise))
- == sizeof(msg_advertise));
-
- return 0;
-}
-
-static int test_client_verify_solicit(DHCP6Message *solicit, uint8_t *option,
- size_t len) {
- uint8_t *optval;
- uint16_t optcode;
- size_t optlen;
- bool found_clientid = false, found_iana = false,
- found_elapsed_time = false;
- int r;
-
- assert_se(solicit->type == DHCP6_SOLICIT);
-
- while ((r = dhcp6_option_parse(&option, &len,
- &optcode, &optlen, &optval)) >= 0) {
- switch(optcode) {
- case DHCP6_OPTION_CLIENTID:
- assert_se(!found_clientid);
- found_clientid = true;
-
- assert_se(optlen == sizeof(test_duid));
- memcpy(&test_duid, optval, sizeof(test_duid));
-
- break;
-
- case DHCP6_OPTION_IA_NA:
- assert_se(!found_iana);
- found_iana = true;
-
- assert_se(optlen == 12);
-
- memcpy(&test_iaid, optval, sizeof(test_iaid));
-
- break;
-
- case DHCP6_OPTION_ELAPSED_TIME:
- assert_se(!found_elapsed_time);
- found_elapsed_time = true;
-
- assert_se(optlen == 2);
-
- break;
- }
- }
-
- assert_se(r == -ENOMSG);
- assert_se(found_clientid && found_iana && found_elapsed_time);
-
- return 0;
-}
-
-static void test_client_information_cb(sd_dhcp6_client *client, int event,
- void *userdata) {
- sd_event *e = userdata;
-
- assert_se(e);
- assert_se(event == DHCP6_EVENT_INFORMATION_REQUEST);
-
- if (verbose)
- printf(" got DHCPv6 event %d\n", event);
-
- assert_se(sd_dhcp6_client_set_information_request(client, false) >= 0);
- assert_se(sd_dhcp6_client_set_callback(client,
- test_client_solicit_cb, e) >= 0);
-
- assert_se(sd_dhcp6_client_start(client) >= 0);
-}
-
-static int test_client_verify_information_request(DHCP6Message *information_request,
- uint8_t *option, size_t len) {
-
- _cleanup_dhcp6_lease_free_ sd_dhcp6_lease *lease = NULL;
- uint8_t *optval;
- uint16_t optcode;
- size_t optlen;
- bool found_clientid = false, found_elapsed_time = false;
- int r;
- struct in6_addr addr;
- uint32_t lt_pref, lt_valid;
-
- assert_se(information_request->type == DHCP6_INFORMATION_REQUEST);
-
- assert_se(dhcp6_lease_new(&lease) >= 0);
-
- while ((r = dhcp6_option_parse(&option, &len,
- &optcode, &optlen, &optval)) >= 0) {
- switch(optcode) {
- case DHCP6_OPTION_CLIENTID:
- assert_se(!found_clientid);
- found_clientid = true;
-
- assert_se(optlen == sizeof(test_duid));
- memcpy(&test_duid, optval, sizeof(test_duid));
-
- break;
-
- case DHCP6_OPTION_IA_NA:
- assert_not_reached("IA TA option must not be present");
-
- break;
-
- case DHCP6_OPTION_SERVERID:
- assert_not_reached("Server ID option must not be present");
-
- break;
-
- case DHCP6_OPTION_ELAPSED_TIME:
- assert_se(!found_elapsed_time);
- found_elapsed_time = true;
-
- assert_se(optlen == 2);
-
- break;
- }
- }
-
- assert_se(r == -ENOMSG);
- assert_se(found_clientid && found_elapsed_time);
-
- sd_dhcp6_lease_reset_address_iter(lease);
-
- assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
- &lt_valid) == -ENOMSG);
-
- return 0;
-}
-
-int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
- const void *packet, size_t len) {
- struct in6_addr mcast =
- IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT;
- DHCP6Message *message;
- uint8_t *option;
-
- assert_se(s == test_dhcp_fd[0]);
- assert_se(server_address);
- assert_se(packet);
- assert_se(len > sizeof(DHCP6Message) + 4);
-
- assert_se(IN6_ARE_ADDR_EQUAL(server_address, &mcast));
-
- message = (DHCP6Message *)packet;
- option = (uint8_t *)(message + 1);
- len -= sizeof(DHCP6Message);
-
- assert_se(message->transaction_id & 0x00ffffff);
-
- if (test_client_message_num == 0) {
- test_client_verify_information_request(message, option, len);
- test_client_send_reply(message);
- test_client_message_num++;
- } else if (test_client_message_num == 1) {
- test_client_verify_solicit(message, option, len);
- test_client_send_advertise(message);
- test_client_message_num++;
- } else if (test_client_message_num == 2) {
- test_client_verify_request(message, option, len);
- test_client_send_reply(message);
- test_client_message_num++;
- }
-
- return len;
-}
-
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
- assert_se(index == test_index);
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_dhcp_fd) < 0)
- return -errno;
-
- return test_dhcp_fd[0];
-}
-
-static int test_client_solicit(sd_event *e) {
- sd_dhcp6_client *client;
- usec_t time_now = now(clock_boottime_or_monotonic());
- bool val = true;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(sd_dhcp6_client_new(&client) >= 0);
- assert_se(client);
-
- assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
-
- assert_se(sd_dhcp6_client_set_index(client, test_index) == 0);
- assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
- sizeof (mac_addr),
- ARPHRD_ETHER) >= 0);
-
- assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
- assert_se(val == false);
- assert_se(sd_dhcp6_client_set_information_request(client, true) >= 0);
- assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0);
- assert_se(val == true);
-
- assert_se(sd_dhcp6_client_set_callback(client,
- test_client_information_cb, e) >= 0);
-
- assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(),
- time_now + 2 * USEC_PER_SEC, 0,
- test_hangcheck, NULL) >= 0);
-
- assert_se(sd_dhcp6_client_start(client) >= 0);
-
- sd_event_loop(e);
-
- hangcheck = sd_event_source_unref(hangcheck);
-
- assert_se(!sd_dhcp6_client_unref(client));
-
- test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_event_unref_ sd_event *e;
-
- assert_se(sd_event_new(&e) >= 0);
-
- log_set_max_level(LOG_DEBUG);
- log_parse_environment();
- log_open();
-
- test_client_basic(e);
- test_option(e);
- test_advertise_option(e);
- test_client_solicit(e);
-
- assert_se(!sd_event_unref(e));
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-icmp6-rs.c b/src/libsystemd-network/test-icmp6-rs.c
deleted file mode 100644
index 8ba21106a7..0000000000
--- a/src/libsystemd-network/test-icmp6-rs.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Intel Corporation. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <netinet/icmp6.h>
-
-#include "socket-util.h"
-
-#include "dhcp6-internal.h"
-#include "sd-icmp6-nd.h"
-
-static struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
-};
-
-static bool verbose = false;
-static sd_event_source *test_hangcheck;
-static int test_fd[2];
-
-typedef int (*send_ra_t)(uint8_t flags);
-static send_ra_t send_ra_function;
-
-static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
- void *userdata) {
- assert_se(false);
-
- return 0;
-}
-
-int dhcp_network_icmp6_bind_router_solicitation(int index) {
- assert_se(index == 42);
-
- if (socketpair(AF_UNIX, SOCK_DGRAM, 0, test_fd) < 0)
- return -errno;
-
- return test_fd[0];
-}
-
-static int send_ra_short_prefix(uint8_t flags) {
- uint8_t advertisement[] = {
- 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- 0x03, 0x04, 0x34, 0xc0, 0x00, 0x00, 0x01, 0xf4,
- 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
- sizeof(advertisement));
-
- return 0;
-}
-
-static void test_short_prefix_cb(sd_icmp6_nd *nd, int event, void *userdata) {
- sd_event *e = userdata;
- struct {
- struct in6_addr addr;
- uint8_t prefixlen;
- bool success;
- } addrs[] = {
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 52, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 64, false },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 60, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 64, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
- 52, true },
- };
- uint8_t prefixlen;
- unsigned int i;
-
- for (i = 0; i < ELEMENTSOF(addrs); i++) {
- printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x",
- __FUNCTION__,
- addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1],
- addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3],
- addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5],
- addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]);
-
- if (addrs[i].success) {
- assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr,
- &prefixlen) >= 0);
- assert_se(addrs[i].prefixlen == prefixlen);
- printf("/%d onlink\n", prefixlen);
- } else {
- assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr,
- &prefixlen) == -EADDRNOTAVAIL);
- printf("/128 offlink\n");
- }
- }
-
- sd_event_exit(e, 0);
-}
-
-static int send_ra_prefixes(uint8_t flags) {
- uint8_t advertisement[] = {
- 0x86, 0x00, 0xbe, 0xd7, 0x40, 0xc0, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x04, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0xf4,
- 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x04, 0x40, 0x00, 0x00, 0x00, 0x02, 0x58,
- 0x00, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x04, 0x3c, 0x80, 0x00, 0x00, 0x03, 0x84,
- 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x03, 0x84,
- 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
- 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53
- };
-
- assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
- sizeof(advertisement));
-
- return 0;
-}
-
-static void test_prefixes_cb(sd_icmp6_nd *nd, int event, void *userdata) {
- sd_event *e = userdata;
- struct {
- struct in6_addr addr;
- uint8_t prefixlen;
- bool success;
- } addrs[] = {
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 63, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0x0d, 0xad,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 64, false },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 60, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x9d, 0xab, 0xcd,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
- 64, true },
- { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xed,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } },
- 63, false },
- };
- uint8_t prefixlen;
- unsigned int i;
-
- for (i = 0; i < ELEMENTSOF(addrs); i++) {
- printf(" %s prefix %02x%02x:%02x%02x:%02x%02x:%02x%02x",
- __FUNCTION__,
- addrs[i].addr.s6_addr[0], addrs[i].addr.s6_addr[1],
- addrs[i].addr.s6_addr[2], addrs[i].addr.s6_addr[3],
- addrs[i].addr.s6_addr[4], addrs[i].addr.s6_addr[5],
- addrs[i].addr.s6_addr[6], addrs[i].addr.s6_addr[7]);
-
- if (addrs[i].success) {
- assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr,
- &prefixlen) >= 0);
- assert_se(addrs[i].prefixlen == prefixlen);
- printf("/%d onlink\n", prefixlen);
- } else {
- assert_se(sd_icmp6_ra_get_prefixlen(nd, &addrs[i].addr,
- &prefixlen) == -EADDRNOTAVAIL);
- printf("/128 offlink\n");
- }
- }
-
- send_ra_function = send_ra_short_prefix;
- assert_se(sd_icmp6_nd_set_callback(nd, test_short_prefix_cb, e) >= 0);
- assert_se(sd_icmp6_nd_stop(nd) >= 0);
- assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
-}
-
-static void test_prefixes(void) {
- sd_event *e;
- sd_icmp6_nd *nd;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- send_ra_function = send_ra_prefixes;
-
- assert_se(sd_event_new(&e) >= 0);
-
- assert_se(sd_icmp6_nd_new(&nd) >= 0);
- assert_se(nd);
-
- assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);
-
- assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0);
- assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
- assert_se(sd_icmp6_nd_set_callback(nd, test_prefixes_cb, e) >= 0);
-
- assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
-
- sd_event_loop(e);
-
- nd = sd_icmp6_nd_unref(nd);
- assert_se(!nd);
-
- close(test_fd[1]);
-
- sd_event_unref(e);
-}
-
-static int send_ra(uint8_t flags) {
- uint8_t advertisement[] = {
- 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
- 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
- 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
- 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
- };
-
- advertisement[5] = flags;
-
- assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) ==
- sizeof(advertisement));
-
- if (verbose)
- printf(" sent RA with flag 0x%02x\n", flags);
-
- return 0;
-}
-
-int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
- return send_ra_function(0);
-}
-
-static void test_rs_done(sd_icmp6_nd *nd, int event, void *userdata) {
- sd_event *e = userdata;
- static int idx = 0;
- struct {
- uint8_t flag;
- int event;
- } flag_event[] = {
- { 0, ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE },
- { ND_RA_FLAG_OTHER, ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER },
- { ND_RA_FLAG_MANAGED, ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED }
- };
- uint32_t mtu;
-
- assert_se(nd);
-
- assert_se(event == flag_event[idx].event);
- idx++;
-
- if (verbose)
- printf(" got event %d\n", event);
-
- if (idx < 3) {
- send_ra(flag_event[idx].flag);
- return;
- }
-
- assert_se(sd_icmp6_ra_get_mtu(nd, &mtu) == -ENOMSG);
-
- sd_event_exit(e, 0);
-}
-
-static void test_rs(void) {
- sd_event *e;
- sd_icmp6_nd *nd;
- usec_t time_now = now(clock_boottime_or_monotonic());
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- send_ra_function = send_ra;
-
- assert_se(sd_event_new(&e) >= 0);
-
- assert_se(sd_icmp6_nd_new(&nd) >= 0);
- assert_se(nd);
-
- assert_se(sd_icmp6_nd_attach_event(nd, e, 0) >= 0);
-
- assert_se(sd_icmp6_nd_set_index(nd, 42) >= 0);
- assert_se(sd_icmp6_nd_set_mac(nd, &mac_addr) >= 0);
- assert_se(sd_icmp6_nd_set_callback(nd, test_rs_done, e) >= 0);
-
- assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
- time_now + 2 *USEC_PER_SEC, 0,
- test_rs_hangcheck, NULL) >= 0);
-
- assert_se(sd_icmp6_nd_stop(nd) >= 0);
- assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
- assert_se(sd_icmp6_nd_stop(nd) >= 0);
-
- assert_se(sd_icmp6_router_solicitation_start(nd) >= 0);
-
- sd_event_loop(e);
-
- test_hangcheck = sd_event_source_unref(test_hangcheck);
-
- nd = sd_icmp6_nd_unref(nd);
- assert_se(!nd);
-
- close(test_fd[1]);
-
- sd_event_unref(e);
-}
-
-int main(int argc, char *argv[]) {
-
- log_set_max_level(LOG_DEBUG);
- log_parse_environment();
- log_open();
-
- test_rs();
- test_prefixes();
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
deleted file mode 100644
index 459d5c324d..0000000000
--- a/src/libsystemd-network/test-ipv4ll.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Axis Communications AB. All rights reserved.
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "util.h"
-#include "socket-util.h"
-
-#include "sd-ipv4ll.h"
-#include "ipv4ll-internal.h"
-
-static bool verbose = false;
-static bool extended = false;
-static int test_fd[2];
-
-static int basic_request_handler_bind = 0;
-static int basic_request_handler_stop = 0;
-static void* basic_request_handler_user_data = (void*)0xCABCAB;
-static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
- assert_se(userdata == basic_request_handler_user_data);
-
- switch(event) {
- case IPV4LL_EVENT_STOP:
- basic_request_handler_stop = 1;
- break;
- case IPV4LL_EVENT_BIND:
- basic_request_handler_bind = 1;
- break;
- default:
- assert_se(0);
- break;
- }
-}
-
-int arp_network_send_raw_socket(int fd, const union sockaddr_union *link,
- const struct ether_arp *arp) {
- assert_se(arp);
- assert_se(link);
- assert_se(fd >= 0);
-
- if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
- return -errno;
-
- return 0;
-}
-
-int arp_network_bind_raw_socket(int index, union sockaddr_union *link) {
- if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
- return -errno;
-
- return test_fd[0];
-}
-
-static void test_arp_header(struct ether_arp *arp) {
- assert_se(arp);
- assert_se(arp->ea_hdr.ar_hrd == htons(ARPHRD_ETHER)); /* HTYPE */
- assert_se(arp->ea_hdr.ar_pro == htons(ETHERTYPE_IP)); /* PTYPE */
- assert_se(arp->ea_hdr.ar_hln == ETH_ALEN); /* HLEN */
- assert_se(arp->ea_hdr.ar_pln == sizeof arp->arp_spa); /* PLEN */
- assert_se(arp->ea_hdr.ar_op == htons(ARPOP_REQUEST)); /* REQUEST */
-}
-
-static void test_arp_probe(void) {
- struct ether_arp arp;
- struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
- be32_t pa = 0x3030;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- arp_packet_probe(&arp, pa, &mac_addr);
- test_arp_header(&arp);
- assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
- assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
-}
-
-static void test_arp_announce(void) {
- struct ether_arp arp;
- struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
- be32_t pa = 0x3131;
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- arp_packet_announcement(&arp, pa, &mac_addr);
- test_arp_header(&arp);
- assert_se(memcmp(arp.arp_sha, &mac_addr, ETH_ALEN) == 0);
- assert_se(memcmp(arp.arp_tpa, &pa, sizeof(pa)) == 0);
- assert_se(memcmp(arp.arp_spa, &pa, sizeof(pa)) == 0);
-}
-
-static void test_public_api_setters(sd_event *e) {
- uint8_t seed[8];
- sd_ipv4ll *ll;
- struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(sd_ipv4ll_new(&ll) == 0);
- assert_se(ll);
-
- assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
- assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
- assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);
-
- assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
- assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
-
- assert_se(sd_ipv4ll_set_address_seed(NULL, NULL) == -EINVAL);
- assert_se(sd_ipv4ll_set_address_seed(ll, NULL) == -EINVAL);
- assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
-
- assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
- assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
- assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
-
- assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
- assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
- assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
- assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
- assert_se(sd_ipv4ll_set_index(ll, 99) == 0);
-
- assert_se(sd_ipv4ll_ref(ll) == ll);
- assert_se(sd_ipv4ll_unref(ll) == ll);
-
- /* Cleanup */
- assert_se(sd_ipv4ll_unref(ll) == NULL);
-}
-
-static void test_basic_request(sd_event *e) {
-
- sd_ipv4ll *ll;
- struct ether_arp arp;
- struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
-
- if (verbose)
- printf("* %s\n", __FUNCTION__);
-
- assert_se(sd_ipv4ll_new(&ll) == 0);
- assert_se(sd_ipv4ll_start(ll) == -EINVAL);
-
- assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
- assert_se(sd_ipv4ll_start(ll) == -EINVAL);
-
- assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
- assert_se(sd_ipv4ll_start(ll) == -EINVAL);
-
- assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
- basic_request_handler_user_data) == 0);
- assert_se(sd_ipv4ll_start(ll) == -EINVAL);
-
- assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
- assert_se(sd_ipv4ll_start(ll) == 0);
-
- sd_event_run(e, (uint64_t) -1);
- assert_se(sd_ipv4ll_start(ll) == -EBUSY);
-
- /* PROBE */
- sd_event_run(e, (uint64_t) -1);
- assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
- test_arp_header(&arp);
-
- if (extended) {
- /* PROBE */
- sd_event_run(e, (uint64_t) -1);
- assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
- test_arp_header(&arp);
-
- /* PROBE */
- sd_event_run(e, (uint64_t) -1);
- assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
- test_arp_header(&arp);
-
- sd_event_run(e, (uint64_t) -1);
- assert_se(basic_request_handler_bind == 1);
- }
-
- sd_ipv4ll_stop(ll);
- assert_se(basic_request_handler_stop == 1);
-
- /* Cleanup */
- assert_se(sd_ipv4ll_unref(ll) == NULL);
- safe_close(test_fd[1]);
-}
-
-int main(int argc, char *argv[]) {
- sd_event *e;
-
- assert_se(sd_event_new(&e) >= 0);
-
- test_public_api_setters(e);
- test_arp_probe();
- test_arp_announce();
- test_basic_request(e);
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-lldp.c b/src/libsystemd-network/test-lldp.c
deleted file mode 100644
index 06545aee59..0000000000
--- a/src/libsystemd-network/test-lldp.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen
- Copyright (C) 2014 Susant Sahani
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdio.h>
-#include <string.h>
-#include <net/ethernet.h>
-#include <arpa/inet.h>
-
-#include "macro.h"
-#include "lldp.h"
-#include "lldp-tlv.h"
-
-#define TEST_LLDP_PORT "em1"
-#define TEST_LLDP_TYPE_SYSTEM_NAME "systemd-lldp"
-#define TEST_LLDP_TYPE_SYSTEM_DESC "systemd-lldp-desc"
-
-static struct ether_addr mac_addr = {
- .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
-};
-
-static int lldp_build_tlv_packet(tlv_packet **ret) {
- _cleanup_tlv_packet_free_ tlv_packet *m = NULL;
- const uint8_t lldp_dst[] = LLDP_MULTICAST_ADDR;
- struct ether_header ether = {
- .ether_type = htons(ETHERTYPE_LLDP),
- };
-
- /* Append ethernet header */
- memcpy(&ether.ether_dhost, lldp_dst, ETHER_ADDR_LEN);
- memcpy(&ether.ether_shost, &mac_addr, ETHER_ADDR_LEN);
-
- assert_se(tlv_packet_new(&m) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, &ether, sizeof(struct ether_header)) >= 0);
-
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_CHASSIS_ID) >= 0);
-
- assert_se(tlv_packet_append_u8(m, LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS) >= 0);
- assert_se(tlv_packet_append_bytes(m, &mac_addr, ETHER_ADDR_LEN) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* port name */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_PORT_ID) >= 0);
-
- assert_se(tlv_packet_append_u8(m, LLDP_PORT_SUBTYPE_INTERFACE_NAME) >= 0);
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_PORT, strlen(TEST_LLDP_PORT) + 1) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* ttl */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_TTL) >= 0);
-
- assert_se(tlv_packet_append_u16(m, 170) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* system name */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_SYSTEM_NAME) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_TYPE_SYSTEM_NAME,
- strlen(TEST_LLDP_TYPE_SYSTEM_NAME)) >= 0);
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* system descrition */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_SYSTEM_DESCRIPTION) >= 0);
-
- assert_se(tlv_packet_append_bytes(m, TEST_LLDP_TYPE_SYSTEM_DESC,
- strlen(TEST_LLDP_TYPE_SYSTEM_DESC)) >= 0);
-
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- /* Mark end of packet */
- assert_se(lldp_tlv_packet_open_container(m, LLDP_TYPE_END) >= 0);
- assert_se(lldp_tlv_packet_close_container(m) >= 0);
-
- *ret = m;
-
- m = NULL;
-
- return 0;
-}
-
-static int lldp_parse_chassis_tlv(tlv_packet *m, uint8_t *type) {
- uint8_t *p, subtype;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_CHASSIS_ID) >= 0);
- assert_se(tlv_packet_read_u8(m, &subtype) >= 0);
-
- switch (subtype) {
- case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
-
- *type = LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS;
- assert_se(tlv_packet_read_bytes(m, &p, &length) >= 0);
-
- assert_se(memcmp(p, &mac_addr.ether_addr_octet, ETHER_ADDR_LEN) == 0);
-
- break;
- default:
- assert_not_reached("Unhandled option");
- }
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_port_id_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
- uint8_t subtype;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_PORT_ID) >= 0);
-
- assert_se(tlv_packet_read_u8(m, &subtype) >= 0);
-
- switch (subtype) {
- case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length-1);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_PORT) == 1);
- break;
- default:
- assert_not_reached("Unhandled option");
- }
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_system_name_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_SYSTEM_NAME) >= 0);
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_TYPE_SYSTEM_NAME) == 1);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 1;
-}
-
-static int lldp_parse_system_desc_tlv(tlv_packet *m) {
- _cleanup_free_ char *p = NULL;
- char *str = NULL;
- uint16_t length;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_SYSTEM_DESCRIPTION) >= 0);
- assert_se(tlv_packet_read_string(m, &str, &length) >= 0);
-
- p = strndup(str, length);
- assert_se(p);
-
- assert_se(streq(p, TEST_LLDP_TYPE_SYSTEM_DESC) == 1);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_ttl_tlv(tlv_packet *m) {
- uint16_t ttl;
-
- assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_TTL) >= 0);
- assert_se(tlv_packet_read_u16(m, &ttl) >= 0);
-
- assert_se(ttl == 170);
-
- assert_se(lldp_tlv_packet_exit_container(m) >= 0);
-
- return 0;
-}
-
-static int lldp_parse_tlv_packet(tlv_packet *m, int len) {
- uint8_t subtype;
-
- assert_se(tlv_packet_parse_pdu(m, len) >= 0);
- assert_se(lldp_parse_chassis_tlv(m, &subtype) >= 0);
- assert_se(lldp_parse_port_id_tlv(m) >= 0);
- assert_se(lldp_parse_system_name_tlv(m) >= 0);
- assert_se(lldp_parse_ttl_tlv(m) >= 0);
- assert_se(lldp_parse_system_desc_tlv(m) >= 0);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_tlv_packet_free_ tlv_packet *tlv = NULL;
-
- /* form a packet */
- lldp_build_tlv_packet(&tlv);
-
- /* parse the packet */
- tlv_packet_parse_pdu(tlv, tlv->length);
-
- /* verify */
- lldp_parse_tlv_packet(tlv, tlv->length);
-
- return 0;
-}
diff --git a/src/libsystemd-network/test-pppoe.c b/src/libsystemd-network/test-pppoe.c
deleted file mode 100644
index 40d04fdb21..0000000000
--- a/src/libsystemd-network/test-pppoe.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright (C) 2014 Tom Gundersen <teg@jklm.no>
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include <linux/veth.h>
-#include <net/if.h>
-
-#include "util.h"
-#include "sd-event.h"
-#include "event-util.h"
-#include "sd-rtnl.h"
-#include "sd-pppoe.h"
-
-static void pppoe_handler(sd_pppoe *ppp, int event, void *userdata) {
- static int pppoe_state = -1;
- sd_event *e = userdata;
-
- assert_se(ppp);
- assert_se(e);
-
- switch (event) {
- case PPPOE_EVENT_RUNNING:
- assert_se(pppoe_state == -1);
- log_info("running");
- break;
- case PPPOE_EVENT_STOPPED:
- assert_se(pppoe_state == PPPOE_EVENT_RUNNING);
- log_info("stopped");
- assert_se(sd_event_exit(e, 0) >= 0);
- break;
- default:
- assert_not_reached("invalid pppoe event");
- }
-
- pppoe_state = event;
-}
-
-static int client_run(const char *client_name, sd_event *e) {
- sd_pppoe *pppoe;
- int client_ifindex;
-
- client_ifindex = (int) if_nametoindex(client_name);
- assert_se(client_ifindex > 0);
-
- assert_se(sd_pppoe_new(&pppoe) >= 0);
- assert_se(sd_pppoe_attach_event(pppoe, e, 0) >= 0);
-
- assert_se(sd_pppoe_set_ifname(pppoe, "pppoe-client") >= 0);
- assert_se(sd_pppoe_set_ifindex(pppoe, client_ifindex) >= 0);
- assert_se(sd_pppoe_set_callback(pppoe, pppoe_handler, e) >= 0);
-
- log_info("starting PPPoE client, it will exit when the server times out and sends PADT");
-
- assert_se(sd_pppoe_start(pppoe) >= 0);
-
- assert_se(sd_event_loop(e) >= 0);
-
- assert_se(!sd_pppoe_unref(pppoe));
-
- return EXIT_SUCCESS;
-}
-
-static int test_pppoe_server(sd_event *e) {
- sd_rtnl *rtnl;
- sd_rtnl_message *m;
- pid_t pid;
- int r, client_ifindex, server_ifindex;
-
- r = unshare(CLONE_NEWNET);
- if (r < 0 && errno == EPERM)
- return EXIT_TEST_SKIP;
-
- assert_se(r >= 0);
-
- assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
- assert_se(sd_rtnl_attach_event(rtnl, e, 0) >= 0);
-
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0);
- assert_se(sd_rtnl_message_append_string(m, IFLA_IFNAME, "pppoe-server") >= 0);
- assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
- assert_se(sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth") >= 0);
- assert_se(sd_rtnl_message_open_container(m, VETH_INFO_PEER) >= 0);
- assert_se(sd_rtnl_message_append_string(m, IFLA_IFNAME, "pppoe-client") >= 0);
- assert_se(sd_rtnl_message_close_container(m) >= 0);
- assert_se(sd_rtnl_message_close_container(m) >= 0);
- assert_se(sd_rtnl_message_close_container(m) >= 0);
- assert_se(sd_rtnl_call(rtnl, m, 0, NULL) >= 0);
-
- client_ifindex = (int) if_nametoindex("pppoe-client");
- assert_se(client_ifindex > 0);
- server_ifindex = (int) if_nametoindex("pppoe-server");
- assert_se(server_ifindex > 0);
-
- m = sd_rtnl_message_unref(m);
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, client_ifindex) >= 0);
- assert_se(sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP) >= 0);
- assert_se(sd_rtnl_call(rtnl, m, 0, NULL) >= 0);
-
- m = sd_rtnl_message_unref(m);
- assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_SETLINK, server_ifindex) >= 0);
- assert_se(sd_rtnl_message_link_set_flags(m, IFF_UP, IFF_UP) >= 0);
- assert_se(sd_rtnl_call(rtnl, m, 0, NULL) >= 0);
-
- pid = fork();
- assert_se(pid >= 0);
- if (pid == 0) {
- /* let the client send some discover messages before the server is started */
- sleep(2);
-
- /* TODO: manage pppoe-server-options */
- execlp("pppoe-server", "pppoe-server", "-F",
- "-I", "pppoe-server",
- "-C", "Test-AC",
- "-S", "Service-Default",
- "-S", "Service-First-Auxiliary",
- "-S", "Service-Second-Auxiliary",
- NULL);
- assert_not_reached("failed to execute pppoe-server. not installed?");
- }
-
- client_run("pppoe-client", e);
-
- assert_se(kill(pid, SIGTERM) >= 0);
- assert_se(wait_for_terminate(pid, NULL) >= 0);
-
- assert_se(!sd_rtnl_message_unref(m));
- assert_se(!sd_rtnl_unref(rtnl));
-
- return EXIT_SUCCESS;
-}
-
-int main(int argc, char *argv[]) {
- _cleanup_event_unref_ sd_event *e = NULL;
-
- log_set_max_level(LOG_DEBUG);
- log_parse_environment();
- log_open();
-
- assert_se(sd_event_new(&e) >= 0);
-
- if (argc == 1) {
- log_info("running PPPoE client against local server");
-
- return test_pppoe_server(e);
- } else if (argc == 2) {
- log_info("running PPPoE client over '%s'", argv[1]);
-
- return client_run(argv[1], e);
- } else {
- log_error("This program takes one or no arguments.\n"
- "\t %s [<ifname>]", program_invocation_short_name);
- return EXIT_FAILURE;
- }
-}