chiark / gitweb /
@@ -1,6 +1,7 @@
[userv-utils.git] / ipif / mech-timestamp.c
diff --git a/ipif/mech-timestamp.c b/ipif/mech-timestamp.c
new file mode 100644 (file)
index 0000000..f679b10
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Timestamp mechanism
+ *
+ * arguments: <max-skew> <max-age>
+ *
+ * encoding: prepend 4 bytes of UNIX time in network byte order
+ *
+ * <max-age> is maximum age in seconds we will accept a packet (or 0
+ * for any age); <max-skew> is maximum future age in seconds we will
+ * accept a packet (or 0 for any future age).
+ *
+ */
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+#include "mech.h"
+
+struct mechdata {
+  uint32_t max_skew, max_age;
+};
+
+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_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, tnow;
+  long age;
+
+  BUF_UNPREPEND(tp,buf,4);
+  timestamp= ntohl(*tp);
+
+  tnow= now();
+  age= timestamp - tnow;
+  if (age > 0) {
+    if (md->max_age && age > md->max_age) {
+      sprintf(cbuf,"packet too old (%lds)",age);
+      return cbuf;
+    }
+  } else if (age < 0) {
+    if (md->max_skew && age > md->max_skew) {
+      sprintf(cbuf,"too much skew (%lds)",-age);
+      return cbuf;
+    }
+  }
+
+  return 0;
+}
+
+STANDARD_MECHANISMLIST("timestamp",timestamp);