diff --git a/.gitignore b/.gitignore index b643968..d8ea634 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,9 @@ tags /test/unit/Makefile /test/unit/*.test /test/unit/*.o + +# Build +/cmake-build-*/ + +# IDE +/.idea/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..004e515 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.10) +project(chrony) + +# Directories configuration +set(SYSCONFDIR "/etc") +set(BINDIR "/usr/local/bin") +set(SBINDIR "/usr/local/sbin") +set(LOCALSTATEDIR "/var") +set(CHRONYVARDIR "/var/lib/chrony") +set(DESTDIR "") + +# Compiler and flags +set(CMAKE_C_FLAGS "-O2 -g -D_FORTIFY_SOURCE=2 -fPIE -fstack-protector-strong --param=ssp-buffer-size=4 -Wmissing-prototypes -Wall -pthread") +set(CMAKE_EXE_LINKER_FLAGS "-pie -Wl,-z,relro,-z,now") + +# Targets +add_executable(chronyd + sys_generic.c sys_linux.c sys_timex.c sys_posix.c cmdmon.c manual.c pktlength.c ntp_auth.c ntp_core.c ntp_ext.c ntp_io.c + ntp_sources.c addrfilt.c clientlog.c keys.c nameserv.c refclock.c refclock_phc.c refclock_pps.c refclock_shm.c + refclock_sock.c nameserv_async.c hwclock.c ntp_io_linux.c rtc_linux.c hash_intmd5.c cmac_gnutls.c + nts_ntp_client.c + array.c cmdparse.c conf.c leapdb.c local.c logging.c main.c memory.c quantiles.c reference.c regress.c rtc.c samplefilt.c + sched.c socket.c sources.c sourcestats.c stubs.c smooth.c sys.c sys_null.c tempcomp.c util.c + nts_ntp_auth.c siv_gnutls.c nts_ke_client.c nts_ke_session.c nts_ntp_server.c nts_ke_server.c +) +add_executable(chronyc + array.c client.c cmdparse.c getdate.c memory.c nameserv.c pktlength.c socket.c util.c hash_intmd5.c cmac_gnutls.c) + +# Libraries +target_link_libraries(chronyd m gnutls) +target_link_libraries(chronyc m edit gnutls) + +# Install commands +install(TARGETS chronyd DESTINATION ${DESTDIR}${SBINDIR}) +install(TARGETS chronyc DESTINATION ${DESTDIR}${BINDIR}) + +# Docs +add_custom_target(docs + COMMAND ${CMAKE_MAKE_PROGRAM} -C doc docs + COMMENT "Building documentation" +) + +add_custom_target(install-docs + COMMAND ${CMAKE_MAKE_PROGRAM} -C doc install-docs + COMMENT "Installing documentation" +) diff --git a/addressing.h b/addressing.h index 3e311fa..8aa4325 100644 --- a/addressing.h +++ b/addressing.h @@ -45,7 +45,7 @@ typedef struct { uint32_t id; } addr; uint16_t family; - uint16_t _pad; + uint16_t interface; } IPAddr; typedef struct { diff --git a/util.c b/util.c index a4c8288..c29a63f 100644 --- a/util.c +++ b/util.c @@ -32,6 +32,9 @@ #include "logging.h" #include "memory.h" #include "util.h" + +#include + #include "hash.h" #define NSEC_PER_SEC 1000000000 @@ -302,13 +305,21 @@ UTI_IPToString(const IPAddr *addr) break; case IPADDR_INET6: ip6 = addr->addr.in6; + uint32_t interface = addr->interface; #ifdef FEAT_IPV6 + // compose the IPv6 inet_ntop(AF_INET6, ip6, result, BUFFER_LENGTH); + // if used, append the interface name + if (interface != 0) { + char* result_if_delimiter = result + strlen(result); + *result_if_delimiter = '%'; + if_indextoname(interface, result_if_delimiter + 1); + } #else assert(BUFFER_LENGTH >= 40); for (a = 0; a < 8; a++) snprintf(result + a * 5, 40 - a * 5, "%04x:", - (unsigned int)(ip6[2 * a] << 8 | ip6[2 * a + 1])); + (unsigned int)(ip6[2 * a] << 8 | ip6[2 * a + 1]));_pad #endif break; case IPADDR_ID: @@ -332,15 +343,35 @@ UTI_StringToIP(const char *addr, IPAddr *ip) if (inet_pton(AF_INET, addr, &in4) > 0) { ip->family = IPADDR_INET4; - ip->_pad = 0; + ip->interface = 0; ip->addr.in4 = ntohl(in4.s_addr); return 1; } #ifdef FEAT_IPV6 - if (inet_pton(AF_INET6, addr, &in6) > 0) { + // split the address into an IP and an interface. + char addr_ip[INET6_ADDRSTRLEN]; + strncpy(addr_ip, addr, sizeof(addr_ip)); + char *addr_if = strchr(addr_ip, '%'); + + // prepare the interface index + unsigned int addr_if_index = 0; + // check if an interface is specified + if (addr_if != NULL) { + // split the string into two string, by replacing the "%" into an end-of-string + *addr_if = '\0'; + // the interface will now start on the next character + addr_if++; + + // get the index of the interface + addr_if_index = if_nametoindex(addr_if); + if (addr_if_index == 0) + return 0; + } + + if (inet_pton(AF_INET6, addr_ip, &in6) > 0) { ip->family = IPADDR_INET6; - ip->_pad = 0; + ip->interface = addr_if_index; memcpy(ip->addr.in6, in6.s6_addr, sizeof (ip->addr.in6)); return 1; } @@ -366,7 +397,7 @@ UTI_StringToIdIP(const char *addr, IPAddr *ip) { if (sscanf(addr, "ID#%"SCNu32, &ip->addr.id) == 1) { ip->family = IPADDR_ID; - ip->_pad = 0; + ip->interface = 0; return 1; } @@ -481,7 +512,7 @@ void UTI_IPNetworkToHost(const IPAddr *src, IPAddr *dest) { dest->family = ntohs(src->family); - dest->_pad = 0; + dest->interface = 0; switch (dest->family) { case IPADDR_INET4: