|  |  |  | @@ -17,7 +17,7 @@ extern "C" { | 
		
	
		
			
				|  |  |  |  | #include <netinet/in.h> | 
		
	
		
			
				|  |  |  |  | #include <linux/netlink.h> | 
		
	
		
			
				|  |  |  |  | #include <linux/rtnetlink.h> | 
		
	
		
			
				|  |  |  |  | #include <malloc.h> | 
		
	
		
			
				|  |  |  |  | // #include <malloc.h> | 
		
	
		
			
				|  |  |  |  | #include <string.h> | 
		
	
		
			
				|  |  |  |  | #include <iostream> | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					|  |  |  | @@ -74,9 +74,9 @@ void WireguardConfig::getWireguardConfig() { | 
		
	
		
			
				|  |  |  |  |   else if (!(WireguardDevices().exist(this->name))) throw std::string("Wireguard interface not exist"); | 
		
	
		
			
				|  |  |  |  |   int status; wg_device *devConfig; wg_peer *peer; | 
		
	
		
			
				|  |  |  |  |   if ((status = wg_get_device(&devConfig, this->name.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) privateKey = wgKeys::toString(devConfig->private_key); | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) publicKey = wgKeys::toString(devConfig->public_key); | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) portListen = devConfig->listen_port; | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_PRIVATE_KEY) this->privateKey = wgKeys::toString(devConfig->private_key); | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_PUBLIC_KEY) this->publicKey = wgKeys::toString(devConfig->public_key); | 
		
	
		
			
				|  |  |  |  |   if (devConfig->flags & WGDEVICE_HAS_LISTEN_PORT) this->portListen = devConfig->listen_port; | 
		
	
		
			
				|  |  |  |  |   this->interfaceAddress.GetInInterface(this->name); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   for ((peer) = (devConfig)->first_peer; (peer); (peer) = (peer)->next_peer) { | 
		
	
	
		
			
				
					|  |  |  | @@ -291,48 +291,28 @@ typedef struct { | 
		
	
		
			
				|  |  |  |  |   __u32 data[8]; | 
		
	
		
			
				|  |  |  |  | } inet_prefix; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | // This function is to open the netlink socket as the name suggests. | 
		
	
		
			
				|  |  |  |  | int netlink_open(struct rtnl_handle* rth) { | 
		
	
		
			
				|  |  |  |  | void netlink_open(struct rtnl_handle* rth) { | 
		
	
		
			
				|  |  |  |  |   int addr_len; | 
		
	
		
			
				|  |  |  |  |   memset(rth, 0, sizeof(rth)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   // Creating the netlink socket of family NETLINK_ROUTE | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | 
		
	
		
			
				|  |  |  |  |   if (rth->fd < 0) | 
		
	
		
			
				|  |  |  |  |   { | 
		
	
		
			
				|  |  |  |  |     perror("cannot open netlink socket"); | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if (rth->fd < 0) throw std::string("cannot open netlink socket"); | 
		
	
		
			
				|  |  |  |  |   memset(&rth->local, 0, sizeof(rth->local)); | 
		
	
		
			
				|  |  |  |  |   rth->local.nl_family = AF_NETLINK; | 
		
	
		
			
				|  |  |  |  |   rth->local.nl_groups = 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   // Binding the netlink socket | 
		
	
		
			
				|  |  |  |  |   if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) | 
		
	
		
			
				|  |  |  |  |   { | 
		
	
		
			
				|  |  |  |  |     perror("cannot bind netlink socket"); | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) throw std::string("cannot bind netlink socket"); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   addr_len = sizeof(rth->local); | 
		
	
		
			
				|  |  |  |  |   if (getsockname(rth->fd, (struct sockaddr*)&rth->local, (socklen_t*) &addr_len) < 0) | 
		
	
		
			
				|  |  |  |  |   { | 
		
	
		
			
				|  |  |  |  |     perror("cannot getsockname"); | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if (addr_len != sizeof(rth->local)) | 
		
	
		
			
				|  |  |  |  |   { | 
		
	
		
			
				|  |  |  |  |     fprintf(stderr, "wrong address lenght %d\n", addr_len); | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if (rth->local.nl_family != AF_NETLINK) | 
		
	
		
			
				|  |  |  |  |   { | 
		
	
		
			
				|  |  |  |  |     fprintf(stderr, "wrong address family %d\n", rth->local.nl_family); | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   if (getsockname(rth->fd, (struct sockaddr*)&rth->local, (socklen_t*) &addr_len) < 0) throw std::string("cannot getsockname"); | 
		
	
		
			
				|  |  |  |  |   if (addr_len != sizeof(rth->local)) throw std::string("wrong address lenght").append(std::to_string(addr_len)); | 
		
	
		
			
				|  |  |  |  |   if (rth->local.nl_family != AF_NETLINK) throw std::string("wrong address family").append(std::to_string(rth->local.nl_family)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   rth->seq = time(NULL); | 
		
	
		
			
				|  |  |  |  |   return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | // This function does the actual reading and writing to the netlink socket | 
		
	
	
		
			
				
					|  |  |  | @@ -352,12 +332,10 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, unsigned | 
		
	
		
			
				|  |  |  |  |   nladdr.nl_pid = peer; | 
		
	
		
			
				|  |  |  |  |   nladdr.nl_groups = groups; | 
		
	
		
			
				|  |  |  |  |   n->nlmsg_seq = ++rtnl->seq; | 
		
	
		
			
				|  |  |  |  |   if (answer == NULL) | 
		
	
		
			
				|  |  |  |  |     n->nlmsg_flags |= NLM_F_ACK; | 
		
	
		
			
				|  |  |  |  |   if (answer == NULL) n->nlmsg_flags |= NLM_F_ACK; | 
		
	
		
			
				|  |  |  |  |   // Actual sending of the message, status contains success/failure | 
		
	
		
			
				|  |  |  |  |   status = sendmsg(rtnl->fd, &msg, 0); | 
		
	
		
			
				|  |  |  |  |   if (status < 0) | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |   return sendmsg(rtnl->fd, &msg, 0); | 
		
	
		
			
				|  |  |  |  |   // if (status < 0) return -1; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | // This is the utility function for adding the parameters to the packet. | 
		
	
	
		
			
				
					|  |  |  | @@ -375,96 +353,25 @@ int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) { | 
		
	
		
			
				|  |  |  |  |   return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | int get_addr_1(inet_prefix *addr, const char *name, int family) { | 
		
	
		
			
				|  |  |  |  |   memset(addr, 0, sizeof(*addr)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (strcmp(name, "default") == 0 || | 
		
	
		
			
				|  |  |  |  |       strcmp(name, "all") == 0 || | 
		
	
		
			
				|  |  |  |  |       strcmp(name, "any") == 0) { | 
		
	
		
			
				|  |  |  |  |     if (family == AF_DECnet) | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
		
			
				|  |  |  |  |     addr->family = family; | 
		
	
		
			
				|  |  |  |  |     addr->bytelen = (family == AF_INET6 ? 16 : 4); | 
		
	
		
			
				|  |  |  |  |     addr->bitlen = -1; | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (strchr(name, ':')) { | 
		
	
		
			
				|  |  |  |  |     addr->family = AF_INET6; | 
		
	
		
			
				|  |  |  |  |     if (family != AF_UNSPEC && family != AF_INET6) | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
		
			
				|  |  |  |  |     if (inet_pton(AF_INET6, name, addr->data) <= 0) | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
		
			
				|  |  |  |  |     addr->bytelen = 16; | 
		
	
		
			
				|  |  |  |  |     addr->bitlen = -1; | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   addr->family = AF_INET; | 
		
	
		
			
				|  |  |  |  |   if (family != AF_UNSPEC && family != AF_INET) | 
		
	
		
			
				|  |  |  |  |     return -1; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   struct in_addr inAddr; | 
		
	
		
			
				|  |  |  |  |   inet_pton(AF_INET, name, (void*)&inAddr); | 
		
	
		
			
				|  |  |  |  |   memcpy(&addr->data,&inAddr.s_addr, sizeof(inAddr.s_addr)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | //  if (get_addr_ipv4((__u8 *)addr->data, name) <= 0) | 
		
	
		
			
				|  |  |  |  | //    return -1; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   addr->bytelen = 4; | 
		
	
		
			
				|  |  |  |  |   addr->bitlen = -1; | 
		
	
		
			
				|  |  |  |  |   return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | int get_prefix(inet_prefix *dst, char *arg, int family) { | 
		
	
		
			
				|  |  |  |  |   int err; | 
		
	
		
			
				|  |  |  |  |   unsigned plen; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   memset(dst, 0, sizeof(*dst)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (strcmp(arg, "default") == 0 || | 
		
	
		
			
				|  |  |  |  |       strcmp(arg, "any") == 0 || | 
		
	
		
			
				|  |  |  |  |       strcmp(arg, "all") == 0) { | 
		
	
		
			
				|  |  |  |  |     if (family == AF_DECnet) | 
		
	
		
			
				|  |  |  |  |       return -1; | 
		
	
		
			
				|  |  |  |  |     dst->family = family; | 
		
	
		
			
				|  |  |  |  |     dst->bytelen = 0; | 
		
	
		
			
				|  |  |  |  |     dst->bitlen = 0; | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   err = get_addr_1(dst, arg, family); | 
		
	
		
			
				|  |  |  |  |   if (err == 0) { | 
		
	
		
			
				|  |  |  |  |     switch(dst->family) { | 
		
	
		
			
				|  |  |  |  |       case AF_INET6: | 
		
	
		
			
				|  |  |  |  |         dst->bitlen = 128; | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       case AF_DECnet: | 
		
	
		
			
				|  |  |  |  |         dst->bitlen = 16; | 
		
	
		
			
				|  |  |  |  |         break; | 
		
	
		
			
				|  |  |  |  |       default: | 
		
	
		
			
				|  |  |  |  |       case AF_INET: | 
		
	
		
			
				|  |  |  |  |         dst->bitlen = 32; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return err; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void IpManeger::SetInInterface(std::string interfaceName) { | 
		
	
		
			
				|  |  |  |  |   if (this->size() == 0) return; | 
		
	
		
			
				|  |  |  |  |   if (!(WireguardDevices().exist(interfaceName))) throw std::string("Wireguard interface not exists!"); | 
		
	
		
			
				|  |  |  |  |   int status; unsigned int ifa_index; wg_device *devConfig;; | 
		
	
		
			
				|  |  |  |  |   int status; | 
		
	
		
			
				|  |  |  |  |   unsigned int ifa_index; | 
		
	
		
			
				|  |  |  |  |   wg_device *devConfig; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if ((status = wg_get_device(&devConfig, interfaceName.c_str())) < 0) throw std::string("It was not possible to get the Wireguard interface settings, code: ").append(std::to_string(status)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   ifa_index = devConfig->ifindex; | 
		
	
		
			
				|  |  |  |  |   free(devConfig); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   for (const auto ip : this->getIpParsed()) { | 
		
	
		
			
				|  |  |  |  |     struct rtnl_handle * rth; | 
		
	
		
			
				|  |  |  |  |     rth = (rtnl_handle*)malloc(sizeof(rtnl_handle)); | 
		
	
		
			
				|  |  |  |  |     netlink_open(rth); | 
		
	
		
			
				|  |  |  |  |   for (const auto ip : this->getIpParsed()) { | 
		
	
		
			
				|  |  |  |  |     int err; | 
		
	
		
			
				|  |  |  |  |     inet_prefix lcl; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // structure of the netlink packet. | 
		
	
		
			
				|  |  |  |  |     struct { | 
		
	
		
			
				|  |  |  |  |       struct nlmsghdr n; | 
		
	
	
		
			
				
					|  |  |  | @@ -482,12 +389,16 @@ void IpManeger::SetInInterface(std::string interfaceName) { | 
		
	
		
			
				|  |  |  |  |     req.ifa.ifa_index = ifa_index ; // get the loopback index | 
		
	
		
			
				|  |  |  |  |     req.ifa.ifa_scope = 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     get_prefix(&lcl, ip.Address.c_str(), req.ifa.ifa_family); | 
		
	
		
			
				|  |  |  |  |     memset(&lcl, 0, sizeof(lcl)); | 
		
	
		
			
				|  |  |  |  |     lcl.family = req.ifa.ifa_family; | 
		
	
		
			
				|  |  |  |  |     lcl.bytelen = (req.ifa.ifa_family == AF_INET) ? 4 : 16; | 
		
	
		
			
				|  |  |  |  |     lcl.bitlen = (req.ifa.ifa_family == AF_INET) ? 32 : 128; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (inet_pton(req.ifa.ifa_family, ip.Address.c_str(), &lcl.data) <= 0) throw std::string("Invalid IP address: ").append(ip.Address); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (req.ifa.ifa_family == AF_UNSPEC) req.ifa.ifa_family = lcl.family; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     struct in_addr inAddr; | 
		
	
		
			
				|  |  |  |  |     inet_pton(req.ifa.ifa_family, ip.Address.c_str(), (void*)&inAddr); | 
		
	
		
			
				|  |  |  |  |     addattr_l(&req.n, sizeof(req), IFA_LOCAL, &inAddr, sizeof(inAddr)); | 
		
	
		
			
				|  |  |  |  |     if (rtnl_talk(rth, &req.n, 0, 0, NULL) < 0); //throw std::string("Cannot set interface ip!"); | 
		
	
		
			
				|  |  |  |  |     addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); | 
		
	
		
			
				|  |  |  |  |     if ((err = rtnl_talk(rth, &req.n, 0, 0, NULL)) < 0) throw std::string("Cannot set interface IP, code: ").append(std::to_string(err)); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | } |