dhcp/systemd: drop dhcp4 client (and related files)

This code is now unused.
This commit is contained in:
Thomas Haller 2022-04-11 12:13:56 +02:00
parent 54119d4105
commit 6150a495c9
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
18 changed files with 0 additions and 5931 deletions

View file

@ -2343,16 +2343,8 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/sd-adapt-core/sd-daemon.h \
src/libnm-systemd-core/sd-adapt-core/sd-device.h \
src/libnm-systemd-core/sd-adapt-core/udev-util.h \
src/libnm-systemd-core/src/libsystemd-network/arp-util.c \
src/libnm-systemd-core/src/libsystemd-network/arp-util.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp-identifier.c \
src/libnm-systemd-core/src/libsystemd-network/dhcp-identifier.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp-internal.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp-lease-internal.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp-network.c \
src/libnm-systemd-core/src/libsystemd-network/dhcp-option.c \
src/libnm-systemd-core/src/libsystemd-network/dhcp-packet.c \
src/libnm-systemd-core/src/libsystemd-network/dhcp-protocol.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp6-lease-internal.h \
src/libnm-systemd-core/src/libsystemd-network/dhcp6-network.c \
@ -2367,10 +2359,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/src/libsystemd-network/lldp-rx-internal.h \
src/libnm-systemd-core/src/libsystemd-network/network-common.c \
src/libnm-systemd-core/src/libsystemd-network/network-common.h \
src/libnm-systemd-core/src/libsystemd-network/network-internal.c \
src/libnm-systemd-core/src/libsystemd-network/network-internal.h \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp-client.c \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp-lease.c \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c \
src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c \
src/libnm-systemd-core/src/libsystemd-network/sd-lldp-rx.c \
@ -2382,9 +2370,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.h \
src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c \
src/libnm-systemd-core/src/systemd/_sd-common.h \
src/libnm-systemd-core/src/systemd/sd-dhcp-client.h \
src/libnm-systemd-core/src/systemd/sd-dhcp-lease.h \
src/libnm-systemd-core/src/systemd/sd-dhcp-option.h \
src/libnm-systemd-core/src/systemd/sd-dhcp6-client.h \
src/libnm-systemd-core/src/systemd/sd-dhcp6-lease.h \
src/libnm-systemd-core/src/systemd/sd-dhcp6-option.h \

View file

@ -3,20 +3,13 @@
libnm_systemd_core = static_library(
'nm-systemd-core',
sources: files(
'src/libsystemd-network/arp-util.c',
'src/libsystemd-network/dhcp-identifier.c',
'src/libsystemd-network/dhcp-network.c',
'src/libsystemd-network/dhcp-option.c',
'src/libsystemd-network/dhcp-packet.c',
'src/libsystemd-network/dhcp6-network.c',
'src/libsystemd-network/dhcp6-option.c',
'src/libsystemd-network/dhcp6-protocol.c',
'src/libsystemd-network/lldp-neighbor.c',
'src/libsystemd-network/lldp-network.c',
'src/libsystemd-network/network-common.c',
'src/libsystemd-network/network-internal.c',
'src/libsystemd-network/sd-dhcp-client.c',
'src/libsystemd-network/sd-dhcp-lease.c',
'src/libsystemd-network/sd-dhcp6-client.c',
'src/libsystemd-network/sd-dhcp6-lease.c',
'src/libsystemd-network/sd-lldp-rx.c',

View file

@ -6,7 +6,6 @@
#ifndef __NM_SD_H__
#define __NM_SD_H__
#include "src/systemd/sd-dhcp-lease.h"
#include "src/systemd/sd-dhcp6-client.h"
#include "src/systemd/sd-lldp-rx.h"
@ -14,15 +13,4 @@
guint nm_sd_event_attach_default(void);
/*****************************************************************************
* expose internal systemd API
*
* FIXME: don't use any internal systemd API.
*****************************************************************************/
struct sd_dhcp_lease;
int dhcp_lease_save(struct sd_dhcp_lease *lease, const char *lease_file);
int dhcp_lease_load(struct sd_dhcp_lease **ret, const char *lease_file);
#endif /* __NM_SD_H__ */

View file

@ -1,142 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
Copyright © 2014 Axis Communications AB. All rights reserved.
***/
#include "nm-sd-adapt-core.h"
#include <arpa/inet.h>
#include <linux/filter.h>
#include <netinet/if_ether.h>
#include "arp-util.h"
#include "ether-addr-util.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "unaligned.h"
#include "util.h"
int arp_update_filter(int fd, const struct in_addr *a, const struct ether_addr *mac) {
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_B + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_hln)), /* A <- hardware address length */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, sizeof(struct ether_addr), 1, 0), /* length == sizeof(ether_addr)? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(struct ether_arp, ea_hdr.ar_pln)), /* A <- protocol address length */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, sizeof(struct in_addr), 1, 0), /* length == sizeof(in_addr) ? */
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, 2, 0), /* protocol == request ? */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REPLY, 1, 0), /* protocol == reply ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
/* Sender Hardware Address must be different from our own */
BPF_STMT(BPF_LDX + BPF_IMM, unaligned_read_be32(&mac->ether_addr_octet[0])), /* X <- 4 bytes of client's MAC */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_sha)), /* A <- 4 bytes of SHA */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 0, 4), /* A == X ? */
BPF_STMT(BPF_LDX + BPF_IMM, unaligned_read_be16(&mac->ether_addr_octet[4])), /* X <- remainder of client's MAC */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct ether_arp, arp_sha) + 4), /* A <- remainder of SHA */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 0, 1), /* A == X ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
/* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
BPF_STMT(BPF_LDX + BPF_IMM, htobe32(a->s_addr)), /* X <- clients IP */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)), /* A <- SPA */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 0, 1), /* A == X ? */
BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_tpa)), /* A <- TPA */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 0, 1), /* A == 0 ? */
BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
};
struct sock_fprog fprog = {
.len = ELEMENTSOF(filter),
.filter = (struct sock_filter*) filter,
};
assert(fd >= 0);
if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog)) < 0)
return -errno;
return 0;
}
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *mac) {
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
.ll.sll_protocol = htobe16(ETH_P_ARP),
.ll.sll_ifindex = ifindex,
.ll.sll_halen = ETH_ALEN,
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
};
_cleanup_close_ int s = -1;
int r;
assert(ifindex > 0);
assert(mac);
s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (s < 0)
return -errno;
r = arp_update_filter(s, a, mac);
if (r < 0)
return r;
if (bind(s, &link.sa, sizeof(link.ll)) < 0)
return -errno;
return TAKE_FD(s);
}
int arp_send_packet(
int fd,
int ifindex,
const struct in_addr *pa,
const struct ether_addr *ha,
bool announce) {
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
.ll.sll_protocol = htobe16(ETH_P_ARP),
.ll.sll_ifindex = ifindex,
.ll.sll_halen = ETH_ALEN,
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
};
struct ether_arp arp = {
.ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
.ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
.ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
.ea_hdr.ar_pln = sizeof(struct in_addr), /* PLEN */
.ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
};
ssize_t n;
assert(fd >= 0);
assert(ifindex > 0);
assert(pa);
assert(in4_addr_is_set(pa));
assert(ha);
assert(!ether_addr_is_null(ha));
memcpy(&arp.arp_sha, ha, ETH_ALEN);
memcpy(&arp.arp_tpa, pa, sizeof(struct in_addr));
if (announce)
memcpy(&arp.arp_spa, pa, sizeof(struct in_addr));
n = sendto(fd, &arp, sizeof(struct ether_arp), 0, &link.sa, sizeof(link.ll));
if (n < 0)
return -errno;
if (n != sizeof(struct ether_arp))
return -EIO;
return 0;
}

