* Commercial licensing is also available.
*/
-#include <string.h>
#include <arpa/inet.h>
+#include <string.h>
#include "general-utilities.h"
+#include "debug.h"
uint32_t nctohl(const uint8_t *p) { // read 4 characters from *p and do ntohl on them
// this is to avoid possible aliasing violations
#include <inttypes.h>
#include <time.h>
+// struct sockaddr_in6 is bigger than struct sockaddr. derp
+#ifdef AF_INET6
+#define SOCKADDR struct sockaddr_storage
+#define SAFAMILY ss_family
+#else
+#define SOCKADDR struct sockaddr
+#define SAFAMILY sa_family
+#endif
+
uint32_t nctohl(const uint8_t *p); // read 4 characters from *p and do ntohl on them, avoiding aliasing
uint16_t nctohs(const uint8_t *p);
uint64_t timespec_to_ns(struct timespec *tn);
*/
#include <string.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <arpa/inet.h>
#include "nqptp-clock-sources.h"
#include "nqptp-ptp-definitions.h"
#include "debug.h"
}
}
+// check all the entries in the clock array and mark all those that
+// belong to ourselves
+
+void update_clock_self_identifications(clock_source *clocks_shared_info,
+ clock_source_private_data *clocks_private_info) {
+ // first, turn off all the self-id flags
+ int i;
+ for (i = 0; i < MAX_CLOCKS ; i++) {
+ clocks_private_info[i].is_one_of_ours = 0;
+ }
+
+ struct ifaddrs *ifap, *ifa;
+ void *addr = NULL;
+ short family;
+ getifaddrs(&ifap);
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ family = ifa->ifa_addr->sa_family;
+#ifdef AF_INET6
+ if (ifa->ifa_addr && family==AF_INET6) {
+ struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) ifa->ifa_addr;
+ addr = &(sa6->sin6_addr);
+ }
+#endif
+ if (ifa->ifa_addr && family==AF_INET) {
+ struct sockaddr_in *sa4 = (struct sockaddr_in *) ifa->ifa_addr;
+ addr = &(sa4->sin_addr);
+ }
+ char ip_string[64];
+ memset(ip_string,0,sizeof(ip_string));
+ if (addr != NULL)
+ inet_ntop(family, addr, ip_string, sizeof(ip_string));
+ if (strlen(ip_string) != 0) {
+ // now set the is_one_of_ours flag of any clock with this ip
+ for (i = 0; i < MAX_CLOCKS ; i++) {
+ if (strcasecmp(ip_string,clocks_shared_info[i].ip) == 0) {
+ debug(2,"found an entry for one of our clocks");
+ clocks_private_info[i].is_one_of_ours = 1;
+ }
+ }
+
+ }
+ }
+ freeifaddrs(ifap);
+}
+
uint16_t in_use;
enum stage current_stage;
uint64_t t2;
+
// for Announce Qualification
uint64_t announce_times[4]; // we'll check qualification and currency using these
int announce_is_valid; // this may mean it's a master clock_source
+ int is_one_of_ours; // true if it is one of our own clocks
} clock_source_private_data;
int find_clock_source_record(char *sender_string, uint64_t packet_clock_id,
clock_source *clocks_shared_info,
clock_source_private_data *clocks_private_info);
+void update_clock_self_identifications(clock_source *clocks_shared_info,
+ clock_source_private_data *clocks_private_info);
+
void manage_clock_sources(uint64_t reception_time, clock_source *clocks_shared_info,
clock_source_private_data *clocks_private_info);
#include "debug.h"
void handle_announce(char *buf, ssize_t recv_len, clock_source* clock_info, clock_source_private_data *clock_private_info, uint64_t reception_time) {
+ // reject Announce messages from self
+ if (clock_private_info->is_one_of_ours == 0) {
// debug_print_buffer(1, buf, (size_t) recv_len);
// make way for the new time
if ((size_t)recv_len >= sizeof(struct ptp_announce_message)) {
uint16_t offsetScaledLogVariance = clockQuality & 0xffff;
debug(1, " grandmasterIdentity: %" PRIx64 ".", grandmaster_clock_id);
debug(1, " grandmasterPriority1: %u.", msg->announce.grandmasterPriority1);
- debug(1, " grandmasterClockQuality,: 0x%x.", msg->announce.grandmasterClockQuality);
+ debug(1, " grandmasterClockQuality: 0x%x.", msg->announce.grandmasterClockQuality);
debug(1, " clockClass: %u.", clockClass); // See 7.6.2.4 clockClass
debug(1, " clockAccuracy: 0x%x.", clockAccuracy); // See 7.6.2.5 clockAccuracy
debug(1, " offsetScaledLogVariance: %x.", offsetScaledLogVariance); // See 7.6.3 PTP variance
clock_private_info->announce_is_valid = 0;
}
}
+ }
}
#include <errno.h>
#include <linux/net_tstamp.h>
#include "nqptp-utilities.h"
+#include "general-utilities.h"
+
#include "debug.h"
#ifndef SO_TIMESTAMPING
struct shm_structure *shared_memory = NULL; // this is where public clock info is available
int epoll_fd;
-// struct sockaddr_in6 is bigger than struct sockaddr.
-#ifdef AF_INET6
-#define SOCKADDR struct sockaddr_storage
-#define SAFAMILY ss_family
-#else
-#define SOCKADDR struct sockaddr
-#define SAFAMILY sa_family
-#endif
-
void goodbye(void) {
// close any open sockets
unsigned int i;
while (1) {
struct epoll_event events[MAX_EVENTS];
+ // the timeout is in seconds
int event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, 1000);
uint64_t reception_time = get_time_now(); // use this if other methods fail
if (the_clock != -1) {
switch (buf[0] & 0xF) {
case Announce:
+ // needed to reject messages coming from self
+ update_clock_self_identifications((clock_source *)&shared_memory->clocks,
+ (clock_source_private_data *)&clocks_private);
handle_announce(buf, recv_len, &shared_memory->clocks[the_clock],&clocks_private[the_clock], reception_time);
break;
case Sync: { // if it's a sync