From 725beb360a4ea9e40655a182958f723f10445080 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 3 Feb 2020 18:28:00 +0100 Subject: [PATCH] ntp: add functions for adding extension fields --- ntp_ext.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- ntp_ext.h | 6 ++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/ntp_ext.c b/ntp_ext.c index 24062a4..b48ae2c 100644 --- a/ntp_ext.c +++ b/ntp_ext.c @@ -21,7 +21,7 @@ ======================================================================= - Functions for working with NTP extension fields + Functions for adding and parsing NTPv4 extension fields */ #include "config.h" @@ -37,6 +37,91 @@ struct ExtFieldHeader { /* ================================================== */ +static int +format_field(unsigned char *buffer, int buffer_length, int start, + int type, int body_length, int *length, void **body) +{ + struct ExtFieldHeader *header; + + if (buffer_length < 0 || start < 0 || buffer_length <= start || + buffer_length - start < sizeof (*header) || start % 4 != 0) + return 0; + + header = (struct ExtFieldHeader *)(buffer + start); + + if (body_length < 0 || sizeof (*header) + body_length > 0xffff || + start + sizeof (*header) + body_length > buffer_length || body_length % 4 != 0) + return 0; + + header->type = htons(type); + header->length = htons(sizeof (*header) + body_length); + *length = sizeof (*header) + body_length; + *body = header + 1; + + return 1; +} + +/* ================================================== */ + +int +NEF_SetField(unsigned char *buffer, int buffer_length, int start, + int type, void *body, int body_length, int *length) +{ + void *ef_body; + + if (!format_field(buffer, buffer_length, start, type, body_length, length, &ef_body)) + return 0; + + memcpy(ef_body, body, body_length); + + return 1; +} + +/* ================================================== */ + +int +NEF_AddBlankField(NTP_Packet *packet, NTP_PacketInfo *info, int type, int body_length, void **body) +{ + int ef_length, length = info->length; + + if (length < NTP_HEADER_LENGTH || length >= sizeof (*packet) || length % 4 != 0) + return 0; + + /* Only NTPv4 packets can have extension fields */ + if (info->version != 4) + return 0; + + if (!format_field((unsigned char *)packet, sizeof (*packet), length, + type, body_length, &ef_length, body)) + return 0; + + if (ef_length < NTP_MIN_EF_LENGTH) + return 0; + + info->length += ef_length; + info->ext_fields++; + + return 1; +} + +/* ================================================== */ + +int +NEF_AddField(NTP_Packet *packet, NTP_PacketInfo *info, + int type, void *body, int body_length) +{ + void *ef_body; + + if (!NEF_AddBlankField(packet, info, type, body_length, &ef_body)) + return 0; + + memcpy(ef_body, body, body_length); + + return 1; +} + +/* ================================================== */ + int NEF_ParseSingleField(unsigned char *buffer, int buffer_length, int start, int *length, int *type, void **body, int *body_length) diff --git a/ntp_ext.h b/ntp_ext.h index eac1bde..7405be8 100644 --- a/ntp_ext.h +++ b/ntp_ext.h @@ -29,6 +29,12 @@ #include "ntp.h" +extern int NEF_SetField(unsigned char *buffer, int buffer_length, int start, + int type, void *body, int body_length, int *length); +extern int NEF_AddBlankField(NTP_Packet *packet, NTP_PacketInfo *info, int type, + int body_length, void **body); +extern int NEF_AddField(NTP_Packet *packet, NTP_PacketInfo *info, + int type, void *body, int body_length); 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,