Commit 39f8b7b5 authored by Thomas Haller's avatar Thomas Haller
Browse files

dhcp: update systemd DHCP code

This is a direct dump from systemd git on 2015-03-02, git commit
4d1d2f0858bb2fa6c.  Only relevant files were included.

    SYSTEMD_DIR=../systemd
    COMMIT=4d1d2f0858bb2fa6c45f0a7b3d427e657c0d4f67

    mkdir -p ./src/dhcp-manager/systemd-dhcp/src/libsystemd/sd-id128/

    (
       cd "$SYSTEMD_DIR"
       git checkout "$COMMIT"
       git reset --hard
       git clean -fdx
    )
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd/sd-id128/sd-id128.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd/sd-id128/sd-id128.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-identifier.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-identifier.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-identifier.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-identifier.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-lease-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-network.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-option.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-packet.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-packet.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp-protocol.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-lease-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-lease-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-network.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-network.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-option.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-option.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/dhcp6-protocol.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/dhcp6-protocol.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/network-internal.h ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/network-internal.h
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-client.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp-lease.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-client.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c
    /bin/cp "$SYSTEMD_DIR"/src/libsystemd-network/sd-dhcp6-lease.c ./src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-lease.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/async.h ./src/dhcp-manager/systemd-dhcp/src/shared/async.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.c ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/fileio.h ./src/dhcp-manager/systemd-dhcp/src/shared/fileio.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/list.h ./src/dhcp-manager/systemd-dhcp/src/shared/list.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/log.h ./src/dhcp-manager/systemd-dhcp/src/shared/log.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/macro.h ./src/dhcp-manager/systemd-dhcp/src/shared/macro.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/path-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/path-util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/path-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/path-util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/refcnt.h ./src/dhcp-manager/systemd-dhcp/src/shared/refcnt.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.c ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/siphash24.h ./src/dhcp-manager/systemd-dhcp/src/shared/siphash24.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/socket-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/socket-util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/sparse-endian.h ./src/dhcp-manager/systemd-dhcp/src/shared/sparse-endian.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/strv.c ./src/dhcp-manager/systemd-dhcp/src/shared/strv.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/strv.h ./src/dhcp-manager/systemd-dhcp/src/shared/strv.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/time-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/time-util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.c ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/utf8.h ./src/dhcp-manager/systemd-dhcp/src/shared/utf8.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/util.c ./src/dhcp-manager/systemd-dhcp/src/shared/util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/util.h ./src/dhcp-manager/systemd-dhcp/src/shared/util.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/unaligned.h ./src/dhcp-manager/systemd-dhcp/src/shared/unaligned.h
    /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.c ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.c
    /bin/cp "$SYSTEMD_DIR"/src/shared/in-addr-util.h ./src/dhcp-manager/systemd-dhcp/src/shared/in-addr-util.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/_sd-common.h ./src/dhcp-manager/systemd-dhcp/src/systemd/_sd-common.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-client.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp-lease.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-client.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-client.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-dhcp6-lease.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-dhcp6-lease.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-event.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-event.h
    /bin/cp "$SYSTEMD_DIR"/src/systemd/sd-id128.h ./src/dhcp-manager/systemd-dhcp/src/systemd/sd-id128.h
