Blame pktlength.c

Packit 96c956
/*
Packit 96c956
  chronyd/chronyc - Programs for keeping computer clocks accurate.
Packit 96c956
Packit 96c956
 **********************************************************************
Packit 96c956
 * Copyright (C) Richard P. Curnow  1997-2002
Packit 96c956
 * Copyright (C) Miroslav Lichvar  2014-2016
Packit 96c956
 * 
Packit 96c956
 * This program is free software; you can redistribute it and/or modify
Packit 96c956
 * it under the terms of version 2 of the GNU General Public License as
Packit 96c956
 * published by the Free Software Foundation.
Packit 96c956
 * 
Packit 96c956
 * This program is distributed in the hope that it will be useful, but
Packit 96c956
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 96c956
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 96c956
 * General Public License for more details.
Packit 96c956
 * 
Packit 96c956
 * You should have received a copy of the GNU General Public License along
Packit 96c956
 * with this program; if not, write to the Free Software Foundation, Inc.,
Packit 96c956
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Packit 96c956
 * 
Packit 96c956
 **********************************************************************
Packit 96c956
Packit 96c956
  =======================================================================
Packit 96c956
Packit 96c956
  Routines to compute the expected length of a command or reply packet.
Packit 96c956
  These operate on the RAW NETWORK packets, from the point of view of
Packit 96c956
  integer endianness within the structures.
Packit 96c956
Packit 96c956
  */
Packit 96c956
#include "config.h"
Packit 96c956
Packit 96c956
#include "sysincl.h"
Packit 96c956
Packit 96c956
#include "util.h"
Packit 96c956
#include "pktlength.h"
Packit 96c956
Packit 96c956
#define PADDING_LENGTH_(request_length, reply_length) \
Packit 96c956
  (uint16_t)((request_length) < (reply_length) ? (reply_length) - (request_length) : 0)
Packit 96c956
Packit 96c956
#define PADDING_LENGTH(request_data, reply_data) \
Packit 96c956
  PADDING_LENGTH_(offsetof(CMD_Request, request_data), offsetof(CMD_Reply, reply_data))
Packit 96c956
Packit 96c956
#define REQ_LENGTH_ENTRY(request_data_field, reply_data_field) \
Packit 96c956
  { offsetof(CMD_Request, data.request_data_field.EOR), \
Packit 96c956
    PADDING_LENGTH(data.request_data_field.EOR, data.reply_data_field.EOR) }
Packit 96c956
Packit 96c956
#define RPY_LENGTH_ENTRY(reply_data_field) \
Packit 96c956
  offsetof(CMD_Reply, data.reply_data_field.EOR)
Packit 96c956
Packit 96c956
/* ================================================== */
Packit 96c956
Packit 96c956
struct request_length {
Packit 96c956
  uint16_t command;
Packit 96c956
  uint16_t padding;
Packit 96c956
};
Packit 96c956
Packit 96c956
static const struct request_length request_lengths[] = {
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* NULL */
Packit 96c956
  REQ_LENGTH_ENTRY(online, null),               /* ONLINE */
Packit 96c956
  REQ_LENGTH_ENTRY(offline, null),              /* OFFLINE */
Packit 96c956
  REQ_LENGTH_ENTRY(burst, null),                /* BURST */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_minpoll, null),       /* MODIFY_MINPOLL */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_maxpoll, null),       /* MODIFY_MAXPOLL */
Packit 96c956
  REQ_LENGTH_ENTRY(dump, null),                 /* DUMP */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_maxdelay, null),      /* MODIFY_MAXDELAY */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_maxdelayratio, null), /* MODIFY_MAXDELAYRATIO */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_maxupdateskew, null), /* MODIFY_MAXUPDATESKEW */
Packit 96c956
  REQ_LENGTH_ENTRY(logon, null),                /* LOGON */
Packit 96c956
  REQ_LENGTH_ENTRY(settime, manual_timestamp),  /* SETTIME */
Packit 96c956
  { 0, 0 },                                     /* LOCAL */
Packit 96c956
  REQ_LENGTH_ENTRY(manual, null),               /* MANUAL */
Packit 96c956
  REQ_LENGTH_ENTRY(null, n_sources),            /* N_SOURCES */
