Bump Standards-Version to 2.2.0.0.
[userv-utils] / ipif / mech-sequence.c
1 /*
2 * Sequence number / nonce mechanism for udp tunnel
3 *
4 * mechanisms: nonce, sequence
5 * arguments: none
6 *
7 * restrictions: none
8 * encoding: prepend 4 bytes of sequence arithmetic serial number
9 * decoding: check increasingness (sequence), or ignore (nonce)
10 */
11 /*
12 * This file is part of ipif, part of userv-utils
13 *
14 * Copyright 1996-2013 Ian Jackson <ijackson@chiark.greenend.org.uk>
15 * Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
16 * Copyright 1999,2003
17 * Chancellor Masters and Scholars of the University of Cambridge
18 * Copyright 2010 Tony Finch <fanf@dotat.at>
19 *
20 * This is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 3 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful, but
26 * WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with userv-utils; if not, see http://www.gnu.org/licenses/.
32 */
33
34 #include <netinet/in.h>
35
36 #include "forwarder.h"
37
38 struct mechdata {
39 uint32_t number;
40 int anyseen; /* decode only */
41 };
42
43 static void mes_sequence(struct mechdata **md_r, int *maxprefix_io, int *maxsuffix_io) {
44 struct mechdata *md;
45
46 XMALLOC(md);
47 get_random(&md->number,sizeof(md->number));
48 *maxprefix_io += 4;
49 *md_r= md;
50 }
51
52 static void mds_sequence(struct mechdata **md_r) {
53 struct mechdata *md;
54 XMALLOC(md);
55 md->anyseen= 0;
56 *md_r= md;
57 }
58
59 static void menc_sequence(struct mechdata *md, struct buffer *buf) {
60 md->number++;
61 *(uint32_t*)buf_prepend(buf,4)= htonl(md->number);
62 }
63
64 static const char *mdec_check(struct mechdata *md, struct buffer *buf) {
65 uint32_t *sp, sequence;
66
67 BUF_UNPREPEND(sp,buf,4);
68 sequence= ntohl(*sp);
69
70 if (md->anyseen)
71 if (sequence - md->number >= 0x800000UL) return "out of order packet";
72
73 md->number= sequence;
74 md->anyseen= 1;
75
76 return 0;
77 }
78
79 static const char *mdec_skip(struct mechdata *md, struct buffer *buf) {
80 uint32_t *sp;
81 BUF_UNPREPEND(sp,buf,4);
82 return 0;
83 }
84
85 const struct mechanism mechlist_sequence[]= {
86 { "nonce", mes_sequence, mds_sequence, menc_sequence, mdec_skip },
87 { "sequence", mes_sequence, mds_sequence, menc_sequence, mdec_check },
88 { 0 }
89 };