View file

@ -1,36 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/***
Copyright © 2014 Axis Communications AB. All rights reserved.
***/
#include <net/ethernet.h>
#include <netinet/in.h>
#include "socket-util.h"
#include "sparse-endian.h"
int arp_update_filter(int fd, const struct in_addr *a, const struct ether_addr *mac);
int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *mac);
int arp_send_packet(
int fd,
int ifindex,
const struct in_addr *pa,
const struct ether_addr *ha,
bool announce);
static inline int arp_send_probe(
int fd,
int ifindex,
const struct in_addr *pa,
const struct ether_addr *ha) {
return arp_send_packet(fd, ifindex, pa, ha, false);
}
static inline int arp_send_announcement(
int fd,
int ifindex,
const struct in_addr *pa,
const struct ether_addr *ha) {
return arp_send_packet(fd, ifindex, pa, ha, true);
}

View file

@ -1,84 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <stdint.h>
#include "sd-dhcp-client.h"
#include "dhcp-protocol.h"
#include "network-common.h"
#include "socket-util.h"
typedef struct sd_dhcp_option {
unsigned n_ref;
uint8_t option;
void *data;
size_t length;
} sd_dhcp_option;
typedef struct DHCPServerData {
struct in_addr *addr;
size_t size;
} DHCPServerData;
extern const struct hash_ops dhcp_option_hash_ops;
typedef struct sd_dhcp_client sd_dhcp_client;
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,
const uint8_t *bcast_addr, size_t bcast_addr_len,
uint16_t arp_type, uint16_t port);
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type);
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);
int dhcp_option_find_option(uint8_t *options, size_t length, uint8_t wanted_code, size_t *ret_offset);
int dhcp_option_remove_option(uint8_t *options, size_t buflen, uint8_t option_code);
typedef int (*dhcp_option_callback_t)(uint8_t code, uint8_t len,
const void *option, void *userdata);
int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t cb, void *userdata, char **error_message);
int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
uint8_t type, uint16_t arp_type, uint8_t hlen, const uint8_t *chaddr,
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 ip_service_type);
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);
void dhcp_client_set_test_mode(sd_dhcp_client *client, bool test_mode);
/* 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_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
#define log_dhcp_client_errno(client, error, fmt, ...) \
log_interface_prefix_full_errno( \
"DHCPv4 client: ", \
sd_dhcp_client, client, \
error, fmt, ##__VA_ARGS__)
#define log_dhcp_client(client, fmt, ...) \
log_interface_prefix_full_errno_zerook( \
"DHCPv4 client: ", \
sd_dhcp_client, client, \
0, fmt, ##__VA_ARGS__)

View file

@ -1,90 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include "sd-dhcp-client.h"
#include "dhcp-internal.h"
#include "dhcp-protocol.h"
#include "list.h"
#include "util.h"
struct sd_dhcp_route {
struct in_addr dst_addr;
struct in_addr gw_addr;
unsigned char dst_prefixlen;
};
struct sd_dhcp_raw_option {
LIST_FIELDS(struct sd_dhcp_raw_option, options);
uint8_t tag;
uint8_t length;
void *data;
};
struct sd_dhcp_lease {
unsigned n_ref;
/* each 0 if unset */
uint32_t t1;
uint32_t t2;
uint32_t lifetime;
/* each 0 if unset */
be32_t address;
be32_t server_address;
be32_t next_server;
bool have_subnet_mask;
be32_t subnet_mask;
bool have_broadcast;
be32_t broadcast;
struct in_addr *router;
size_t router_size;
DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
struct sd_dhcp_route *static_routes;
size_t n_static_routes;
struct sd_dhcp_route *classless_routes;
size_t n_classless_routes;
uint16_t mtu; /* 0 if unset */
char *domainname;
char **search_domains;
char *hostname;
char *root_path;
void *client_id;
size_t client_id_len;
void *vendor_specific;
size_t vendor_specific_len;
char *timezone;
uint8_t sixrd_ipv4masklen;
uint8_t sixrd_prefixlen;
struct in6_addr sixrd_prefix;
struct in_addr *sixrd_br_addresses;
size_t sixrd_n_br_addresses;
LIST_HEAD(struct sd_dhcp_raw_option, private_options);
};
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t client_id_len);

View file