Packit 96c956
  REQ_LENGTH_ENTRY(source_data, source_data),   /* SOURCE_DATA */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* REKEY */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* ALLOW */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* ALLOWALL */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* DENY */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* DENYALL */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* CMDALLOW */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* CMDALLOWALL */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* CMDDENY */
Packit 96c956
  REQ_LENGTH_ENTRY(allow_deny, null),           /* CMDDENYALL */
Packit 96c956
  REQ_LENGTH_ENTRY(ac_check, null),             /* ACCHECK */
Packit 96c956
  REQ_LENGTH_ENTRY(ac_check, null),             /* CMDACCHECK */
Packit 96c956
  { 0, 0 },                                     /* ADD_SERVER */
Packit 96c956
  { 0, 0 },                                     /* ADD_PEER */
Packit 96c956
  REQ_LENGTH_ENTRY(del_source, null),           /* DEL_SOURCE */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* WRITERTC */
Packit 96c956
  REQ_LENGTH_ENTRY(dfreq, null),                /* DFREQ */
Packit 96c956
  REQ_LENGTH_ENTRY(doffset, null),              /* DOFFSET */
Packit 96c956
  REQ_LENGTH_ENTRY(null, tracking),             /* TRACKING */
Packit 96c956
  REQ_LENGTH_ENTRY(sourcestats, sourcestats),   /* SOURCESTATS */
Packit 96c956
  REQ_LENGTH_ENTRY(null, rtc),                  /* RTCREPORT */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* TRIMRTC */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* CYCLELOGS */
Packit 96c956
  { 0, 0 },                                     /* SUBNETS_ACCESSED - not supported */
Packit 96c956
  { 0, 0 },                                     /* CLIENT_ACCESSES - not supported */
Packit 96c956
  { 0, 0 },                                     /* CLIENT_ACCESSES_BY_INDEX - not supported */
Packit 96c956
  REQ_LENGTH_ENTRY(null, manual_list),          /* MANUAL_LIST */
Packit 96c956
  REQ_LENGTH_ENTRY(manual_delete, null),        /* MANUAL_DELETE */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* MAKESTEP */
Packit 96c956
  REQ_LENGTH_ENTRY(null, activity),             /* ACTIVITY */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_minstratum, null),    /* MODIFY_MINSTRATUM */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_polltarget, null),    /* MODIFY_POLLTARGET */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_maxdelaydevratio, null), /* MODIFY_MAXDELAYDEVRATIO */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* RESELECT */
Packit 96c956
  REQ_LENGTH_ENTRY(reselect_distance, null),    /* RESELECTDISTANCE */
Packit 96c956
  REQ_LENGTH_ENTRY(modify_makestep, null),      /* MODIFY_MAKESTEP */
Packit 96c956
  REQ_LENGTH_ENTRY(null, smoothing),            /* SMOOTHING */
Packit 96c956
  REQ_LENGTH_ENTRY(smoothtime, null),           /* SMOOTHTIME */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* REFRESH */
Packit 96c956
  REQ_LENGTH_ENTRY(null, server_stats),         /* SERVER_STATS */
Packit 96c956
  REQ_LENGTH_ENTRY(client_accesses_by_index,
Packit 96c956
                   client_accesses_by_index),   /* CLIENT_ACCESSES_BY_INDEX2 */
Packit 96c956
  REQ_LENGTH_ENTRY(local, null),                /* LOCAL2 */
Packit 96c956
  REQ_LENGTH_ENTRY(ntp_data, ntp_data),         /* NTP_DATA */
Packit 96c956
  { 0, 0 },                                     /* ADD_SERVER2 */
Packit 96c956
  { 0, 0 },                                     /* ADD_PEER2 */
Packit 96c956
  REQ_LENGTH_ENTRY(ntp_source, null),           /* ADD_SERVER3 */
Packit 96c956
  REQ_LENGTH_ENTRY(ntp_source, null),           /* ADD_PEER3 */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* SHUTDOWN */
Packit 96c956
  REQ_LENGTH_ENTRY(null, null),                 /* ONOFFLINE */
