/* * Ouroboros - Copyright (C) 2016 * * The API to instruct IPCPs * * Sander Vrijders <sander.vrijders@intec.ugent.be> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define OUROBOROS_PREFIX "lib-ipcp" #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 199506L #endif #include <ouroboros/ipcp.h> #include <ouroboros/common.h> #include <ouroboros/logs.h> #include <ouroboros/config.h> #include <ouroboros/utils.h> #include <ouroboros/sockets.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> static int send_ipcp_msg(pid_t pid, struct ipcp_msg * msg) { int sockfd = 0; buffer_t * buf = NULL; char * sock_path; sock_path = ipcp_sock_path(pid); if (sock_path == NULL) return -1; sockfd = client_socket_open(sock_path); if (sockfd < 0) { free(sock_path); return -1; } buf = serialize_ipcp_msg(msg); if (buf == NULL) { free(sock_path); close(sockfd); return -1; } if (write(sockfd, buf->data, buf->size) == -1) { free(sock_path); free(buf->data); free(buf); close(sockfd); return -1; } free(buf->data); free(buf); close(sockfd); return 0; } pid_t ipcp_create(rina_name_t name, char * ipcp_type) { pid_t pid = 0; char * api_id = NULL; char * aei_id = NULL; size_t len = 0; char * ipcp_dir = "bin/ipcpd"; char * full_name = NULL; if (ipcp_type == NULL) return -1; pid = fork(); if (pid == -1) { LOG_ERR("Failed to fork"); return pid; } if (pid != 0) { return pid; } api_id = malloc(n_digits(name.api_id) + 1); if (!api_id) { LOG_ERR("Failed to malloc"); exit(EXIT_FAILURE); } sprintf(api_id, "%d", name.api_id); aei_id = malloc(n_digits(name.aei_id) + 1); if (!aei_id) { LOG_ERR("Failed to malloc"); free(api_id); exit(EXIT_FAILURE); } sprintf(aei_id, "%d", name.aei_id); len += strlen(INSTALL_DIR); len += strlen(ipcp_dir); len += 2; full_name = malloc(len); if (!full_name) { LOG_ERR("Failed to malloc"); free(api_id); free(aei_id); exit(EXIT_FAILURE); } strcpy(full_name, INSTALL_DIR); strcat(full_name, "/"); strcat(full_name, ipcp_dir); char * argv[] = {full_name, name.ap_name, api_id, name.ae_name, aei_id, ipcp_type, 0}; char * envp[] = {0}; execve(argv[0], &argv[0], envp); LOG_DBG("%s", strerror(errno)); LOG_ERR("Failed to load IPCP daemon"); LOG_ERR("Make sure to run the installed version"); free(api_id); free(aei_id); free(full_name); exit(EXIT_FAILURE); } int ipcp_destroy(pid_t pid) { int status; if (kill(pid, SIGTERM)) { LOG_ERR("Failed to destroy IPCP"); return -1; } if (waitpid(pid, &status, 0) < 0) { LOG_ERR("Failed to destroy IPCP"); return -1; } return 0; } int ipcp_reg(pid_t pid, char ** difs, size_t difs_size) { struct ipcp_msg msg; if (difs == NULL) return -1; msg.code = IPCP_REG; msg.difs = difs; msg.difs_size = difs_size; if (send_ipcp_msg(pid, &msg)) { LOG_ERR("Failed to send message to daemon"); return -1; } return 0; } int ipcp_unreg(pid_t pid, char ** difs, size_t difs_size) { struct ipcp_msg msg; if (difs == NULL) return -1; msg.code = IPCP_UNREG; msg.difs = difs; msg.difs_size = difs_size; if (send_ipcp_msg(pid, &msg)) { LOG_ERR("Failed to send message to daemon"); return -1; } return 0; } int ipcp_bootstrap(pid_t pid, struct dif_config conf) { struct ipcp_msg msg; msg.code = IPCP_BOOTSTRAP; msg.conf = &conf; if (send_ipcp_msg(pid, &msg)) { LOG_ERR("Failed to send message to daemon"); return -1; } return 0; } int ipcp_enroll(pid_t pid, char * dif_name, rina_name_t member, char ** n_1_difs, ssize_t n_1_difs_size) { struct ipcp_msg msg; if (n_1_difs == NULL) return -1; if (dif_name == NULL) return -1; msg.code = IPCP_ENROLL; msg.dif_name = dif_name; msg.member = &member; msg.difs = n_1_difs; msg.difs_size = n_1_difs_size; if (send_ipcp_msg(pid, &msg)) { LOG_ERR("Failed to send message to daemon"); return -1; } return 0; }