@ -1,257 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include "nm-sd-adapt-core.h"
#include <errno.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <string.h>
#include <linux/filter.h>
#include <linux/if_infiniband.h>
#include <linux/if_packet.h>
#include "dhcp-internal.h"
#include "fd-util.h"
#include "socket-util.h"
#include "unaligned.h"
static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
uint32_t xid,
const uint8_t *bcast_addr,
size_t bcast_addr_len,
const struct ether_addr *eth_mac,
uint16_t arp_type, uint8_t dhcp_hlen,
uint16_t port) {
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, port, 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_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_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 */
/* We only support MAC address length to be either 0 or 6 (ETH_ALEN). Optionally
* compare chaddr for ETH_ALEN bytes. */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETH_ALEN, 0, 8), /* A (the MAC address length) == ETH_ALEN ? */
BPF_STMT(BPF_LDX + BPF_IMM, unaligned_read_be32(&eth_mac->ether_addr_octet[0])), /* X <- 4 bytes of client's MAC */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), /* A == X ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LDX + BPF_IMM, unaligned_read_be16(&eth_mac->ether_addr_octet[4])), /* X <- remainder of client's MAC */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_X, 0, 1, 0), /* A == X ? */
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, UINT32_MAX), /* accept */
};
struct sock_fprog fprog = {
.len = ELEMENTSOF(filter),
.filter = filter
};
_cleanup_close_ int s = -1;
int r;
assert(ifindex > 0);
assert(link);
s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (s < 0)
return -errno;
r = setsockopt_int(s, SOL_PACKET, PACKET_AUXDATA, true);
if (r < 0)
return r;
r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, sizeof(fprog));
if (r < 0)
return -errno;
link->ll = (struct sockaddr_ll) {
.sll_family = AF_PACKET,
.sll_protocol = htobe16(ETH_P_IP),
.sll_ifindex = ifindex,
.sll_hatype = htobe16(arp_type),
.sll_halen = bcast_addr_len,
};
memcpy(link->ll.sll_addr, bcast_addr, bcast_addr_len); /* We may overflow link->ll. link->ll_buffer ensures we have enough space. */
r = bind(s, &link->sa, SOCKADDR_LL_LEN(link->ll));
if (r < 0)
return -errno;
return TAKE_FD(s);
}
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,
const uint8_t *bcast_addr,
size_t bcast_addr_len,
uint16_t arp_type,
uint16_t port) {
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 *default_bcast_addr;
size_t expected_bcast_addr_len;
uint8_t dhcp_hlen = 0;
if (arp_type == ARPHRD_ETHER) {
assert_return(mac_addr_len == ETH_ALEN, -EINVAL);
memcpy(&eth_mac, mac_addr, ETH_ALEN);
dhcp_hlen = ETH_ALEN;
default_bcast_addr = eth_bcast;
expected_bcast_addr_len = ETH_ALEN;
} else if (arp_type == ARPHRD_INFINIBAND) {
default_bcast_addr = ib_bcast;
expected_bcast_addr_len = INFINIBAND_ALEN;
} else
return -EINVAL;
if (bcast_addr && bcast_addr_len > 0)
assert_return(bcast_addr_len == expected_bcast_addr_len, -EINVAL);
else {
bcast_addr = default_bcast_addr;
bcast_addr_len = expected_bcast_addr_len;
}
return _bind_raw_socket(ifindex, link, xid, bcast_addr, bcast_addr_len,
&eth_mac, arp_type, dhcp_hlen, port);
}
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type) {
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;
s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (s < 0)
return -errno;
if (ip_service_type >= 0)
r = setsockopt_int(s, IPPROTO_IP, IP_TOS, ip_service_type);
else
r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
if (r < 0)
return r;
r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
if (r < 0)
return r;
if (ifindex > 0) {
r = socket_bind_to_ifindex(s, ifindex);
if (r < 0)
return r;
}
if (port == DHCP_PORT_SERVER) {
r = setsockopt_int(s, SOL_SOCKET, SO_BROADCAST, true);
if (r < 0)
return r;
if (address == INADDR_ANY) {
/* IP_PKTINFO filter should not be applied when packets are
allowed to enter/leave through the interface other than
DHCP server sits on(BindToInterface option). */
r = setsockopt_int(s, IPPROTO_IP, IP_PKTINFO, true);
if (r < 0)
return r;
}
} else {
r = setsockopt_int(s, IPPROTO_IP, IP_FREEBIND, true);
if (r < 0)
return r;
}
if (bind(s, &src.sa, sizeof(src.in)) < 0)
return -errno;
return TAKE_FD(s);
}
int dhcp_network_send_raw_socket(
int s,
const union sockaddr_union *link,
const void *packet,
size_t len) {
/* Do not add assert(s >= 0) here, as this is called in fuzz-dhcp-server, and in that case this
* function should fail with negative errno. */
assert(link);
assert(packet);
assert(len > 0);
if (sendto(s, packet, len, 0, &link->sa, SOCKADDR_LL_LEN(link->ll)) < 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,
};
assert(s >= 0);
assert(packet);
assert(len > 0);
if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)) < 0)
return -errno;
return 0;
}

View file

