/* * * Embedded Linux library * * Copyright (C) 2020 Intel Corporation. All rights reserved. * * This library 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. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ struct l_dhcp6_client; enum { DHCP6_PORT_SERVER = 547, DHCP6_PORT_CLIENT = 546, }; enum { DHCP6_OPTION_CLIENT_ID = 1, DHCP6_OPTION_SERVER_ID = 2, DHCP6_OPTION_IA_NA = 3, DHCP6_OPTION_IA_TA = 4, DHCP6_OPTION_IA_ADDR = 5, DHCP6_OPTION_REQUEST_OPTION = 6, DHCP6_OPTION_PREFERENCE = 7, DHCP6_OPTION_ELAPSED_TIME = 8, DHCP6_OPTION_STATUS_CODE = 13, DHCP6_OPTION_RAPID_COMMIT = 14, DHCP6_OPTION_USER_CLASS = 15, DHCP6_OPTION_VENDOR_CLASS = 16, DHCP6_OPTION_VENDOR_OPTS = 17, DHCP6_OPTION_IA_PD = 25, DHCP6_OPTION_IA_PREFIX = 26, DHCP6_OPTION_INF_RT = 32, DHCP6_OPTION_SOL_MAX_RT = 82, DHCP6_OPTION_INF_MAX_RT = 83, }; #define DHCP6_ADDR_LINKLOCAL_ALL_NODES \ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } } /* RFC 8415, Section 11.1 */ enum duid_type { DUID_TYPE_LINK_LAYER_ADDR_PLUS_TIME = 1, DUID_TYPE_ENTERPRISE_NUMBER = 2, DUID_TYPE_LINK_LAYER_ADDR = 3, DUID_TYPE_UNIVERSALLY_UNIQUE_ID = 4, }; struct duid { __be16 type; uint8_t identifier[]; } __attribute__ ((packed)); /* RFC 8415, Figure 2 */ struct dhcp6_message { union { uint8_t msg_type; __be32 transaction_id; }; uint8_t options[]; } __attribute__ ((packed)); struct dhcp6_option_iter { const uint8_t *options; uint16_t pos; uint16_t max; }; typedef void (*dhcp6_transport_rx_cb_t)(const void *, size_t, void *); struct dhcp6_transport { int (*open)(struct dhcp6_transport *s); int (*send)(struct dhcp6_transport *transport, const struct in6_addr *dest, const void *data, size_t len); void (*close)(struct dhcp6_transport *transport); uint32_t ifindex; dhcp6_transport_rx_cb_t rx_cb; void *rx_data; }; struct dhcp6_transport *_dhcp6_default_transport_new(uint32_t ifindex, const struct in6_addr *addr, uint16_t port); void _dhcp6_transport_free(struct dhcp6_transport *transport); void _dhcp6_transport_set_rx_callback(struct dhcp6_transport *transport, dhcp6_transport_rx_cb_t rx_cb, void *userdata); void __dhcp6_option_iter_init(struct dhcp6_option_iter *iter, const void *options, size_t len); bool _dhcp6_option_iter_init(struct dhcp6_option_iter *iter, const struct dhcp6_message *message, size_t len); bool _dhcp6_option_iter_next(struct dhcp6_option_iter *iter, uint16_t *type, uint16_t *len, const void **data); bool _dhcp6_client_set_transport(struct l_dhcp6_client *client, struct dhcp6_transport *transport); struct dhcp6_address_info { uint8_t addr[16]; uint32_t preferred_lifetime; uint32_t valid_lifetime; uint8_t prefix_len; }; struct dhcp6_ia { uint8_t iaid[4]; uint32_t t1; uint32_t t2; struct dhcp6_address_info info; }; struct l_dhcp6_lease { uint8_t *server_id; size_t server_id_len; uint8_t preference; struct dhcp6_ia ia_na; struct dhcp6_ia ia_pd; uint8_t *dns; uint16_t dns_len; char **domain_list; bool have_na : 1; bool have_pd : 1; bool rapid_commit : 1; }; struct l_dhcp6_lease *_dhcp6_lease_new(void); void _dhcp6_lease_free(struct l_dhcp6_lease *lease); struct l_dhcp6_lease *_dhcp6_lease_parse_options( struct dhcp6_option_iter *iter, const uint8_t expected_iaid[static 4]); uint32_t _dhcp6_lease_get_t1(struct l_dhcp6_lease *lease); uint32_t _dhcp6_lease_get_t2(struct l_dhcp6_lease *lease); uint32_t _dhcp6_lease_get_valid_lifetime(struct l_dhcp6_lease *lease); uint32_t _dhcp6_lease_get_preferred_lifetime(struct l_dhcp6_lease *lease);