summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2016-04-27 21:36:26 +0200
committerSander Vrijders <sander.vrijders@intec.ugent.be>2016-04-27 22:37:53 +0200
commitc01a4c47d2ac21f54ad86a618eec30921f2bc73d (patch)
treea9d675152417928ebfae8c034a43d0f81e750dd4
parentd697babdbe0671b5d9a4cf4e0e46234f5045faef (diff)
downloadouroboros-c01a4c47d2ac21f54ad86a618eec30921f2bc73d.tar.gz
ouroboros-c01a4c47d2ac21f54ad86a618eec30921f2bc73d.zip
ipcpd: Add registration to DNS server
This adds support for adding the application name to a BIND DNS server through the nsupdate utility.
-rw-r--r--include/ouroboros/config.h.in1
-rw-r--r--src/ipcpd/shim-udp/CMakeLists.txt36
-rw-r--r--src/ipcpd/shim-udp/main.c103
3 files changed, 121 insertions, 19 deletions
diff --git a/include/ouroboros/config.h.in b/include/ouroboros/config.h.in
index 6abce97a..380c1065 100644
--- a/include/ouroboros/config.h.in
+++ b/include/ouroboros/config.h.in
@@ -30,5 +30,6 @@
#define _POSIX_C_SOURCE 199506L
#define IPCP_SHIM_UDP_EXEC "@IPCP_SHIM_UDP_TARGET@"
#define IPCP_NORMAL_EXEC "@IPCP_NORMAL_TARGET@"
+#define NSUPDATE_EXEC "@NSUPDATE_EXECUTABLE@"
#endif
diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt
index f730fa3a..c71fa00b 100644
--- a/src/ipcpd/shim-udp/CMakeLists.txt
+++ b/src/ipcpd/shim-udp/CMakeLists.txt
@@ -14,30 +14,40 @@ include_directories(${CMAKE_BINARY_DIR}/include)
include(CheckFunctionExists)
CHECK_FUNCTION_EXISTS("gethostbyname" CMAKE_HAVE_GETHOSTBYNAME)
IF(NOT CMAKE_HAVE_GETHOSTBYNAME)
- CHECK_LIBRARY_EXISTS("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
- IF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
- SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl)
- ELSE (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
- CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
- IF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
- SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd)
- ENDIF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
- ENDIF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ CHECK_LIBRARY_EXISTS("nsl" "gethostbyname" "" CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ IF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lnsl)
+ ELSE (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
+ CHECK_LIBRARY_EXISTS("bsd" "gethostbyname" "" CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ IF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ SET (X11_X_EXTRA_LIBS ${X11_X_EXTRA_LIBS} -lbsd)
+ ENDIF (CMAKE_LIB_BSD_HAS_GETHOSTBYNAME)
+ ENDIF (CMAKE_LIB_NSL_HAS_GETHOSTBYNAME)
ENDIF(NOT CMAKE_HAVE_GETHOSTBYNAME)
+# Find the nsupdate executable
+find_program(NSUPDATE_EXECUTABLE
+ NAMES nsupdate
+ DOC "The nsupdate tool that enables DDNS")
+
+if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND")
+ message(FATAL_ERROR "Could not find nsupdate, which is needed for DDNS")
+else()
+ message("-- Found nsupdate: ${NSUPDATE_EXECUTABLE}")
+endif()
+
SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET")
set(SHIM_UDP_SOURCES
- # Add source files here
- ${CMAKE_CURRENT_SOURCE_DIR}/main.c
-)
+ # Add source files here
+ ${CMAKE_CURRENT_SOURCE_DIR}/main.c)
add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES})
target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros)
include(MacroAddCompileFlags)
if (CMAKE_BUILD_TYPE MATCHES Debug)
- MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG)
+ MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG)
endif (CMAKE_BUILD_TYPE MATCHES Debug)
install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION bin)
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 71c414ef..460fe9e3 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -44,11 +44,13 @@
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
+#include <sys/wait.h>
#define THIS_TYPE IPCP_SHIM_UDP
#define LISTEN_PORT htons(0x0D1F)
#define SHIM_UDP_BUF_SIZE 256
#define SHIM_UDP_MAX_SDU_SIZE 8980
+#define DNS_TTL 86400
#define shim_data(type) ((struct ipcp_udp_data *) type->data)
@@ -340,35 +342,124 @@ int ipcp_udp_bootstrap(struct dif_config * conf)
return 0;
}
+/* FIXME: Dependency on nsupdate to be removed in the end */
+static int ddns_send(char * cmd)
+{
+ pid_t pid = 0;
+ int wstatus;
+ int pipe_fd[2];
+ char * argv[] = {NSUPDATE_EXEC, 0};
+ char * envp[] = {0};
+
+ if (pipe(pipe_fd)) {
+ LOG_ERR("Failed to create pipe.");
+ return -1;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ LOG_ERR("Failed to fork.");
+ return -1;
+ }
+
+ if (pid == 0) {
+ close(pipe_fd[1]);
+ dup2(pipe_fd[0], 0);
+ execve(argv[0], &argv[0], envp);
+ }
+
+ close(pipe_fd[0]);
+
+ if (write(pipe_fd[1], cmd, strlen(cmd)) == -1) {
+ LOG_ERR("Failed to register with DNS server.");
+ close(pipe_fd[1]);
+ return -1;
+ }
+
+ waitpid(pid, &wstatus, 0);
+ if (WIFEXITED(wstatus) == true &&
+ WEXITSTATUS(wstatus) == 0)
+ LOG_DBGF("Succesfully communicated with DNS server.");
+ else
+ LOG_ERR("Failed to register with DNS server.");
+
+ close(pipe_fd[1]);
+ return 0;
+}
+
int ipcp_udp_name_reg(char * name)
{
+ char ipstr[INET_ADDRSTRLEN];
+ char dnsstr[INET_ADDRSTRLEN];
+ /* max DNS name length + max IP length + command length */
+ char cmd[100];
+ uint32_t dns_addr;
+ uint32_t ip_addr;
+
if (_ipcp->state != IPCP_ENROLLED) {
LOG_DBGF("Won't register with non-enrolled IPCP.");
return -1;
}
+ if (strlen(name) > 24) {
+ LOG_ERR("DNS names cannot be longer than 24 chars.");
+ return -1;
+ }
+
if (ipcp_data_add_reg_entry(_ipcp->data, name)) {
LOG_ERR("Failed to add %s to local registry.", name);
return -1;
}
- LOG_DBG("Registered %s", name);
+ /* register application with DNS server */
+
+ dns_addr = shim_data(_ipcp)->dns_addr;
+ if (dns_addr != 0) {
+ ip_addr = shim_data(_ipcp)->ip_addr;
- /* FIXME: register application with DNS server */
- LOG_MISSING;
+ inet_ntop(AF_INET, &ip_addr, ipstr, INET_ADDRSTRLEN);
+ inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN);
+ sprintf(cmd, "server %s\nupdate add %s %d A %s\nsend\nquit\n",
+ dnsstr, name, DNS_TTL, ipstr);
+
+ if (ddns_send(cmd)) {
+ ipcp_data_del_reg_entry(_ipcp->data, name);
+ return -1;
+ }
+ }
+
+ LOG_DBG("Registered %s.", name);
return 0;
}
int ipcp_udp_name_unreg(char * name)
{
+ char dnsstr[INET_ADDRSTRLEN];
+ /* max DNS name length + max IP length + max command length */
+ char cmd[100];
+ uint32_t dns_addr;
+
+ if (strlen(name) > 24) {
+ LOG_ERR("DNS names cannot be longer than 24 chars.");
+ return -1;
+ }
+
+ /* unregister application with DNS server */
+
+ dns_addr = shim_data(_ipcp)->dns_addr;
+ if (dns_addr != 0) {
+ inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN);
+ sprintf(cmd, "server %s\nupdate delete %s A\nsend\nquit\n",
+ dnsstr, name);
+
+ ddns_send(cmd);
+ }
+
ipcp_data_del_reg_entry(_ipcp->data, name);
LOG_DBG("Unregistered %s.", name);
- /* FIXME: unregister application from DNS server */
- LOG_MISSING;
-
return 0;
}