diff options
Diffstat (limited to 'src/libsystemd-network/include')
14 files changed, 1036 insertions, 0 deletions
diff --git a/src/libsystemd-network/include/systemd-network/arp-util.h b/src/libsystemd-network/include/systemd-network/arp-util.h new file mode 100644 index 0000000000..3ef56b002a --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/arp-util.h @@ -0,0 +1,32 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Axis Communications AB. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/if_ether.h> + +#include "socket-util.h" +#include "sparse-endian.h" + +int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac); + +int arp_send_probe(int fd, int ifindex, + be32_t pa, const struct ether_addr *ha); +int arp_send_announcement(int fd, int ifindex, + be32_t pa, const struct ether_addr *ha); diff --git a/src/libsystemd-network/include/systemd-network/dhcp-identifier.h b/src/libsystemd-network/include/systemd-network/dhcp-identifier.h new file mode 100644 index 0000000000..802a0d6bc2 --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp-identifier.h @@ -0,0 +1,74 @@ +#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 <systemd/sd-id128.h> + +#include "macro.h" +#include "sparse-endian.h" +#include "unaligned.h" + +typedef enum DUIDType { + DUID_TYPE_LLT = 1, + DUID_TYPE_EN = 2, + DUID_TYPE_LL = 3, + DUID_TYPE_UUID = 4, + _DUID_TYPE_MAX, + _DUID_TYPE_INVALID = -1, +} DUIDType; + +/* 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 + +/* https://tools.ietf.org/html/rfc3315#section-9.1 */ +struct duid { + be16_t type; + union { + struct { + /* DUID_TYPE_LLT */ + uint16_t htype; + uint32_t time; + uint8_t haddr[0]; + } _packed_ llt; + struct { + /* DUID_TYPE_EN */ + uint32_t pen; + uint8_t id[8]; + } _packed_ en; + struct { + /* DUID_TYPE_LL */ + int16_t htype; + uint8_t haddr[0]; + } _packed_ ll; + struct { + /* DUID_TYPE_UUID */ + sd_id128_t uuid; + } _packed_ uuid; + struct { + uint8_t data[MAX_DUID_LEN]; + } _packed_ raw; + }; +} _packed_; + +int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len); +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, void *_id); diff --git a/src/libsystemd-network/include/systemd-network/dhcp-internal.h b/src/libsystemd-network/include/systemd-network/dhcp-internal.h new file mode 100644 index 0000000000..dda4c13919 --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp-internal.h @@ -0,0 +1,68 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <linux/if_packet.h> +#include <net/ethernet.h> +#include <net/if_arp.h> +#include <stdint.h> + +#include <systemd/sd-dhcp-client.h> + +#include "dhcp-protocol.h" +#include "socket-util.h" + +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, + uint32_t xid, const uint8_t *mac_addr, + size_t mac_addr_len, uint16_t arp_type); +int dhcp_network_bind_udp_socket(be32_t address, uint16_t port); +int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, + const void *packet, size_t len); +int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, + const void *packet, size_t len); + +int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, uint8_t overload, + uint8_t code, size_t optlen, const void *optval); + +typedef int (*dhcp_option_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, size_t optlen, + size_t *optoffset); + +uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len); + +void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr, + uint16_t source, be32_t destination_addr, + uint16_t destination, uint16_t len); + +int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum); + +/* 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(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) diff --git a/src/libsystemd-network/include/systemd-network/dhcp-lease-internal.h b/src/libsystemd-network/include/systemd-network/dhcp-lease-internal.h new file mode 100644 index 0000000000..646e612cee --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp-lease-internal.h @@ -0,0 +1,102 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdint.h> +#include <linux/if_packet.h> + +#include <systemd/sd-dhcp-client.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 router; + be32_t next_server; + + bool have_subnet_mask; + be32_t subnet_mask; + + bool have_broadcast; + be32_t broadcast; + + struct in_addr *dns; + size_t dns_size; + + struct in_addr *ntp; + size_t ntp_size; + + struct sd_dhcp_route *static_route; + size_t static_route_size, static_route_allocated; + + uint16_t mtu; /* 0 if unset */ + + char *domainname; + char *hostname; + char *root_path; + + void *client_id; + size_t client_id_len; + + void *vendor_specific; + size_t vendor_specific_len; + + char *timezone; + + 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_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); + +int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file); +int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file); diff --git a/src/libsystemd-network/include/systemd-network/dhcp-protocol.h b/src/libsystemd-network/include/systemd-network/dhcp-protocol.h new file mode 100644 index 0000000000..3e32484c1d --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp-protocol.h @@ -0,0 +1,113 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/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, + DHCP_OFFER = 2, + DHCP_REQUEST = 3, + DHCP_DECLINE = 4, + DHCP_ACK = 5, + DHCP_NAK = 6, + DHCP_RELEASE = 7, + DHCP_INFORM = 8, + DHCP_FORCERENEW = 9, +}; + +enum { + DHCP_OVERLOAD_FILE = 1, + DHCP_OVERLOAD_SNAME = 2, +}; + +#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), +}; diff --git a/src/libsystemd-network/include/systemd-network/dhcp-server-internal.h b/src/libsystemd-network/include/systemd-network/dhcp-server-internal.h new file mode 100644 index 0000000000..7ba1e72155 --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp-server-internal.h @@ -0,0 +1,96 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Intel Corporation. All rights reserved. + Copyright (C) 2014 Tom Gundersen + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <systemd/sd-dhcp-server.h> +#include <systemd/sd-event.h> + +#include "dhcp-internal.h" +#include "hashmap.h" +#include "log.h" +#include "util.h" + +typedef struct DHCPClientId { + size_t length; + void *data; +} DHCPClientId; + +typedef struct DHCPLease { + DHCPClientId client_id; + + be32_t address; + be32_t gateway; + uint8_t chaddr[16]; + usec_t expiration; +} DHCPLease; + +struct sd_dhcp_server { + unsigned n_ref; + + sd_event *event; + int event_priority; + sd_event_source *receive_message; + int fd; + int fd_raw; + + int ifindex; + be32_t address; + be32_t netmask; + be32_t subnet; + uint32_t pool_offset; + uint32_t pool_size; + + char *timezone; + + struct in_addr *ntp, *dns; + unsigned n_ntp, n_dns; + + bool emit_router; + + Hashmap *leases_by_client_id; + DHCPLease **bound_leases; + DHCPLease invalid_lease; + + uint32_t max_lease_time, default_lease_time; +}; + +typedef struct DHCPRequest { + /* received message */ + DHCPMessage *message; + + /* options */ + DHCPClientId client_id; + size_t max_optlen; + be32_t server_id; + be32_t requested_ip; + uint32_t lifetime; +} DHCPRequest; + +#define log_dhcp_server(client, fmt, ...) log_internal(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__) + +int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, + size_t length); +int dhcp_server_send_packet(sd_dhcp_server *server, + DHCPRequest *req, DHCPPacket *packet, + int type, size_t optoffset); + +void client_id_hash_func(const void *p, struct siphash *state); +int client_id_compare_func(const void *_a, const void *_b); diff --git a/src/libsystemd-network/include/systemd-network/dhcp6-internal.h b/src/libsystemd-network/include/systemd-network/dhcp6-internal.h new file mode 100644 index 0000000000..4228053ade --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp6-internal.h @@ -0,0 +1,81 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014-2015 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <net/ethernet.h> +#include <netinet/in.h> + +#include <systemd/sd-event.h> + +#include "list.h" +#include "macro.h" +#include "sparse-endian.h" + +typedef struct DHCP6Address DHCP6Address; + +struct DHCP6Address { + LIST_FIELDS(DHCP6Address, addresses); + + struct { + struct in6_addr address; + be32_t lifetime_preferred; + be32_t lifetime_valid; + } iaaddr _packed_; +}; + +struct DHCP6IA { + uint16_t type; + struct { + be32_t id; + be32_t lifetime_t1; + be32_t lifetime_t2; + } _packed_; + sd_event_source *timeout_t1; + sd_event_source *timeout_t2; + + LIST_HEAD(DHCP6Address, addresses); +}; + +typedef struct DHCP6IA DHCP6IA; + +#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) +#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__) + +int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, + size_t optlen, const void *optval); +int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, DHCP6IA *ia); +int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, + size_t *optlen, uint8_t **optvalue); +int dhcp6_option_parse_ia(uint8_t **buf, size_t *buflen, uint16_t iatype, + DHCP6IA *ia); +int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, + struct in6_addr **addrs, size_t count, + size_t *allocated); +int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen, + char ***str_arr); + +int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address); +int dhcp6_network_send_udp_socket(int s, struct in6_addr *address, + const void *packet, size_t len); + +const char *dhcp6_message_type_to_string(int s) _const_; +int dhcp6_message_type_from_string(const char *s) _pure_; +const char *dhcp6_message_status_to_string(int s) _const_; +int dhcp6_message_status_from_string(const char *s) _pure_; diff --git a/src/libsystemd-network/include/systemd-network/dhcp6-lease-internal.h b/src/libsystemd-network/include/systemd-network/dhcp6-lease-internal.h new file mode 100644 index 0000000000..8e9a6f8e8c --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp6-lease-internal.h @@ -0,0 +1,74 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014-2015 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdint.h> + +#include <systemd/sd-dhcp6-lease.h> + +#include "dhcp6-internal.h" + +struct sd_dhcp6_lease { + unsigned n_ref; + + uint8_t *serverid; + size_t serverid_len; + uint8_t preference; + bool rapid_commit; + + DHCP6IA ia; + + DHCP6Address *addr_iter; + + struct in6_addr *dns; + size_t dns_count; + size_t dns_allocated; + char **domains; + size_t domains_count; + struct in6_addr *ntp; + size_t ntp_count; + size_t ntp_allocated; + char **ntp_fqdn; + size_t ntp_fqdn_count; +}; + +int dhcp6_lease_clear_timers(DHCP6IA *ia); +int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire); +DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia); + +int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id, + size_t len); +int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len); +int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference); +int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference); +int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease); +int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit); + +int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid); + +int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); +int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval, + size_t optlen); +int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen); +int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, + size_t optlen) ; + +int dhcp6_lease_new(sd_dhcp6_lease **ret); diff --git a/src/libsystemd-network/include/systemd-network/dhcp6-protocol.h b/src/libsystemd-network/include/systemd-network/dhcp6-protocol.h new file mode 100644 index 0000000000..2487c470ab --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/dhcp6-protocol.h @@ -0,0 +1,106 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/ip6.h> +#include <netinet/udp.h> + +#include "macro.h" +#include "sparse-endian.h" + +struct DHCP6Message { + union { + struct { + uint8_t type; + uint8_t _pad[3]; + } _packed_; + be32_t transaction_id; + }; +} _packed_; + +typedef struct DHCP6Message DHCP6Message; + +#define DHCP6_MIN_OPTIONS_SIZE \ + 1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) + +#define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT \ + { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } } + +enum { + DHCP6_PORT_SERVER = 547, + DHCP6_PORT_CLIENT = 546, +}; + +#define DHCP6_INF_TIMEOUT 1 * USEC_PER_SEC +#define DHCP6_INF_MAX_RT 120 * USEC_PER_SEC +#define DHCP6_SOL_MAX_DELAY 1 * USEC_PER_SEC +#define DHCP6_SOL_TIMEOUT 1 * USEC_PER_SEC +#define DHCP6_SOL_MAX_RT 120 * USEC_PER_SEC +#define DHCP6_REQ_TIMEOUT 1 * USEC_PER_SEC +#define DHCP6_REQ_MAX_RT 120 * USEC_PER_SEC +#define DHCP6_REQ_MAX_RC 10 +#define DHCP6_REN_TIMEOUT 10 * USEC_PER_SEC +#define DHCP6_REN_MAX_RT 600 * USEC_PER_SEC +#define DHCP6_REB_TIMEOUT 10 * USEC_PER_SEC +#define DHCP6_REB_MAX_RT 600 * USEC_PER_SEC + +enum DHCP6State { + DHCP6_STATE_STOPPED = 0, + DHCP6_STATE_INFORMATION_REQUEST = 1, + DHCP6_STATE_SOLICITATION = 2, + DHCP6_STATE_REQUEST = 3, + DHCP6_STATE_BOUND = 4, + DHCP6_STATE_RENEW = 5, + DHCP6_STATE_REBIND = 6, +}; + +enum { + DHCP6_SOLICIT = 1, + DHCP6_ADVERTISE = 2, + DHCP6_REQUEST = 3, + DHCP6_CONFIRM = 4, + DHCP6_RENEW = 5, + DHCP6_REBIND = 6, + DHCP6_REPLY = 7, + DHCP6_RELEASE = 8, + DHCP6_DECLINE = 9, + DHCP6_RECONFIGURE = 10, + DHCP6_INFORMATION_REQUEST = 11, + DHCP6_RELAY_FORW = 12, + DHCP6_RELAY_REPL = 13, + _DHCP6_MESSAGE_MAX = 14, +}; + +enum { + DHCP6_NTP_SUBOPTION_SRV_ADDR = 1, + DHCP6_NTP_SUBOPTION_MC_ADDR = 2, + DHCP6_NTP_SUBOPTION_SRV_FQDN = 3, +}; + +enum { + DHCP6_STATUS_SUCCESS = 0, + DHCP6_STATUS_UNSPEC_FAIL = 1, + DHCP6_STATUS_NO_ADDRS_AVAIL = 2, + DHCP6_STATUS_NO_BINDING = 3, + DHCP6_STATUS_NOT_ON_LINK = 4, + DHCP6_STATUS_USE_MULTICAST = 5, + _DHCP6_STATUS_MAX = 6, +}; diff --git a/src/libsystemd-network/include/systemd-network/icmp6-util.h b/src/libsystemd-network/include/systemd-network/icmp6-util.h new file mode 100644 index 0000000000..2b4dbc76ce --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/icmp6-util.h @@ -0,0 +1,25 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014-2015 Intel Corporation. All rights reserved. + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <net/ethernet.h> + +int icmp6_bind_router_solicitation(int index); +int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); diff --git a/src/libsystemd-network/include/systemd-network/lldp-internal.h b/src/libsystemd-network/include/systemd-network/lldp-internal.h new file mode 100644 index 0000000000..a6be995e3b --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/lldp-internal.h @@ -0,0 +1,53 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <systemd/sd-event.h> +#include <systemd/sd-lldp.h> + +#include "hashmap.h" +#include "log.h" +#include "prioq.h" + +struct sd_lldp { + int ifindex; + int fd; + + sd_event *event; + int64_t event_priority; + sd_event_source *io_event_source; + sd_event_source *timer_event_source; + + Prioq *neighbor_by_expiry; + Hashmap *neighbor_by_id; + + uint64_t neighbors_max; + + sd_lldp_callback_t callback; + void *userdata; + + uint16_t capability_mask; + + struct ether_addr filter_address; +}; + +#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) +#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__) diff --git a/src/libsystemd-network/include/systemd-network/lldp-neighbor.h b/src/libsystemd-network/include/systemd-network/lldp-neighbor.h new file mode 100644 index 0000000000..050159ab73 --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/lldp-neighbor.h @@ -0,0 +1,106 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Lennart Poettering + + 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 <stdbool.h> +#include <sys/types.h> + +#include <systemd/sd-lldp.h> + +#include "hash-funcs.h" +#include "lldp-internal.h" +#include "time-util.h" + +typedef struct LLDPNeighborID { + /* The spec calls this an "MSAP identifier" */ + void *chassis_id; + size_t chassis_id_size; + + void *port_id; + size_t port_id_size; +} LLDPNeighborID; + +struct sd_lldp_neighbor { + /* Neighbor objects stay around as long as they are linked into an "sd_lldp" object or n_ref > 0. */ + sd_lldp *lldp; + unsigned n_ref; + + usec_t until; + unsigned prioq_idx; + + struct ether_addr source_address; + struct ether_addr destination_address; + + LLDPNeighborID id; + + /* The raw packet size. The data is appended to the object, accessible via LLDP_NEIGHBOR_RAW() */ + size_t raw_size; + + /* The current read index for the iterative TLV interface */ + size_t rindex; + + /* And a couple of fields parsed out. */ + bool has_ttl:1; + bool has_capabilities:1; + bool has_port_vlan_id:1; + + uint16_t ttl; + + uint16_t system_capabilities; + uint16_t enabled_capabilities; + + char *port_description; + char *system_name; + char *system_description; + + uint16_t port_vlan_id; + + char *chassis_id_as_string; + char *port_id_as_string; +}; + +static inline void *LLDP_NEIGHBOR_RAW(const sd_lldp_neighbor *n) { + return (uint8_t*) n + ALIGN(sizeof(sd_lldp_neighbor)); +} + +static inline uint8_t LLDP_NEIGHBOR_TYPE(const sd_lldp_neighbor *n) { + return ((uint8_t*) LLDP_NEIGHBOR_RAW(n))[n->rindex] >> 1; +} + +static inline size_t LLDP_NEIGHBOR_LENGTH(const sd_lldp_neighbor *n) { + uint8_t *p; + + p = (uint8_t*) LLDP_NEIGHBOR_RAW(n) + n->rindex; + return p[1] + (((size_t) (p[0] & 1)) << 8); +} + +static inline void* LLDP_NEIGHBOR_DATA(const sd_lldp_neighbor *n) { + return ((uint8_t*) LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2; +} + +extern const struct hash_ops lldp_neighbor_id_hash_ops; +int lldp_neighbor_prioq_compare_func(const void *a, const void *b); + +sd_lldp_neighbor *lldp_neighbor_unlink(sd_lldp_neighbor *n); +sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size); +int lldp_neighbor_parse(sd_lldp_neighbor *n); +void lldp_neighbor_start_ttl(sd_lldp_neighbor *n); +bool lldp_neighbor_equal(const sd_lldp_neighbor *a, const sd_lldp_neighbor *b); diff --git a/src/libsystemd-network/include/systemd-network/lldp-network.h b/src/libsystemd-network/include/systemd-network/lldp-network.h new file mode 100644 index 0000000000..43ed54b3b2 --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/lldp-network.h @@ -0,0 +1,25 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2014 Tom Gundersen + Copyright (C) 2014 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <systemd/sd-event.h> + +int lldp_network_bind_raw_socket(int ifindex); diff --git a/src/libsystemd-network/include/systemd-network/network-internal.h b/src/libsystemd-network/include/systemd-network/network-internal.h new file mode 100644 index 0000000000..1cafb0747f --- /dev/null +++ b/src/libsystemd-network/include/systemd-network/network-internal.h @@ -0,0 +1,81 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright (C) 2013 Tom Gundersen <teg@jklm.no> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdbool.h> + +#include <systemd/sd-dhcp-lease.h> + +#include "condition.h" +#include "udev.h" + +bool net_match_config(const struct ether_addr *match_mac, + char * const *match_path, + char * const *match_driver, + char * const *match_type, + char * const *match_name, + Condition *match_host, + Condition *match_virt, + Condition *match_kernel, + Condition *match_arch, + const struct ether_addr *dev_mac, + const char *dev_path, + const char *dev_parent_driver, + const char *dev_driver, + const char *dev_type, + const char *dev_name); + +int config_parse_net_condition(const char *unit, const char *filename, unsigned line, + const char *section, unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_hwaddr(const char *unit, const char *filename, unsigned line, + const char *section, unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_ifnames(const char *unit, const char *filename, unsigned line, + const char *section, unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_ifalias(const char *unit, const char *filename, unsigned line, + const char *section, unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata); + +int config_parse_iaid(const char *unit, const char *filename, unsigned line, + const char *section, unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, void *userdata); + +int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result); +const char *net_get_name(struct udev_device *device); + +void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size); +int deserialize_in_addrs(struct in_addr **addresses, const char *string); +void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, + size_t size); +int deserialize_in6_addrs(struct in6_addr **addresses, const char *string); + +/* don't include "dhcp-lease-internal.h" as it causes conflicts between netinet/ip.h and linux/ip.h */ +struct sd_dhcp_route; + +void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size); +int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string); + +int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size); +int deserialize_dhcp_option(void **data, size_t *data_len, const char *string); |