| 1 | /* |
| 2 | * This file is part of secnet. |
| 3 | * See README for full list of copyright holders. |
| 4 | * |
| 5 | * secnet is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 3 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * secnet is distributed in the hope that it will be useful, but |
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 13 | * General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * version 3 along with secnet; if not, see |
| 17 | * https://www.gnu.org/licenses/gpl.html. |
| 18 | */ |
| 19 | |
| 20 | #ifndef TRANSFORM_COMMON_H |
| 21 | #define TRANSFORM_COMMON_H |
| 22 | |
| 23 | #include "magic.h" |
| 24 | |
| 25 | #define KEYED_CHECK do{ \ |
| 26 | if (!ti->keyed) { \ |
| 27 | *errmsg="transform unkeyed"; \ |
| 28 | return transform_apply_err; \ |
| 29 | } \ |
| 30 | }while(0) |
| 31 | |
| 32 | #define RECVBITMAP_SIZE 32 |
| 33 | typedef uint32_t recvbitmap_type; |
| 34 | |
| 35 | #define SEQNUM_CHECK(seqnum, p) do{ \ |
| 36 | uint32_t skew=seqnum-ti->lastrecvseq; \ |
| 37 | if (skew<0x8fffffff) { \ |
| 38 | /* Ok */ \ |
| 39 | ti->lastrecvseq=seqnum; \ |
| 40 | if (skew < RECVBITMAP_SIZE) \ |
| 41 | ti->recvbitmap <<= skew; \ |
| 42 | else \ |
| 43 | ti->recvbitmap=0; \ |
| 44 | skew=0; \ |
| 45 | } else if ((0-skew)<(p)->max_seq_skew) { \ |
| 46 | /* Ok */ \ |
| 47 | } else { \ |
| 48 | /* Too much skew */ \ |
| 49 | *errmsg="seqnum: too much skew"; \ |
| 50 | return transform_apply_seqrange; \ |
| 51 | } \ |
| 52 | if ((p)->dedupe) { \ |
| 53 | recvbitmap_type recvbit=(uint32_t)1 << skew; \ |
| 54 | if (ti->recvbitmap & recvbit) { \ |
| 55 | *errmsg="seqnum: duplicate"; \ |
| 56 | return transform_apply_seqdupe; \ |
| 57 | } \ |
| 58 | ti->recvbitmap |= recvbit; \ |
| 59 | } \ |
| 60 | }while(0) |
| 61 | |
| 62 | #define SEQNUM_KEYED_FIELDS \ |
| 63 | uint32_t sendseq; \ |
| 64 | uint32_t lastrecvseq; \ |
| 65 | recvbitmap_type recvbitmap; /* 1<<0 is lastrecvseq (i.e., most recent) */ \ |
| 66 | bool_t keyed |
| 67 | |
| 68 | #define SEQNUM_KEYED_INIT(initlastrecvseq,initsendseq) \ |
| 69 | (ti->lastrecvseq=(initlastrecvseq), \ |
| 70 | ti->sendseq=(initsendseq), \ |
| 71 | ti->recvbitmap=0, \ |
| 72 | ti->keyed=True) |
| 73 | |
| 74 | #define TRANSFORM_VALID \ |
| 75 | static bool_t transform_valid(void *sst) \ |
| 76 | { \ |
| 77 | struct transform_inst *ti=sst; \ |
| 78 | \ |
| 79 | return ti->keyed; \ |
| 80 | } |
| 81 | |
| 82 | #define TRANSFORM_DESTROY \ |
| 83 | static void transform_destroy(void *sst) \ |
| 84 | { \ |
| 85 | struct transform_inst *st=sst; \ |
| 86 | \ |
| 87 | FILLZERO(*st); /* Destroy key material */ \ |
| 88 | free(st); \ |
| 89 | } |
| 90 | |
| 91 | #define SET_CAPAB_TRANSFORMNUM(def) do{ \ |
| 92 | st->ops.capab_transformnum=dict_read_number(dict, "capab-num", \ |
| 93 | False, "transform", loc, (def)); \ |
| 94 | if (st->ops.capab_transformnum > CAPAB_TRANSFORMNUM_MAX) \ |
| 95 | cfgfatal(loc,"transform","capab-num out of range 0..%d\n", \ |
| 96 | CAPAB_TRANSFORMNUM_MAX); \ |
| 97 | }while(0) |
| 98 | |
| 99 | #define TRANSFORM_CREATE_CORE \ |
| 100 | struct transform_inst *ti; \ |
| 101 | NEW(ti); \ |
| 102 | /* mlock XXX */ \ |
| 103 | ti->ops.st=ti; \ |
| 104 | ti->ops.setkey=transform_setkey; \ |
| 105 | ti->ops.valid=transform_valid; \ |
| 106 | ti->ops.delkey=transform_delkey; \ |
| 107 | ti->ops.forwards=transform_forward; \ |
| 108 | ti->ops.reverse=transform_reverse; \ |
| 109 | ti->ops.destroy=transform_destroy; \ |
| 110 | ti->keyed=False; |
| 111 | |
| 112 | #define SEQNUM_PARAMS_FIELDS \ |
| 113 | uint32_t max_seq_skew; \ |
| 114 | bool_t dedupe; |
| 115 | |
| 116 | #define SEQNUM_PARAMS_INIT(dict,p,desc,loc) \ |
| 117 | (p)->max_seq_skew=dict_read_number((dict), "max-sequence-skew", \ |
| 118 | False, (desc), (loc), 10); \ |
| 119 | bool_t can_dedupe=(p)->max_seq_skew < RECVBITMAP_SIZE; \ |
| 120 | (p)->dedupe=dict_read_bool((dict), "dedupe", \ |
| 121 | False,(desc),(loc), can_dedupe); \ |
| 122 | if ((p)->dedupe && !can_dedupe) \ |
| 123 | cfgfatal(loc,"transform", \ |
| 124 | "cannot dedupe with max-sequence-skew>=32"); \ |
| 125 | else (void)0 |
| 126 | |
| 127 | #endif /*TRANSFORM_COMMON_H*/ |