168 lines
6.7 KiB
C
168 lines
6.7 KiB
C
/*
|
|
* Copyright (c) 2022 Tomoyuki Sakurai <y@trombik.org>
|
|
* Copyright (c) 2023-2024 Simone Rossetto <simros85@gmail.com>
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this
|
|
* list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
|
|
* its contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
#if !defined(__ESP_WIREGUARD__H__)
|
|
#define __ESP_WIREGUARD__H__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "esp_wireguard_err.h"
|
|
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <lwip/netif.h>
|
|
|
|
#define WG_KEY_LEN (32)
|
|
#define WG_B64_KEY_LEN (4 * ((WG_KEY_LEN + 2) / 3))
|
|
|
|
typedef uint8_t wg_key_t[WG_KEY_LEN];
|
|
|
|
typedef struct {
|
|
/* interface config */
|
|
wg_key_t private_key2; /**< private key generated by wg genkey. Required. */
|
|
uint16_t listen_port; /**< a 16-bit port for listening */
|
|
uint32_t fw_mark; /**< a 32-bit fwmark for outgoing packets */
|
|
/* peer config */
|
|
wg_key_t public_key2; /**< public key calculated by wg pubkey from a private key. Required. */
|
|
wg_key_t preshared_key2; /**< preshared key generated by wg genpsk. */
|
|
ip_addr_t address2; /**< a local IP address. */
|
|
ip_addr_t subnet; /**< a subnet mask of the local IP address. */
|
|
ip_addr_t netmask2; /**< the global subnet for the netif. */
|
|
const char* endpoint; /**< an endpoint IP address or hostname. */
|
|
ip_addr_t endpoint_ip; /**< endpoint IP address (internal use, resolved through dns query) */
|
|
uint16_t port; /**< a port number of remote endpoint. Default is 51820. */
|
|
uint16_t persistent_keepalive; /**< a seconds interval, between 1 and 65535 inclusive, of how often to send an
|
|
authenticated empty packet to the peer for the purpose of keeping a stateful
|
|
firewall or NAT mapping valid persistently. Set zero to disable the feature.
|
|
Default is zero. */
|
|
} wireguard_config_t;
|
|
|
|
typedef struct {
|
|
wireguard_config_t* config; /**< a pointer to wireguard config */
|
|
struct netif* netif; /**< a pointer to configured netif */
|
|
} wireguard_ctx_t;
|
|
|
|
/**
|
|
* @brief Initialize WireGuard
|
|
*
|
|
* Call this function to initialize the context of WireGuard.
|
|
*
|
|
* Do not call this function multiple times.
|
|
*
|
|
* To connect to other peer, use `esp_wireguard_disconnect()`, and
|
|
* `esp_wireguard_init()` with a new configuration. To reconnect to
|
|
* the same peer just use `esp_wireguard_disconnect()` and then
|
|
* `esp_wireguard_connect()`.
|
|
*
|
|
* @param config WireGuard configuration.
|
|
* @param[out] ctx Context of WireGuard.
|
|
*
|
|
* @return
|
|
* - ESP_OK: Successfully initilized WireGuard interface.
|
|
* - ESP_ERR_INVALID_ARG: given argument is invalid.
|
|
* - ESP_ERR_INVALID_STATE: hostname dns resolution cannot start
|
|
* - ESP_FAIL: Other error.
|
|
*/
|
|
esp_err_t esp_wireguard_init(wireguard_config_t *config, wireguard_ctx_t *ctx);
|
|
|
|
/**
|
|
* @brief Create a WireGuard interface and start establishing the connection
|
|
* to the peer.
|
|
*
|
|
* Call this function to start establishing the connection. Note that `ESP_OK`
|
|
* does not mean the connection is established. To see if the connection is
|
|
* established, or the peer is up, use `esp_wireguard_peer_is_up()`.
|
|
*
|
|
* Do not call this function multiple times.
|
|
*
|
|
* @param ctx Context of WireGuard.
|
|
* @return
|
|
* - ESP_OK on success.
|
|
* - ESP_ERR_INVALID_ARG if input arguments are invalid
|
|
* - ESP_ERR_RETRY dns query still ongoing for endpoint hostname resolution (retry connection)
|
|
* - ESP_ERR_INVALID_IP if endpoint IP address is missing or invalid (dns query failed)
|
|
* - ESP_FAIL on failure.
|
|
*/
|
|
esp_err_t esp_wireguard_connect(wireguard_ctx_t *ctx);
|
|
|
|
/**
|
|
* @brief Test if the peer is up.
|
|
* @param ctx Context of WireGuard
|
|
* @return
|
|
* - ESP_OK on peer up.
|
|
* - ESP_ERR_INVALID_ARG if ctx is NULL.
|
|
* - ESP_FAIL on peer still down.
|
|
*/
|
|
esp_err_t esp_wireguard_peer_is_up(const wireguard_ctx_t *ctx);
|
|
|
|
/**
|
|
* @brief Get timestamp of the latest handshake (with seconds resolution since unix epoch)
|
|
* @param ctx Context of WireGuard
|
|
* @param result the output timestamp
|
|
* @return
|
|
* - ESP_OK on success
|
|
* - ESP_FAIL if no handshake already completed
|
|
* - ESP_ERR_INVALID_ARG if ctx is NULL
|
|
* - ESP_ERR_INVALID_STATE if data inside ctx is not valid
|
|
*/
|
|
esp_err_t esp_wireguard_latest_handshake(const wireguard_ctx_t *ctx, time_t *result);
|
|
|
|
/**
|
|
* @brief Add new allowed IP/mask to the list of allowed ip/mask
|
|
* @param ctx Context of WireGuard
|
|
* @param allowed_ip The new IP to be allowed through tunnel
|
|
* @param allowed_ip_mask The mask of the new IP
|
|
* @return
|
|
* - ESP_OK on success
|
|
* - ESP_FAIL if the adding failed
|
|
* - ESP_ERR_INVALID_ARG if ctx, allowed_ip or allowed_ip_mask are invalid or empty
|
|
* - ESP_ERR_INVALID_STATE if data inside ctx is not valid
|
|
*/
|
|
esp_err_t esp_wireguard_add_allowed_ip(const wireguard_ctx_t *ctx, const ip_addr_t& allowed_ip, const ip_addr_t& allowed_ip_mask);
|
|
|
|
/**
|
|
* @brief Disconnect from the peer
|
|
*
|
|
* @param ctx Context of WireGuard.
|
|
* @return
|
|
* - ESP_OK on success.
|
|
*/
|
|
esp_err_t esp_wireguard_disconnect(wireguard_ctx_t *ctx);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
// vim: expandtab tabstop=4
|