@ -1,443 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include "nm-sd-adapt-core.h"
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include "alloc-util.h"
#include "dhcp-internal.h"
#include "dhcp-server-internal.h"
#include "memory-util.h"
#include "strv.h"
#include "utf8.h"
/* Append type-length value structure to the options buffer */
static int dhcp_option_append_tlv(uint8_t options[], size_t size, size_t *offset, uint8_t code, size_t optlen, const void *optval) {
assert(options);
assert(size > 0);
assert(offset);
assert(optlen <= UINT8_MAX);
assert(*offset < size);
if (*offset + 2 + optlen > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = optlen;
memcpy_safe(&options[*offset + 2], optval, optlen);
*offset += 2 + optlen;
return 0;
}
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(size > 0);
assert(offset);
int r;
if (code != SD_DHCP_OPTION_END)
/* always make sure there is space for an END option */
size--;
switch (code) {
case SD_DHCP_OPTION_PAD:
case SD_DHCP_OPTION_END:
if (*offset + 1 > size)
return -ENOBUFS;
options[*offset] = code;
*offset += 1;
break;
case SD_DHCP_OPTION_USER_CLASS: {
size_t total = 0;
if (strv_isempty((char **) optval))
return -EINVAL;
STRV_FOREACH(s, (char **) optval) {
size_t len = strlen(*s);
if (len > 255 || len == 0)
return -EINVAL;
total += 1 + len;
}
if (*offset + 2 + total > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = total;
*offset += 2;
STRV_FOREACH(s, (char **) optval) {
size_t len = strlen(*s);
options[*offset] = len;
memcpy(&options[*offset + 1], *s, len);
*offset += 1 + len;
}
break;
}
case SD_DHCP_OPTION_SIP_SERVER:
if (*offset + 3 + optlen > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = optlen + 1;
options[*offset + 2] = 1;
memcpy_safe(&options[*offset + 3], optval, optlen);
*offset += 3 + optlen;
break;
case SD_DHCP_OPTION_VENDOR_SPECIFIC: {
OrderedSet *s = (OrderedSet *) optval;
struct sd_dhcp_option *p;
size_t l = 0;
ORDERED_SET_FOREACH(p, s)
l += p->length + 2;
if (*offset + l + 2 > size)
return -ENOBUFS;
options[*offset] = code;
options[*offset + 1] = l;
*offset += 2;
ORDERED_SET_FOREACH(p, s) {
r = dhcp_option_append_tlv(options, size, offset, p->option, p->length, p->data);
if (r < 0)
return r;
}
break;
}
case SD_DHCP_OPTION_RELAY_AGENT_INFORMATION: {
#if 0 /* NM_IGNORED */
sd_dhcp_server *server = (sd_dhcp_server *) optval;
size_t current_offset = *offset + 2;
if (server->agent_circuit_id) {
r = dhcp_option_append_tlv(options, size, &current_offset, SD_DHCP_RELAY_AGENT_CIRCUIT_ID,
strlen(server->agent_circuit_id), server->agent_circuit_id);
if (r < 0)
return r;
}
if (server->agent_remote_id) {
r = dhcp_option_append_tlv(options, size, &current_offset, SD_DHCP_RELAY_AGENT_REMOTE_ID,
strlen(server->agent_remote_id), server->agent_remote_id);
if (r < 0)
return r;
}
options[*offset] = code;
options[*offset + 1] = current_offset - *offset - 2;
assert(current_offset - *offset - 2 <= UINT8_MAX);
*offset = current_offset;
break;
#endif /* NM_IGNORED */
g_return_val_if_reached(-EINVAL);
}
default:
return dhcp_option_append_tlv(options, size, offset, code, optlen, optval);
}
return 0;
}
static int option_length(uint8_t *options, size_t length, size_t offset) {
assert(options);
assert(offset < length);
if (IN_SET(options[offset], SD_DHCP_OPTION_PAD, SD_DHCP_OPTION_END))
return 1;
if (length < offset + 2)
return -ENOBUFS;
/* validating that buffer is long enough */
if (length < offset + 2 + options[offset + 1])
return -ENOBUFS;
return options[offset + 1] + 2;
}
int dhcp_option_find_option(uint8_t *options, size_t length, uint8_t code, size_t *ret_offset) {
int r;
assert(options);
assert(ret_offset);
for (size_t offset = 0; offset < length; offset += r) {
r = option_length(options, length, offset);
if (r < 0)
return r;
if (code == options[offset]) {
*ret_offset = offset;
return r;
}
}
return -ENOENT;
}
int dhcp_option_remove_option(uint8_t *options, size_t length, uint8_t option_code) {
int r;
size_t offset;
assert(options);
r = dhcp_option_find_option(options, length, option_code, &offset);
if (r < 0)
return r;
memmove(options + offset, options + offset + r, length - offset - r);
return length - r;
}
int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset,
uint8_t overload,
uint8_t code, size_t optlen, const void *optval) {
const bool use_file = overload & DHCP_OVERLOAD_FILE;
const bool use_sname = overload & DHCP_OVERLOAD_SNAME;
int r;
assert(message);
assert(offset);
/* If *offset is in range [0, size), we are writing to ->options,
* if *offset is in range [size, size + sizeof(message->file)) and use_file, we are writing to ->file,
* if *offset is in range [size + use_file*sizeof(message->file), size + use_file*sizeof(message->file) + sizeof(message->sname))
* and use_sname, we are writing to ->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 && (use_file || use_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, SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
*offset = size;
} else
return r;
}
if (use_file) {
size_t 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 && use_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->file, sizeof(message->file), &file_offset, SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
return r;
*offset = size + sizeof(message->file);
} else
return r;
}
}
if (use_sname) {
size_t sname_offset = *offset - size - use_file*sizeof(message->file);
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 + use_file*sizeof(message->file) + 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, char **error_message, dhcp_option_callback_t cb,
void *userdata) {
uint8_t code, len;
const uint8_t *option;
size_t offset = 0;
while (offset < buflen) {
code = options[offset ++];
switch (code) {
case SD_DHCP_OPTION_PAD:
continue;
case SD_DHCP_OPTION_END:
return 0;
}
if (buflen < offset + 1)
return -ENOBUFS;
len = options[offset ++];
if (buflen < offset + len)
return -EINVAL;
option = &options[offset];
switch (code) {
case SD_DHCP_OPTION_MESSAGE_TYPE:
if (len != 1)
return -EINVAL;
if (message_type)
*message_type = *option;
break;
case SD_DHCP_OPTION_ERROR_MESSAGE:
if (len == 0)
return -EINVAL;
if (error_message) {
_cleanup_free_ char *string = NULL;
/* Accept a trailing NUL byte */
if (memchr(option, 0, len - 1))
return -EINVAL;
string = memdup_suffix0((const char *) option, len);
if (!string)
return -ENOMEM;
if (!ascii_is_valid(string))
return -EINVAL;
free_and_replace(*error_message, string);
}
break;
case SD_DHCP_OPTION_OVERLOAD:
if (len != 1)
return -EINVAL;
if (overload)
*overload = *option;
break;
default:
if (cb)
cb(code, len, option, userdata);
break;
}
offset += len;
}
if (offset < buflen)
return -EINVAL;
return 0;
}
int dhcp_option_parse(DHCPMessage *message, size_t len, dhcp_option_callback_t cb, void *userdata, char **_error_message) {
_cleanup_free_ char *error_message = NULL;
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, &error_message, cb, userdata);
if (r < 0)
return r;
if (overload & DHCP_OVERLOAD_FILE) {
r = parse_options(message->file, sizeof(message->file), NULL, &message_type, &error_message, cb, userdata);
if (r < 0)
return r;
}
if (overload & DHCP_OVERLOAD_SNAME) {
r = parse_options(message->sname, sizeof(message->sname), NULL, &message_type, &error_message, cb, userdata);
if (r < 0)
return r;
}
if (message_type == 0)
return -ENOMSG;
if (_error_message && IN_SET(message_type, DHCP_NAK, DHCP_DECLINE))
*_error_message = TAKE_PTR(error_message);
return message_type;
}
static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
if (!i)
return NULL;
free(i->data);
return mfree(i);
}
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret) {
assert_return(ret, -EINVAL);
assert_return(length == 0 || data, -EINVAL);
_cleanup_free_ void *q = memdup(data, length);
if (!q)
return -ENOMEM;
sd_dhcp_option *p = new(sd_dhcp_option, 1);
if (!p)
return -ENOMEM;
*p = (sd_dhcp_option) {
.n_ref = 1,
.option = option,
.length = length,
.data = TAKE_PTR(q),
};
*ret = TAKE_PTR(p);
return 0;
}
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
dhcp_option_hash_ops,
void,
trivial_hash_func,
trivial_compare_func,
sd_dhcp_option,
sd_dhcp_option_unref);

View file

@ -1,196 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include "nm-sd-adapt-core.h"
#include <errno.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <string.h>
#include "dhcp-internal.h"
#include "dhcp-protocol.h"
#include "memory-util.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,
uint8_t hlen,
const uint8_t *chaddr,
size_t optlen,
size_t *optoffset) {
size_t offset = 0;
int r;
assert(IN_SET(op, BOOTREQUEST, BOOTREPLY));
assert(chaddr || hlen == 0);
message->op = op;
message->htype = arp_type;
/* RFC2131 section 4.1.1:
The client MUST include its hardware address in the chaddr field, if
necessary for delivery of DHCP reply messages.
RFC 4390 section 2.1:
A DHCP client, when working over an IPoIB interface, MUST follow the
following rules:
"htype" (hardware address type) MUST be 32 [ARPPARAM].
"hlen" (hardware address length) MUST be 0.
"chaddr" (client hardware address) field MUST be zeroed.
*/
message->hlen = (arp_type == ARPHRD_INFINIBAND) ? 0 : hlen;
memcpy_safe(message->chaddr, chaddr, message->hlen);
message->xid = htobe32(xid);
message->magic = htobe32(DHCP_MAGIC_COOKIE);
r = dhcp_option_append(message, optlen, &offset, 0,
SD_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, int ip_service_type) {
packet->ip.version = IPVERSION;
packet->ip.ihl = DHCP_IP_SIZE / 4;
packet->ip.tot_len = htobe16(len);
if (ip_service_type >= 0)
packet->ip.tos = ip_service_type;
else
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, uint16_t port) {
size_t hdrlen;
assert(packet);
/* IP */
if (packet->ip.version != IPVERSION)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: not IPv4");
if (packet->ip.ihl < 5)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: IPv4 IHL (%u words) invalid",
packet->ip.ihl);
hdrlen = packet->ip.ihl * 4;
if (hdrlen < 20)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: IPv4 IHL (%zu bytes) "
"smaller than minimum (20 bytes)",
hdrlen);
if (len < hdrlen)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: packet (%zu bytes) "
"smaller than expected (%zu) by IP header",
len, hdrlen);
/* UDP */
if (packet->ip.protocol != IPPROTO_UDP)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: not UDP");
if (len < hdrlen + be16toh(packet->udp.len))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: packet (%zu bytes) "
"smaller than expected (%zu) by UDP header",
len, hdrlen + be16toh(packet->udp.len));
if (be16toh(packet->udp.dest) != port)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: to port %u, which "
"is not the DHCP client port (%u)",
be16toh(packet->udp.dest), port);
/* 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))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: invalid IP checksum");
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))
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"ignoring packet: invalid UDP checksum");
}
return 0;
}

View file

@ -1,108 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/***
Copyright © 2013 Intel Corporation. All rights reserved.
***/
#include <netinet/ip.h>
#include <netinet/udp.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, /* [RFC2132] */
DHCP_OFFER = 2, /* [RFC2132] */
DHCP_REQUEST = 3, /* [RFC2132] */
DHCP_DECLINE = 4, /* [RFC2132] */
DHCP_ACK = 5, /* [RFC2132] */
DHCP_NAK = 6, /* [RFC2132] */
DHCP_RELEASE = 7, /* [RFC2132] */
DHCP_INFORM = 8, /* [RFC2132] */
DHCP_FORCERENEW = 9, /* [RFC3203] */
DHCPLEASEQUERY = 10, /* [RFC4388] */
DHCPLEASEUNASSIGNED = 11, /* [RFC4388] */
DHCPLEASEUNKNOWN = 12, /* [RFC4388] */
DHCPLEASEACTIVE = 13, /* [RFC4388] */
DHCPBULKLEASEQUERY = 14, /* [RFC6926] */
DHCPLEASEQUERYDONE = 15, /* [RFC6926] */
DHCPACTIVELEASEQUERY = 16, /* [RFC7724] */
DHCPLEASEQUERYSTATUS = 17, /* [RFC7724] */
DHCPTLS = 18, /* [RFC7724] */
};
enum {
DHCP_OVERLOAD_FILE = 1,
DHCP_OVERLOAD_SNAME = 2,
};
#define DHCP_MAX_FQDN_LENGTH 255
enum {
DHCP_FQDN_FLAG_S = (1 << 0),
DHCP_FQDN_FLAG_O = (1 << 1),
DHCP_FQDN_FLAG_E = (1 << 2),
DHCP_FQDN_FLAG_N = (1 << 3),
};