Packit 96c956
};
Packit 96c956
Packit 96c956
static const uint16_t reply_lengths[] = {
Packit 96c956
  0,                                            /* empty slot */
Packit 96c956
  RPY_LENGTH_ENTRY(null),                       /* NULL */
Packit 96c956
  RPY_LENGTH_ENTRY(n_sources),                  /* N_SOURCES */
Packit 96c956
  RPY_LENGTH_ENTRY(source_data),                /* SOURCE_DATA */
Packit 96c956
  0,                                            /* MANUAL_TIMESTAMP */
Packit 96c956
  RPY_LENGTH_ENTRY(tracking),                   /* TRACKING */
Packit 96c956
  RPY_LENGTH_ENTRY(sourcestats),                /* SOURCESTATS */
Packit 96c956
  RPY_LENGTH_ENTRY(rtc),                        /* RTC */
Packit 96c956
  0,                                            /* SUBNETS_ACCESSED - not supported */
Packit 96c956
  0,                                            /* CLIENT_ACCESSES - not supported */
Packit 96c956
  0,                                            /* CLIENT_ACCESSES_BY_INDEX - not supported */
Packit 96c956
  0,                                            /* MANUAL_LIST - not supported */
Packit 96c956
  RPY_LENGTH_ENTRY(activity),                   /* ACTIVITY */
Packit 96c956
  RPY_LENGTH_ENTRY(smoothing),                  /* SMOOTHING */
Packit 96c956
  RPY_LENGTH_ENTRY(server_stats),               /* SERVER_STATS */
Packit 96c956
  RPY_LENGTH_ENTRY(client_accesses_by_index),   /* CLIENT_ACCESSES_BY_INDEX2 */
Packit 96c956
  RPY_LENGTH_ENTRY(ntp_data),                   /* NTP_DATA */
Packit 96c956
  RPY_LENGTH_ENTRY(manual_timestamp),           /* MANUAL_TIMESTAMP2 */
Packit 96c956
  RPY_LENGTH_ENTRY(manual_list),                /* MANUAL_LIST2 */
Packit 96c956
};
Packit 96c956
Packit 96c956
/* ================================================== */
Packit 96c956
Packit 96c956
int
Packit 96c956
PKL_CommandLength(CMD_Request *r)
Packit 96c956
{
Packit 96c956
  uint32_t type;
Packit 96c956
  int command_length;
Packit 96c956
Packit 96c956
  assert(sizeof (request_lengths) / sizeof (request_lengths[0]) == N_REQUEST_TYPES);
Packit 96c956
Packit 96c956
  type = ntohs(r->command);
Packit 96c956
  if (type >= N_REQUEST_TYPES)
Packit 96c956
    return 0;
Packit 96c956
Packit 96c956
  command_length = request_lengths[type].command;
Packit 96c956
  if (!command_length)
Packit 96c956
    return 0;
Packit 96c956
Packit 96c956
  return command_length + PKL_CommandPaddingLength(r);
Packit 96c956
}
Packit 96c956
Packit 96c956
/* ================================================== */
Packit 96c956
Packit 96c956
int
Packit 96c956
PKL_CommandPaddingLength(CMD_Request *r)
Packit 96c956
{
Packit 96c956
  uint32_t type;
Packit 96c956
Packit 96c956
  if (r->version < PROTO_VERSION_PADDING)
Packit 96c956
    return 0;
Packit 96c956
Packit 96c956
  type = ntohs(r->command);
Packit 96c956
Packit 96c956
  if (type >= N_REQUEST_TYPES)
Packit 96c956
    return 0;
Packit 96c956
Packit 96c956
  return request_lengths[ntohs(r->command)].padding;
Packit 96c956
}
Packit 96c956
Packit 96c956
/* ================================================== */
Packit 96c956
Packit 96c956
int
Packit 96c956
PKL_ReplyLength(CMD_Reply *r)
Packit 96c956
{
Packit 96c956
  uint32_t type;
Packit 96c956
Packit 96c956
  assert(sizeof (reply_lengths) / sizeof (reply_lengths[0]) == N_REPLY_TYPES);
Packit 96c956
Packit 96c956
  type = ntohs(r->reply);
Packit 96c956
Packit 96c956
  /* Note that reply type codes start from 1, not 0 */
Packit 96c956
  if (type < 1 || type >= N_REPLY_TYPES)
Packit 96c956
    return 0;
Packit 96c956
Packit 96c956
  return reply_lengths[type];
Packit 96c956
}
Packit 96c956
Packit 96c956
/* ================================================== */
Packit 96c956