--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ Functions for working with NTP extension fields
+ */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include "ntp_ext.h"
+
+struct ExtFieldHeader {
+ uint16_t type;
+ uint16_t length;
+};
+
+/* ================================================== */
+
+int
+NEF_ParseSingleField(unsigned char *buffer, int buffer_length, int start,
+ int *length, int *type, void **body, int *body_length)
+{
+ struct ExtFieldHeader *header;
+ int ef_length;
+
+ if (buffer_length < 0 || start < 0 || buffer_length <= start ||
+ buffer_length - start < sizeof (*header))
+ return 0;
+
+ header = (struct ExtFieldHeader *)(buffer + start);
+
+ assert(sizeof (*header) == 4);
+
+ ef_length = ntohs(header->length);
+
+ if (ef_length < (int)(sizeof (*header)) || start + ef_length > buffer_length ||
+ ef_length % 4 != 0)
+ return 0;
+
+ if (length)
+ *length = ef_length;
+ if (type)
+ *type = ntohs(header->type);
+ if (body)
+ *body = header + 1;
+ if (body_length)
+ *body_length = ef_length - sizeof (*header);
+
+ return 1;
+}
+
+/* ================================================== */
+
+int
+NEF_ParseField(NTP_Packet *packet, int packet_length, int start,
+ int *length, int *type, void **body, int *body_length)
+{
+ int ef_length;
+
+ if (packet_length <= NTP_HEADER_LENGTH || packet_length > sizeof (*packet) ||
+ packet_length <= start || packet_length % 4 != 0 ||
+ start < NTP_HEADER_LENGTH || start % 4 != 0)
+ return 0;
+
+ /* Only NTPv4 packets have extension fields */
+ if (NTP_LVM_TO_VERSION(packet->lvm) != 4)
+ return 0;
+
+ /* Check if the remaining data is a MAC. RFC 7822 specifies the maximum
+ length of a MAC in NTPv4 packets in order to enable deterministic
+ parsing. */
+ if (packet_length - start <= NTP_MAX_V4_MAC_LENGTH)
+ return 0;
+
+ if (!NEF_ParseSingleField((unsigned char *)packet, packet_length, start,
+ &ef_length, type, body, body_length))
+ return 0;
+
+ if (ef_length < NTP_MIN_EF_LENGTH)
+ return 0;
+
+ if (length)
+ *length = ef_length;
+
+ return 1;
+}
--- /dev/null
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Miroslav Lichvar 2019
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ **********************************************************************
+
+ =======================================================================
+
+ Header file for NTP extension fields
+ */
+
+#ifndef GOT_NTP_EXT_H
+#define GOT_NTP_EXT_H
+
+#include "ntp.h"
+
+extern int NEF_ParseSingleField(unsigned char *buffer, int buffer_length, int start,
+ int *length, int *type, void **body, int *body_length);
+extern int NEF_ParseField(NTP_Packet *packet, int packet_length, int start,
+ int *length, int *type, void **body, int *body_length);
+
+#endif