View file

@ -1,243 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "nm-sd-adapt-core.h"
#include <arpa/inet.h>
#include <linux/if.h>
#include <netinet/ether.h>
#include "sd-ndisc.h"
#include "alloc-util.h"
#include "dhcp-lease-internal.h"
#include "extract-word.h"
#include "hexdecoct.h"
#include "log.h"
#include "network-internal.h"
#include "parse-util.h"
size_t serialize_in_addrs(FILE *f,
const struct in_addr *addresses,
size_t size,
bool *with_leading_space,
bool (*predicate)(const struct in_addr *addr)) {
assert(f);
assert(addresses);
size_t count = 0;
bool _space = false;
if (!with_leading_space)
with_leading_space = &_space;
for (size_t i = 0; i < size; i++) {
char sbuf[INET_ADDRSTRLEN];
if (predicate && !predicate(&addresses[i]))
continue;
if (*with_leading_space)
fputc(' ', f);
fputs(inet_ntop(AF_INET, &addresses[i], sbuf, sizeof(sbuf)), f);
count++;
*with_leading_space = true;
}
return count;
}
int deserialize_in_addrs(struct in_addr **ret, const char *string) {
_cleanup_free_ struct in_addr *addresses = NULL;
int size = 0;
assert(ret);
assert(string);
for (;;) {
_cleanup_free_ char *word = NULL;
struct in_addr *new_addresses;
int r;
r = extract_first_word(&string, &word, NULL, 0);
if (r < 0)
return r;
if (r == 0)
break;
new_addresses = reallocarray(addresses, size + 1, sizeof(struct in_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
r = inet_pton(AF_INET, word, &(addresses[size]));
if (r <= 0)
continue;
size++;
}
*ret = size > 0 ? TAKE_PTR(addresses) : NULL;
return size;
}
void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, size_t size, bool *with_leading_space) {
assert(f);
assert(addresses);
assert(size);
bool _space = false;
if (!with_leading_space)
with_leading_space = &_space;
for (size_t i = 0; i < size; i++) {
char buffer[INET6_ADDRSTRLEN];
if (*with_leading_space)
fputc(' ', f);
fputs(inet_ntop(AF_INET6, addresses+i, buffer, sizeof(buffer)), f);
*with_leading_space = true;
}
}
int deserialize_in6_addrs(struct in6_addr **ret, const char *string) {
_cleanup_free_ struct in6_addr *addresses = NULL;
int size = 0;
assert(ret);
assert(string);
for (;;) {
_cleanup_free_ char *word = NULL;
struct in6_addr *new_addresses;
int r;
r = extract_first_word(&string, &word, NULL, 0);
if (r < 0)
return r;
if (r == 0)
break;
new_addresses = reallocarray(addresses, size + 1, sizeof(struct in6_addr));
if (!new_addresses)
return -ENOMEM;
else
addresses = new_addresses;
r = inet_pton(AF_INET6, word, &(addresses[size]));
if (r <= 0)
continue;
size++;
}
*ret = TAKE_PTR(addresses);
return size;
}
void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size) {
assert(f);
assert(key);
assert(routes);
assert(size);
fprintf(f, "%s=", key);
for (size_t i = 0; i < size; i++) {
char sbuf[INET_ADDRSTRLEN];
struct in_addr dest, gw;
uint8_t length;
assert_se(sd_dhcp_route_get_destination(routes[i], &dest) >= 0);
assert_se(sd_dhcp_route_get_gateway(routes[i], &gw) >= 0);
assert_se(sd_dhcp_route_get_destination_prefix_length(routes[i], &length) >= 0);
fprintf(f, "%s/%" PRIu8, inet_ntop(AF_INET, &dest, sbuf, sizeof sbuf), length);
fprintf(f, ",%s%s", inet_ntop(AF_INET, &gw, sbuf, sizeof sbuf), i < size - 1 ? " ": "");
}
fputs("\n", f);
}
int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, const char *string) {
_cleanup_free_ struct sd_dhcp_route *routes = NULL;
size_t size = 0;
assert(ret);
assert(ret_size);
assert(string);
/* WORD FORMAT: dst_ip/dst_prefixlen,gw_ip */
for (;;) {
_cleanup_free_ char *word = NULL;
char *tok, *tok_end;
unsigned n;
int r;
r = extract_first_word(&string, &word, NULL, 0);
if (r < 0)
return r;
if (r == 0)
break;
if (!GREEDY_REALLOC(routes, size + 1))
return -ENOMEM;
tok = word;
/* 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 = TAKE_PTR(routes);
return 0;
}
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size) {
_cleanup_free_ char *hex_buf = NULL;
assert(f);
assert(key);
assert(data);
hex_buf = hexmem(data, size);
if (!hex_buf)
return -ENOMEM;
fprintf(f, "%s=%s\n", key, hex_buf);
return 0;
}

View file

@ -1,31 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include <stdbool.h>
#include <stdio.h>
#include "sd-dhcp-lease.h"
size_t serialize_in_addrs(FILE *f,
const struct in_addr *addresses,
size_t size,
bool *with_leading_space,
bool (*predicate)(const struct in_addr *addr));
int deserialize_in_addrs(struct in_addr **addresses, const char *string);
void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses,
size_t size,
bool *with_leading_space);
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;
struct sd_dhcp_lease;
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, const char *string);
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,345 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#ifndef foosddhcpclienthfoo
#define foosddhcpclienthfoo
/***
Copyright © 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 <inttypes.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <stdbool.h>
#include "sd-dhcp-lease.h"
#include "sd-dhcp-option.h"
#include "sd-event.h"
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
enum {
SD_DHCP_CLIENT_EVENT_STOP = 0,
SD_DHCP_CLIENT_EVENT_IP_ACQUIRE = 1,
SD_DHCP_CLIENT_EVENT_IP_CHANGE = 2,
SD_DHCP_CLIENT_EVENT_EXPIRED = 3,
SD_DHCP_CLIENT_EVENT_RENEW = 4,
SD_DHCP_CLIENT_EVENT_SELECTING = 5,
SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE = 6, /* Sent when we have not received a reply after the first few attempts.
* The client may want to start acquiring link-local addresses. */
};
/* https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options */
enum {
SD_DHCP_OPTION_PAD = 0, /* [RFC2132] */
SD_DHCP_OPTION_SUBNET_MASK = 1, /* [RFC2132] */
SD_DHCP_OPTION_TIME_OFFSET = 2, /* [RFC2132], deprecated by 100 and 101 */
SD_DHCP_OPTION_ROUTER = 3, /* [RFC2132] */
SD_DHCP_OPTION_TIME_SERVER = 4, /* [RFC2132] */
SD_DHCP_OPTION_NAME_SERVER = 5, /* [RFC2132] */
SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6, /* [RFC2132] */
SD_DHCP_OPTION_LOG_SERVER = 7, /* [RFC2132] */
SD_DHCP_OPTION_QUOTES_SERVER = 8, /* [RFC2132] */
SD_DHCP_OPTION_LPR_SERVER = 9, /* [RFC2132] */
SD_DHCP_OPTION_IMPRESS_SERVER = 10, /* [RFC2132] */
SD_DHCP_OPTION_RLP_SERVER = 11, /* [RFC2132] */
SD_DHCP_OPTION_HOST_NAME = 12, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_FILE_SIZE = 13, /* [RFC2132] */
SD_DHCP_OPTION_MERIT_DUMP_FILE = 14, /* [RFC2132] */
SD_DHCP_OPTION_DOMAIN_NAME = 15, /* [RFC2132] */
SD_DHCP_OPTION_SWAP_SERVER = 16, /* [RFC2132] */
SD_DHCP_OPTION_ROOT_PATH = 17, /* [RFC2132] */
SD_DHCP_OPTION_EXTENSION_FILE = 18, /* [RFC2132] */
SD_DHCP_OPTION_FORWARD = 19, /* [RFC2132] */
SD_DHCP_OPTION_SOURCE_ROUTE = 20, /* [RFC2132] */
SD_DHCP_OPTION_POLICY_FILTER = 21, /* [RFC2132] */
SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY = 22, /* [RFC2132] */
SD_DHCP_OPTION_DEFAULT_IP_TTL = 23, /* [RFC2132] */
SD_DHCP_OPTION_MTU_TIMEOUT = 24, /* [RFC2132] */
SD_DHCP_OPTION_MTU_PLATEAU = 25, /* [RFC2132] */
SD_DHCP_OPTION_MTU_INTERFACE = 26, /* [RFC2132] */
SD_DHCP_OPTION_MTU_SUBNET = 27, /* [RFC2132] */
SD_DHCP_OPTION_BROADCAST = 28, /* [RFC2132] */
SD_DHCP_OPTION_MASK_DISCOVERY = 29, /* [RFC2132] */
SD_DHCP_OPTION_MASK_SUPPLIER = 30, /* [RFC2132] */
SD_DHCP_OPTION_ROUTER_DISCOVERY = 31, /* [RFC2132] */
SD_DHCP_OPTION_ROUTER_REQUEST = 32, /* [RFC2132] */
SD_DHCP_OPTION_STATIC_ROUTE = 33, /* [RFC2132] */
SD_DHCP_OPTION_TRAILERS = 34, /* [RFC2132] */
SD_DHCP_OPTION_ARP_TIMEOUT = 35, /* [RFC2132] */
SD_DHCP_OPTION_ETHERNET = 36, /* [RFC2132] */
SD_DHCP_OPTION_DEFAULT_TCP_TTL = 37, /* [RFC2132] */
SD_DHCP_OPTION_KEEPALIVE_TIME = 38, /* [RFC2132] */
SD_DHCP_OPTION_KEEPALIVE_DATA = 39, /* [RFC2132] */
SD_DHCP_OPTION_NIS_DOMAIN = 40, /* [RFC2132] */
SD_DHCP_OPTION_NIS_SERVER = 41, /* [RFC2132] */
SD_DHCP_OPTION_NTP_SERVER = 42, /* [RFC2132] */
SD_DHCP_OPTION_VENDOR_SPECIFIC = 43, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_NAME_SERVER = 44, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_DIST_SERVER = 45, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_NODE_TYPE = 46, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_SCOPE = 47, /* [RFC2132] */
SD_DHCP_OPTION_X_WINDOW_FONT = 48, /* [RFC2132] */
SD_DHCP_OPTION_X_WINDOW_MANAGER = 49, /* [RFC2132] */
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, /* [RFC2132] */
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, /* [RFC2132] */
SD_DHCP_OPTION_OVERLOAD = 52, /* [RFC2132] */
SD_DHCP_OPTION_MESSAGE_TYPE = 53, /* [RFC2132] */
SD_DHCP_OPTION_SERVER_IDENTIFIER = 54, /* [RFC2132] */
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55, /* [RFC2132] */
SD_DHCP_OPTION_ERROR_MESSAGE = 56, /* [RFC2132] */
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57, /* [RFC2132] */
SD_DHCP_OPTION_RENEWAL_TIME = 58, /* [RFC2132] */
SD_DHCP_OPTION_REBINDING_TIME = 59, /* [RFC2132] */
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, /* [RFC2132] */
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, /* [RFC2132] */
SD_DHCP_OPTION_NETWARE_IP_DOMAIN = 62, /* [RFC2242] */
SD_DHCP_OPTION_NETWARE_IP_OPTION = 63, /* [RFC2242] */
SD_DHCP_OPTION_NIS_DOMAIN_NAME = 64, /* [RFC2132] */
SD_DHCP_OPTION_NIS_SERVER_ADDR = 65, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_SERVER_NAME = 66, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_FILENAME = 67, /* [RFC2132] */
SD_DHCP_OPTION_HOME_AGENT_ADDRESSES = 68, /* [RFC2132] */
SD_DHCP_OPTION_SMTP_SERVER = 69, /* [RFC2132] */
SD_DHCP_OPTION_POP3_SERVER = 70, /* [RFC2132] */
SD_DHCP_OPTION_NNTP_SERVER = 71, /* [RFC2132] */
SD_DHCP_OPTION_WWW_SERVER = 72, /* [RFC2132] */
SD_DHCP_OPTION_FINGER_SERVER = 73, /* [RFC2132] */
SD_DHCP_OPTION_IRC_SERVER = 74, /* [RFC2132] */
SD_DHCP_OPTION_STREETTALK_SERVER = 75, /* [RFC2132] */
SD_DHCP_OPTION_STDA_SERVER = 76, /* [RFC2132] */
SD_DHCP_OPTION_USER_CLASS = 77, /* [RFC3004] */
SD_DHCP_OPTION_DIRECTORY_AGENT = 78, /* [RFC2610] */
SD_DHCP_OPTION_SERVICE_SCOPE = 79, /* [RFC2610] */
SD_DHCP_OPTION_RAPID_COMMIT = 80, /* [RFC4039] */
SD_DHCP_OPTION_FQDN = 81, /* [RFC4702] */
SD_DHCP_OPTION_RELAY_AGENT_INFORMATION = 82, /* [RFC3046] */
SD_DHCP_OPTION_ISNS = 83, /* [RFC4174] */
/* option code 84 is unassigned [RFC3679] */
SD_DHCP_OPTION_NDS_SERVER = 85, /* [RFC2241] */
SD_DHCP_OPTION_NDS_TREE_NAME = 86, /* [RFC2241] */
SD_DHCP_OPTION_NDS_CONTEXT = 87, /* [RFC2241] */
SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAM = 88, /* [RFC4280] */
SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS = 89, /* [RFC4280] */
SD_DHCP_OPTION_AUTHENTICATION = 90, /* [RFC3118] */
SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME = 91, /* [RFC4388] */
SD_DHCP_OPTION_ASSOCIATED_IP = 92, /* [RFC4388] */
SD_DHCP_OPTION_CLIENT_SYSTEM = 93, /* [RFC4578] */
SD_DHCP_OPTION_CLIENT_NDI = 94, /* [RFC4578] */
SD_DHCP_OPTION_LDAP = 95, /* [RFC3679] */
/* option code 96 is unassigned [RFC3679] */
SD_DHCP_OPTION_UUID = 97, /* [RFC4578] */
SD_DHCP_OPTION_USER_AUTHENTICATION = 98, /* [RFC2485] */
SD_DHCP_OPTION_GEOCONF_CIVIC = 99, /* [RFC4776] */
SD_DHCP_OPTION_POSIX_TIMEZONE = 100, /* [RFC4833] */
SD_DHCP_OPTION_TZDB_TIMEZONE = 101, /* [RFC4833] */
/* option codes 102-107 are unassigned [RFC3679] */
SD_DHCP_OPTION_IPV6_ONLY_PREFERRED = 108, /* [RFC8925] */
SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS = 109, /* [RFC8539] */
/* option codes 110-111 are unassigned [RFC3679] */
SD_DHCP_OPTION_NETINFO_ADDRESS = 112, /* [RFC3679] */
SD_DHCP_OPTION_NETINFO_TAG = 113, /* [RFC3679] */
SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL = 114, /* [RFC8910] */
/* option code 115 is unassigned [RFC3679] */
SD_DHCP_OPTION_AUTO_CONFIG = 116, /* [RFC2563] */
SD_DHCP_OPTION_NAME_SERVICE_SEARCH = 117, /* [RFC2937] */
SD_DHCP_OPTION_SUBNET_SELECTION = 118, /* [RFC3011] */
SD_DHCP_OPTION_DOMAIN_SEARCH = 119, /* [RFC3397] */
SD_DHCP_OPTION_SIP_SERVER = 120, /* [RFC3361] */
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, /* [RFC3442] */
SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION = 122, /* [RFC3495] */
SD_DHCP_OPTION_GEOCONF = 123, /* [RFC6225] */
SD_DHCP_OPTION_VENDOR_CLASS = 124, /* [RFC3925] */
SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION = 125, /* [RFC3925] */
/* option codes 126-127 are unassigned [RFC3679] */
/* option codes 128-135 are assigned to use by PXE, but they are vendor specific [RFC4578] */
SD_DHCP_OPTION_PANA_AGENT = 136, /* [RFC5192] */
SD_DHCP_OPTION_LOST_SERVER_FQDN = 137, /* [RFC5223] */
SD_DHCP_OPTION_CAPWAP_AC_ADDRESS = 138, /* [RFC5417] */
SD_DHCP_OPTION_MOS_ADDRESS = 139, /* [RFC5678] */
SD_DHCP_OPTION_MOS_FQDN = 140, /* [RFC5678] */
SD_DHCP_OPTION_SIP_SERVICE_DOMAINS = 141, /* [RFC6011] */
SD_DHCP_OPTION_ANDSF_ADDRESS = 142, /* [RFC6153] */
SD_DHCP_OPTION_SZTP_REDIRECT = 143, /* [RFC8572] */
SD_DHCP_OPTION_GEOLOC = 144, /* [RFC6225] */
SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE = 145, /* [RFC6704] */
SD_DHCP_OPTION_RDNSS_SELECTION = 146, /* [RFC6731] */
SD_DHCP_OPTION_DOTS_RI = 147, /* [RFC8973] */
SD_DHCP_OPTION_DOTS_ADDRESS = 148, /* [RFC8973] */
/* option code 149 is unassigned [RFC3942] */
SD_DHCP_OPTION_TFTP_SERVER_ADDRESS = 150, /* [RFC5859] */
SD_DHCP_OPTION_STATUS_CODE = 151, /* [RFC6926] */
SD_DHCP_OPTION_BASE_TIME = 152, /* [RFC6926] */
SD_DHCP_OPTION_START_TIME_OF_STATE = 153, /* [RFC6926] */
SD_DHCP_OPTION_QUERY_START_TIME = 154, /* [RFC6926] */
SD_DHCP_OPTION_QUERY_END_TIME = 155, /* [RFC6926] */
SD_DHCP_OPTION_DHCP_STATE = 156, /* [RFC6926] */
SD_DHCP_OPTION_DATA_SOURCE = 157, /* [RFC6926] */
SD_DHCP_OPTION_PCP_SERVER = 158, /* [RFC7291] */
SD_DHCP_OPTION_PORT_PARAMS = 159, /* [RFC7618] */
/* option code 160 is unassigned [RFC7710][RFC8910] */
SD_DHCP_OPTION_MUD_URL = 161, /* [RFC8520] */
/* option codes 162-174 are unassigned [RFC3942] */
/* option codes 175-177 are temporary assigned. */
/* option codes 178-207 are unassigned [RFC3942] */
SD_DHCP_OPTION_PXELINUX_MAGIC = 208, /* [RFC5071] Deprecated */
SD_DHCP_OPTION_CONFIGURATION_FILE = 209, /* [RFC5071] */
SD_DHCP_OPTION_PATH_PREFIX = 210, /* [RFC5071] */
SD_DHCP_OPTION_REBOOT_TIME = 211, /* [RFC5071] */
SD_DHCP_OPTION_6RD = 212, /* [RFC5969] */
SD_DHCP_OPTION_ACCESS_DOMAIN = 213, /* [RFC5986] */
/* option codes 214-219 are unassigned */
SD_DHCP_OPTION_SUBNET_ALLOCATION = 220, /* [RFC6656] */
SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION = 221, /* [RFC6607] */
/* option codes 222-223 are unassigned [RFC3942] */
/* option codes 224-254 are reserved for private use */
SD_DHCP_OPTION_PRIVATE_BASE = 224,
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, /* [RFC7844] */
SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252, /* [RFC7844] */
SD_DHCP_OPTION_PRIVATE_LAST = 254,
SD_DHCP_OPTION_END = 255, /* [RFC2132] */
};
/* Suboptions for SD_DHCP_OPTION_RELAY_AGENT_INFORMATION option */
enum {
SD_DHCP_RELAY_AGENT_CIRCUIT_ID = 1,
SD_DHCP_RELAY_AGENT_REMOTE_ID = 2,
};
typedef struct sd_dhcp_client sd_dhcp_client;
typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
int sd_dhcp_client_set_callback(
sd_dhcp_client *client,
sd_dhcp_client_callback_t cb,
void *userdata);
int sd_dhcp_client_set_request_option(
sd_dhcp_client *client,
uint8_t option);
int sd_dhcp_client_set_request_address(
sd_dhcp_client *client,
const struct in_addr *last_address);
int sd_dhcp_client_set_request_broadcast(
sd_dhcp_client *client,
int broadcast);
int sd_dhcp_client_set_ifindex(
sd_dhcp_client *client,
int interface_index);
int sd_dhcp_client_set_ifname(
sd_dhcp_client *client,
const char *interface_name);
int sd_dhcp_client_get_ifname(sd_dhcp_client *client, const char **ret);
int sd_dhcp_client_set_mac(
sd_dhcp_client *client,
const uint8_t *addr,
const uint8_t *bcast_addr,
size_t addr_len,
uint16_t arp_type);
int sd_dhcp_client_set_client_id(
sd_dhcp_client *client,
uint8_t type,
const uint8_t *data,
size_t data_len);
int sd_dhcp_client_set_iaid_duid(
sd_dhcp_client *client,
bool iaid_set,
uint32_t iaid,
uint16_t duid_type,
const void *duid,
size_t duid_len);
int sd_dhcp_client_set_iaid_duid_llt(
sd_dhcp_client *client,
bool iaid_set,
uint32_t iaid,
uint64_t llt_time);
int sd_dhcp_client_set_duid(
sd_dhcp_client *client,
uint16_t duid_type,
const void *duid,
size_t duid_len);
int sd_dhcp_client_set_duid_llt(
sd_dhcp_client *client,
uint64_t llt_time);
int sd_dhcp_client_get_client_id(
sd_dhcp_client *client,
uint8_t *type,
const uint8_t **data,
size_t *data_len);
int sd_dhcp_client_set_mtu(
sd_dhcp_client *client,
uint32_t mtu);
int sd_dhcp_client_set_max_attempts(
sd_dhcp_client *client,
uint64_t attempt);
int sd_dhcp_client_set_client_port(
sd_dhcp_client *client,
uint16_t port);
int sd_dhcp_client_set_hostname(
sd_dhcp_client *client,
const char *hostname);
int sd_dhcp_client_set_vendor_class_identifier(
sd_dhcp_client *client,
const char *vci);
int sd_dhcp_client_set_mud_url(
sd_dhcp_client *client,
const char *mudurl);
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
char * const *user_class);
int sd_dhcp_client_get_lease(
sd_dhcp_client *client,
sd_dhcp_lease **ret);
int sd_dhcp_client_set_service_type(
sd_dhcp_client *client,
int type);
int sd_dhcp_client_set_fallback_lease_lifetime(
sd_dhcp_client *client,
uint32_t fallback_lease_lifetime);
int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v);
int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v);
int sd_dhcp_client_is_running(sd_dhcp_client *client);
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
int sd_dhcp_client_send_release(sd_dhcp_client *client);
int sd_dhcp_client_send_decline(sd_dhcp_client *client);
int sd_dhcp_client_send_renew(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
/* NOTE: anonymize parameter is used to initialize PRL memory with different
* options when using RFC7844 Anonymity Profiles */
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize);
int sd_dhcp_client_id_to_string(const void *data, size_t len, char **ret);
int sd_dhcp_client_attach_event(
sd_dhcp_client *client,
sd_event *event,
int64_t priority);
int sd_dhcp_client_detach_event(sd_dhcp_client *client);
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
_SD_END_DECLARATIONS;
#endif

