/* * Timestamp mechanism for udp tunnel * * mechanism: timestamp * arguments: * * restrictions: none * encoding: prepend 4 bytes of UNIX time in network byte order * * is maximum age in seconds we will accept a packet (or 0 * for any age); is maximum future age in seconds we will * accept a packet (or 0 for any future age). * */ /* * This file is part of ipif, part of userv-utils * * Copyright 1996-2013 Ian Jackson * Copyright 1998 David Damerell * Copyright 1999,2003 * Chancellor Masters and Scholars of the University of Cambridge * Copyright 2010 Tony Finch * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * 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 userv-utils; if not, see http://www.gnu.org/licenses/. */ #include #include #include "forwarder.h" #define WARN_EVERY 30 struct mechdata { time_t max_skew, max_age; time_t next_warn; }; static void mds_timestamp(struct mechdata **md_r) { struct mechdata *md; md= xmalloc(sizeof(md)); md->max_skew= getarg_ulong(); md->max_age= getarg_ulong(); md->next_warn= now(); *md_r= md; } static void mes_timestamp(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_io) { mds_timestamp(md_r); *maxprefix_io += 4; } static void menc_timestamp(struct mechdata *md, struct buffer *buf) { *(uint32_t*)buf_prepend(buf,4)= htonl(now()); } static const char *mdec_timestamp(struct mechdata *md, struct buffer *buf) { static char cbuf[40]; uint32_t *tp, timestamp; time_t tnow; long age; BUF_UNPREPEND(tp,buf,4); timestamp= ntohl(*tp); tnow= now(); age= timestamp - (uint32_t)tnow; if (age > 0) { if (!md->max_age || age <= md->max_age) return 0; sprintf(cbuf,"packet too old (%lds)",age); } else if (age < 0) { if (!md->max_skew || age >= -md->max_skew) return 0; sprintf(cbuf,"too much skew (%lds)",-age); } else { return 0; } if (tnow < md->next_warn) return ""; md->next_warn= tnow+WARN_EVERY; return cbuf; } STANDARD_MECHANISMLIST("timestamp",timestamp);