diff --git a/candm.h b/candm.h index 8fe2255..575f1ed 100644 --- a/candm.h +++ b/candm.h @@ -102,7 +102,8 @@ #define REQ_SHUTDOWN 62 #define REQ_ONOFFLINE 63 #define REQ_ADD_SOURCE 64 -#define N_REQUEST_TYPES 65 +#define REQ_NTP_SOURCE_NAME 65 +#define N_REQUEST_TYPES 66 /* Structure used to exchange timespecs independent of time_t size */ typedef struct { @@ -342,6 +343,11 @@ typedef struct { int32_t EOR; } REQ_NTPData; +typedef struct { + IPAddr ip_addr; + int32_t EOR; +} REQ_NTPSourceName; + /* ================================================== */ #define PKT_TYPE_CMD_REQUEST 1 @@ -444,6 +450,7 @@ typedef struct { REQ_ReselectDistance reselect_distance; REQ_SmoothTime smoothtime; REQ_NTPData ntp_data; + REQ_NTPData ntp_source_name; } data; /* Command specific parameters */ /* Padding used to prevent traffic amplification. It only defines the @@ -480,7 +487,8 @@ typedef struct { #define RPY_NTP_DATA 16 #define RPY_MANUAL_TIMESTAMP2 17 #define RPY_MANUAL_LIST2 18 -#define N_REPLY_TYPES 19 +#define RPY_NTP_SOURCE_NAME 19 +#define N_REPLY_TYPES 20 /* Status codes */ #define STT_SUCCESS 0 @@ -696,6 +704,11 @@ typedef struct { int32_t EOR; } RPY_NTPData; +typedef struct { + int8_t name[256]; + int32_t EOR; +} RPY_NTPSourceName; + typedef struct { uint8_t version; uint8_t pkt_type; @@ -725,6 +738,7 @@ typedef struct { RPY_Activity activity; RPY_Smoothing smoothing; RPY_NTPData ntp_data; + RPY_NTPSourceName ntp_source_name; } data; /* Reply specific parameters */ } CMD_Reply; diff --git a/cmdmon.c b/cmdmon.c index 70fa2c9..ce5c719 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -133,6 +133,7 @@ static const char permissions[] = { PERMIT_AUTH, /* SHUTDOWN */ PERMIT_AUTH, /* ONOFFLINE */ PERMIT_AUTH, /* ADD_SOURCE */ + PERMIT_OPEN, /* NTP_SOURCE_NAME */ }; /* ================================================== */ @@ -1188,6 +1189,33 @@ handle_shutdown(CMD_Request *rx_message, CMD_Reply *tx_message) SCH_QuitProgram(); } +/* ================================================== */ + +static void +handle_ntp_source_name(CMD_Request *rx_message, CMD_Reply *tx_message) +{ + IPAddr addr; + char *name; + + UTI_IPNetworkToHost(&rx_message->data.ntp_data.ip_addr, &addr); + name = NSR_GetName(&addr); + + if (!name) { + tx_message->status = htons(STT_NOSUCHSOURCE); + return; + } + + tx_message->reply = htons(RPY_NTP_SOURCE_NAME); + + /* Avoid compiler warning */ + if (strlen(name) >= sizeof (tx_message->data.ntp_source_name.name)) + memcpy(tx_message->data.ntp_source_name.name, name, + sizeof (tx_message->data.ntp_source_name.name)); + else + strncpy((char *)tx_message->data.ntp_source_name.name, name, + sizeof (tx_message->data.ntp_source_name.name)); +} + /* ================================================== */ /* Read a packet and process it */ @@ -1561,6 +1589,10 @@ read_from_cmd_socket(int sock_fd, int event, void *anything) handle_onoffline(&rx_message, &tx_message); break; + case REQ_NTP_SOURCE_NAME: + handle_ntp_source_name(&rx_message, &tx_message); + break; + default: DEBUG_LOG("Unhandled command %d", rx_command); tx_message.status = htons(STT_FAILED); diff --git a/ntp_sources.c b/ntp_sources.c index 2b300dc..6a05bdd 100644 --- a/ntp_sources.c +++ b/ntp_sources.c @@ -782,6 +782,29 @@ NSR_GetLocalRefid(IPAddr *address) /* ================================================== */ +char * +NSR_GetName(IPAddr *address) +{ + NTP_Remote_Address remote_addr; + int slot, found; + SourceRecord *record; + + remote_addr.ip_addr = *address; + remote_addr.port = 0; + + find_slot(&remote_addr, &slot, &found); + if (!found) + return NULL; + + record = get_record(slot); + if (record->name) + return record->name; + + return UTI_IPToString(&record->remote_addr->ip_addr); +} + +/* ================================================== */ + /* This routine is called by ntp_io when a new packet arrives off the network, possibly with an authentication tail */ void diff --git a/ntp_sources.h b/ntp_sources.h index 4214233..686678e 100644 --- a/ntp_sources.h +++ b/ntp_sources.h @@ -90,6 +90,10 @@ extern void NSR_RefreshAddresses(void); /* Procedure to get local reference ID corresponding to a source */ extern uint32_t NSR_GetLocalRefid(IPAddr *address); +/* Procedure to get the name of a source. If the source doesn't have a name, + it returns a temporary string containing formatted address. */ +extern char *NSR_GetName(IPAddr *address); + /* This routine is called by ntp_io when a new packet arrives off the network */ extern void NSR_ProcessRx(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, NTP_Local_Timestamp *rx_ts, NTP_Packet *message, int length); diff --git a/pktlength.c b/pktlength.c index bb2058c..32b6f5a 100644 --- a/pktlength.c +++ b/pktlength.c @@ -121,6 +121,8 @@ static const struct request_length request_lengths[] = { REQ_LENGTH_ENTRY(null, null), /* SHUTDOWN */ REQ_LENGTH_ENTRY(null, null), /* ONOFFLINE */ REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_SOURCE */ + REQ_LENGTH_ENTRY(ntp_source_name, + ntp_source_name), /* NTP_SOURCE_NAME */ }; static const uint16_t reply_lengths[] = { @@ -143,6 +145,7 @@ static const uint16_t reply_lengths[] = { RPY_LENGTH_ENTRY(ntp_data), /* NTP_DATA */ RPY_LENGTH_ENTRY(manual_timestamp), /* MANUAL_TIMESTAMP2 */ RPY_LENGTH_ENTRY(manual_list), /* MANUAL_LIST2 */ + RPY_LENGTH_ENTRY(ntp_source_name), /* NTP_SOURCE_NAME */ }; /* ================================================== */