View file

@ -1,91 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#ifndef foosddhcpleasehfoo
#define foosddhcpleasehfoo
/***
Copyright © 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 <inttypes.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
typedef struct sd_dhcp_lease sd_dhcp_lease;
typedef struct sd_dhcp_route sd_dhcp_route;
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
typedef enum sd_dhcp_lease_server_type_t {
SD_DHCP_LEASE_DNS,
SD_DHCP_LEASE_NTP,
SD_DHCP_LEASE_SIP,
SD_DHCP_LEASE_POP3,
SD_DHCP_LEASE_SMTP,
SD_DHCP_LEASE_LPR,
_SD_DHCP_LEASE_SERVER_TYPE_MAX,
_SD_DHCP_LEASE_SERVER_TYPE_INVALID = -EINVAL,
_SD_ENUM_FORCE_S64(DHCP_LEASE_SERVER_TYPE),
} sd_dhcp_lease_server_type_t;
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2);
int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_server_type_t what, const struct in_addr **addr);
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_static_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret);
int sd_dhcp_lease_get_classless_routes(sd_dhcp_lease *lease, sd_dhcp_route ***ret);
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
int sd_dhcp_lease_get_6rd(
sd_dhcp_lease *lease,
uint8_t *ret_ipv4masklen,
uint8_t *ret_prefixlen,
struct in6_addr *ret_prefix,
const struct in_addr **ret_br_addresses,
size_t *ret_n_br_addresses);
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination);
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length);
int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_lease, sd_dhcp_lease_unref);
_SD_END_DECLARATIONS;
#endif

View file

@ -1,38 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#ifndef foosddhcpoptionhfoo
#define foosddhcpoptionhfoo
/***
Copyright © 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 <inttypes.h>
#include <sys/types.h>
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
typedef struct sd_dhcp_option sd_dhcp_option;
int sd_dhcp_option_new(uint8_t option, const void *data, size_t length, sd_dhcp_option **ret);
sd_dhcp_option *sd_dhcp_option_ref(sd_dhcp_option *ra);
sd_dhcp_option *sd_dhcp_option_unref(sd_dhcp_option *ra);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_option, sd_dhcp_option_unref);
_SD_END_DECLARATIONS;
#endif