mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 00:10:07 +01:00
dhcp/systemd: drop dhcp4 client (and related files)
This code is now unused.
This commit is contained in:
parent
54119d4105
commit
6150a495c9
18 changed files with 0 additions and 5931 deletions
15
Makefile.am
15
Makefile.am
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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__)
|
||||
|
|
@ -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);
|
||||
|
|
@ -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(ð_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(ð_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(ð_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,
|
||||
ð_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;
|
||||
}
|
||||
|
|
@ -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, ¤t_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, ¤t_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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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),
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Reference in a new issue