parent e2e4637c
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright (C) 2015 Tom Gundersen <teg@jklmen>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "sd-id128.h"
#include "libudev.h"
#include "udev-util.h"
#include "virt.h"
#include "sparse-endian.h"
#include "siphash24.h"
#include "dhcp6-protocol.h"
#include "dhcp-identifier.h"
#include "network-internal.h"
#define SYSTEMD_PEN 43793
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
sd_id128_t machine_id;
int r;
assert(duid);
assert(len);
r = sd_id128_get_machine(&machine_id);
if (r < 0)
return r;
duid->type = htobe16(DHCP6_DUID_EN);
duid->en.pen = htobe32(SYSTEMD_PEN);
*len = sizeof(duid->type) + sizeof(duid->en);
/* a bit of snake-oil perhaps, but no need to expose the machine-id
directly */
siphash24(duid->en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
return 0;
}
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, uint32_t *_id) {
/* name is a pointer to memory in the udev_device struct, so must
have the same scope */
_cleanup_udev_device_unref_ struct udev_device *device = NULL;
const char *name = NULL;
uint64_t id;
if (detect_container(NULL) <= 0) {
/* not in a container, udev will be around */
_cleanup_udev_unref_ struct udev *udev;
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
udev = udev_new();
if (!udev)
return -ENOMEM;
sprintf(ifindex_str, "n%d", ifindex);
device = udev_device_new_from_device_id(udev, ifindex_str);
if (device) {
if (udev_device_get_is_initialized(device) <= 0)
/* not yet ready */
return -EBUSY;
name = net_get_name(device);
}
}
if (name)
siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
else
/* fall back to MAC address if no predictable name available */
siphash24((uint8_t*)&id, mac, mac_len, HASH_KEY.bytes);
/* fold into 32 bits */
*_id = (id & 0xffffffff) ^ (id >> 32);
return 0;
}
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright (C) 2015 Tom Gundersen <teg@jklmen>
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "macro.h"
#include "sparse-endian.h"
#include "sd-id128.h"
/* RFC 3315 section 9.1:
* A DUID can be no more than 128 octets long (not including the type code).
*/
#define MAX_DUID_LEN 128
struct duid {
uint16_t type;
union {
struct {
/* DHCP6_DUID_LLT */
uint16_t htype;
uint32_t time;
uint8_t haddr[0];
} _packed_ llt;
struct {
/* DHCP6_DUID_EN */
uint32_t pen;
uint8_t id[8];
} _packed_ en;
struct {
/* DHCP6_DUID_LL */
int16_t htype;
uint8_t haddr[0];
} _packed_ ll;
struct {
/* DHCP6_DUID_UUID */
sd_id128_t uuid;
} _packed_ uuid;
struct {
uint8_t data[MAX_DUID_LEN];
} _packed_ raw;
};
} _packed_;
int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, uint32_t *_id);
......@@ -71,4 +71,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
#define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
#define log_dhcp_client(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
......@@ -18,7 +18,6 @@
***/
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/if_packet.h>
......@@ -26,7 +25,6 @@
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <unistd.h>
#include <linux/filter.h>
#include "socket-util.h"
......@@ -63,7 +61,7 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)), /* A <- DHCP header type */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0), /* header type == arp_type ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- mac address length */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)), /* A <- MAC address length */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), /* address length == dhcp_hlen ? */
BPF_STMT(BPF_RET + BPF_K, 0), /* ignore */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)), /* A <- client identifier */
......
......@@ -18,22 +18,14 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <sys/param.h>
#include "util.h"
#include "list.h"
#include "dhcp-protocol.h"
#include "dhcp-lease-internal.h"
#include "dhcp-internal.h"
#include "sd-dhcp-lease.h"
#include "sd-dhcp-client.h"
#define DHCP_CLIENT_MIN_OPTIONS_SIZE 312
......
......@@ -56,7 +56,7 @@ struct DHCP6IA {
typedef struct DHCP6IA DHCP6IA;
#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
#define log_dhcp6_client(p, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
int dhcp_network_icmp6_bind_router_solicitation(int index);
int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
......
......@@ -51,6 +51,8 @@ enum {
DHCP6_PORT_CLIENT = 546,
};
#define DHCP6_INF_TIMEOUT 1 * USEC_PER_SEC
#define DHCP6_INF_MAX_RT 120 * USEC_PER_SEC
#define DHCP6_SOL_MAX_DELAY 1 * USEC_PER_SEC
#define DHCP6_SOL_TIMEOUT 1 * USEC_PER_SEC
#define DHCP6_SOL_MAX_RT 120 * USEC_PER_SEC
......@@ -71,6 +73,7 @@ enum {
enum DHCP6State {
DHCP6_STATE_STOPPED = 0,
DHCP6_STATE_INFORMATION_REQUEST = 1,
DHCP6_STATE_SOLICITATION = 2,
DHCP6_STATE_REQUEST = 3,
DHCP6_STATE_BOUND = 4,
......
......@@ -22,11 +22,9 @@
#include <netinet/ether.h>
#include <linux/if.h>
#include <arpa/inet.h>
#include <fnmatch.h>
#include "strv.h"
#include "siphash24.h"
#include "libudev-private.h"
#include "dhcp-lease-internal.h"
#include "log.h"
#include "utf8.h"
......@@ -83,10 +81,10 @@ int net_get_unique_predictable_data(struct udev_device *device, uint8_t result[8
}
bool net_match_config(const struct ether_addr *match_mac,
const char *match_path,
const char *match_driver,
const char *match_type,
const char *match_name,
char * const *match_paths,
char * const *match_drivers,
char * const *match_types,
char * const *match_names,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel,
......@@ -99,37 +97,37 @@ bool net_match_config(const struct ether_addr *match_mac,
const char *dev_name) {
if (match_host && !condition_test(match_host))
return 0;
return false;
if (match_virt && !condition_test(match_virt))
return 0;
return false;
if (match_kernel && !condition_test(match_kernel))
return 0;
return false;
if (match_arch && !condition_test(match_arch))
return 0;
return false;
if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
return 0;
return false;
if (match_path && (!dev_path || fnmatch(match_path, dev_path, 0)))
return 0;
if (!strv_isempty(match_paths) &&
(!dev_path || !strv_fnmatch(match_paths, dev_path, 0)))
return false;
if (match_driver) {
if (dev_parent_driver && !streq(match_driver, dev_parent_driver))
return 0;
else if (!streq_ptr(match_driver, dev_driver))
return 0;
}
if (!strv_isempty(match_drivers) &&
(!dev_driver || !strv_fnmatch(match_drivers, dev_driver, 0)))
return false;
if (match_type && !streq_ptr(match_type, dev_type))
return 0;
if (!strv_isempty(match_types) &&
(!dev_type || !strv_fnmatch_or_empty(match_types, dev_type, 0)))
return false;
if (match_name && (!dev_name || fnmatch(match_name, dev_name, 0)))
return 0;
if (!strv_isempty(match_names) &&
(!dev_name || !strv_fnmatch_or_empty(match_names, dev_name, 0)))
return false;
return 1;
return true;
}
int config_parse_net_condition(const char *unit,
......@@ -212,6 +210,49 @@ int config_parse_ifname(const char *unit,
return 0;
}
int config_parse_ifnames(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char ***sv = data;
const char *word, *state;
size_t l;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
FOREACH_WORD(word, l, rvalue, state) {
char *n;
n = strndup(word, l);
if (!n)
return log_oom();
if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
r = strv_consume(sv, n);
if (r < 0)
return log_oom();
}
return 0;
}
int config_parse_ifalias(const char *unit,
const char *filename,
unsigned line,
......@@ -224,7 +265,7 @@ int config_parse_ifalias(const char *unit,
void *userdata) {
char **s = data;
char *n;
_cleanup_free_ char *n = NULL;
assert(filename);
assert(lvalue);
......@@ -238,17 +279,15 @@ int config_parse_ifalias(const char *unit,
if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
free(n);
return 0;
}
free(*s);
if (*n)
if (*n) {
*s = n;
else {
free(n);
n = NULL;
} else
*s = NULL;
}
return 0;
}
......@@ -392,10 +431,12 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route
fprintf(f, "%s=", key);
for (i = 0; i < size; i++)
fprintf(f, "%s/%" PRIu8 ",%s%s", inet_ntoa(routes[i].dst_addr),
routes[i].dst_prefixlen, inet_ntoa(routes[i].gw_addr),
for (i = 0; i < size; i++) {
fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr),
routes[i].dst_prefixlen);
fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr),
(i < (size - 1)) ? " ": "");
}
fputs("\n", f);
}
......
......@@ -21,18 +21,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <netinet/ether.h>
#include <netinet/in.h>
#include <stdbool.h>
#include "udev.h"
#include "condition.h"
bool net_match_config(const struct ether_addr *match_mac,
const char *match_path,
const char *match_driver,
const char *match_type,
const char *match_name,
char * const *match_path,
char * const *match_driver,
char * const *match_type,
char * const *match_name,
Condition *match_host,
Condition *match_virt,
Condition *match_kernel,
......@@ -56,6 +54,10 @@ int config_parse_ifname(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ifnames(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_ifalias(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
......
......@@ -24,21 +24,19 @@
#include <net/ethernet.h>
#include <net/if_arp.h>
#include <linux/if_infiniband.h>
#include <netinet/ether.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include "util.h"
#include "list.h"
#include "refcnt.h"
#include "async.h"
#include "dhcp-protocol.h"
#include "dhcp-internal.h"
#include "dhcp-lease-internal.h"
#include "dhcp-identifier.h"
#include "sd-dhcp-client.h"
#define MAX_CLIENT_ID_LEN 64 /* Arbitrary limit */
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
struct sd_dhcp_client {
......@@ -60,29 +58,31 @@ struct sd_dhcp_client {
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
size_t mac_addr_len;
uint16_t arp_type;
union {
struct {
uint8_t type; /* 0: Generic (non-LL) (RFC 2132) */
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ gen;
struct {
uint8_t type; /* 1: Ethernet Link-Layer (RFC 2132) */
uint8_t haddr[ETH_ALEN];
} _packed_ eth;
struct {
uint8_t type; /* 2 - 254: ARP/Link-Layer (RFC 2132) */
uint8_t haddr[0];
} _packed_ ll;
struct {
uint8_t type; /* 255: Node-specific (RFC 4361) */
uint8_t iaid[4];
uint8_t duid[MAX_CLIENT_ID_LEN - 4];
} _packed_ ns;
struct {
uint8_t type;
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ raw;
} client_id;
struct {
uint8_t type;
union {
struct {
/* 0: Generic (non-LL) (RFC 2132) */
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ gen;
struct {
/* 1: Ethernet Link-Layer (RFC 2132) */
uint8_t haddr[ETH_ALEN];
} _packed_ eth;
struct {
/* 2 - 254: ARP/Link-Layer (RFC 2132) */
uint8_t haddr[0];
} _packed_ ll;
struct {
/* 255: Node-specific (RFC 4361) */
uint32_t iaid;
struct duid duid;
} _packed_ ns;
struct {
uint8_t data[MAX_CLIENT_ID_LEN];
} _packed_ raw;
};
} _packed_ client_id;
size_t client_id_len;
char *hostname;
char *vendor_class_identifier;
......@@ -239,10 +239,9 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
*data = NULL;
*data_len = 0;
if (client->client_id_len) {
*type = client->client_id.raw.type;
*type = client->client_id.type;
*data = client->client_id.raw.data;
*data_len = client->client_id_len -
sizeof (client->client_id.raw.type);
*data_len = client->client_id_len - sizeof(client->client_id.type);
}
return 0;
......@@ -270,8 +269,8 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
break;
}
if (client->client_id_len == data_len + sizeof (client->client_id.raw.type) &&
client->client_id.raw.type == type &&
if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
client->client_id.type == type &&
memcmp(&client->client_id.raw.data, data, data_len) == 0)
return 0;
......@@ -282,9 +281,9 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
client_stop(client, DHCP_EVENT_STOP);
}
client->client_id.raw.type = type;
client->client_id.type = type;
memcpy(&client->client_id.raw.data, data, data_len);
client->client_id_len = data_len + sizeof (client->client_id.raw.type);
client->client_id_len = data_len + sizeof (client->client_id.type);
if (need_restart && client->state != DHCP_STATE_STOPPED)
sd_dhcp_client_start(client);
......@@ -461,12 +460,21 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
if (client->arp_type == ARPHRD_ETHER)
memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);