19 #include "spdlog/spdlog.h"
20 #include <netlink/netlink.h>
21 #include <netlink/attr.h>
22 #include <netlink/msg.h>
23 #include <linux/rtnetlink.h>
25 #include <linux/xfrm.h>
26 #include <linux/ipsec.h>
27 #include <arpa/inet.h>
29 #include <boost/algorithm/hex.hpp>
37 struct xfrm_userpolicy_info xpinfo = {};
38 xpinfo.lft.soft_byte_limit = XFRM_INF;
39 xpinfo.lft.hard_byte_limit = XFRM_INF;
40 xpinfo.lft.soft_packet_limit = XFRM_INF;
41 xpinfo.lft.hard_packet_limit = XFRM_INF;
42 xpinfo.dir = (direction ==
Direction::In) ? XFRM_POLICY_IN : XFRM_POLICY_OUT;
44 xpinfo.sel.family = AF_INET;
45 xpinfo.sel.saddr.a4 = INADDR_ANY;
46 xpinfo.sel.daddr.a4 = inet_addr(dest_address.c_str());
47 xpinfo.sel.prefixlen_d = 32;
49 struct xfrm_user_tmpl tmpl = {};
50 tmpl.id.daddr.a4 = inet_addr(dest_address.c_str());
51 tmpl.id.spi = htonl(spi);
52 tmpl.id.proto = IPPROTO_ESP;
53 tmpl.saddr.a4 = INADDR_ANY;
55 tmpl.mode = XFRM_MODE_TRANSPORT;
56 tmpl.aalgos = (~(__u32)0);
57 tmpl.ealgos = (~(__u32)0);
58 tmpl.calgos = (~(__u32)0);
59 tmpl.family = AF_INET;
61 msg = nlmsg_alloc_simple(XFRM_MSG_UPDPOLICY, 0);
62 nlmsg_append(msg, &xpinfo,
sizeof(xpinfo), NLMSG_ALIGNTO);
63 nla_put(msg, XFRMA_TMPL,
sizeof(tmpl), &tmpl);
65 sk = nl_socket_alloc();
66 nl_connect(sk, NETLINK_XFRM);
67 nl_send_auto(sk, msg);
75 struct xfrm_usersa_info xsinfo = {};
77 xsinfo.sel.family = AF_INET;
78 xsinfo.sel.saddr.a4 = INADDR_ANY;
79 xsinfo.sel.daddr.a4 = inet_addr(dest_address.c_str());
80 xsinfo.sel.prefixlen_d = 32;
82 xsinfo.id.daddr.a4 = inet_addr(dest_address.c_str());
83 xsinfo.id.spi = htonl(spi);
84 xsinfo.id.proto = IPPROTO_ESP;
86 xsinfo.saddr.a4 = INADDR_ANY;
88 xsinfo.lft.soft_byte_limit = XFRM_INF;
89 xsinfo.lft.hard_byte_limit = XFRM_INF;
90 xsinfo.lft.soft_packet_limit = XFRM_INF;
91 xsinfo.lft.hard_packet_limit = XFRM_INF;
94 xsinfo.family = AF_INET;
95 xsinfo.mode = XFRM_MODE_TRANSPORT;
98 std::vector<char> binary_key;
99 for (
unsigned int i = 0; i < key.length(); i += 2) {
100 binary_key.emplace_back((
char)strtol(key.substr(i, 2).c_str(),
nullptr, 16));
102 if (binary_key.size() > 512) {
103 throw "Key is too long";
105 size_t algo_size =
sizeof(
struct xfrm_algo) + binary_key.size();
106 void *algo_mem = std::malloc(algo_size);
107 struct xfrm_algo *algo =
new(algo_mem)
struct xfrm_algo;
109 strcpy(algo->alg_name,
"aes");
110 algo->alg_key_len = binary_key.size() * 8;
111 memcpy(algo->alg_key, &binary_key[0], binary_key.size());
113 msg = nlmsg_alloc_simple(XFRM_MSG_NEWSA, 0);
114 nlmsg_append(msg, &xsinfo,
sizeof(xsinfo), NLMSG_ALIGNTO);
115 nla_put(msg, XFRMA_ALG_CRYPT, algo_size, algo);
117 sk = nl_socket_alloc();
118 nl_connect(sk, NETLINK_XFRM);
119 nl_send_auto(sk, msg);
124 void enable_esp(uint32_t spi,
const std::string& dest_address,
Direction direction,
const std::string& key)
void configure_policy(uint32_t spi, const std::string &dest_address, Direction direction)
void enable_esp(uint32_t spi, const std::string &dest_address, Direction direction, const std::string &key)
void configure_state(uint32_t spi, const std::string &dest_address, Direction direction, const std::string &key)