From 378c3572cf366f5cd817fb5f9620a70fcfb309ad Mon Sep 17 00:00:00 2001 From: CIFuzz Date: Fri, 1 Dec 2023 01:03:54 +0000 Subject: [PATCH] Coverage upload --- coverage/latest/dumps/merged.profdata | Bin 10496 -> 10496 bytes coverage/latest/dumps/test_libfuzzer.profdata | Bin 10496 -> 10496 bytes coverage/latest/logs/test_libfuzzer.log | 22 +- .../compat/arc4random.c.html | 2 +- .../compat/arc4random_linux.h.html | 2 +- .../compat/arc4random_uniform.c.html | 2 +- .../compat/chacha_private.h.html | 2 +- .../openiked-portable/compat/freezero.c.html | 2 +- .../compat/getdtablecount.c.html | 2 +- .../openiked-portable/compat/getrtable.c.html | 2 +- .../compat/imsg-buffer.c.html | 2 +- .../src/openiked-portable/compat/imsg.c.html | 2 +- .../src/openiked-portable/compat/imsg.h.html | 2 +- .../compat/openbsd-compat.h.html | 2 +- .../compat/recallocarray.c.html | 2 +- .../compat/setproctitle.c.html | 2 +- .../openiked-portable/compat/strlcat.c.html | 2 +- .../openiked-portable/compat/strlcpy.c.html | 2 +- .../openiked-portable/compat/strtonum.c.html | 2 +- .../openiked-portable/compat/sys/queue.h.html | 2 +- .../openiked-portable/compat/sys/tree.h.html | 2 +- .../src/openiked-portable/compat/vis.c.html | 2 +- .../src/openiked-portable/compat/vis.h.html | 2 +- .../src/openiked-portable/iked/iked.h.html | 2 +- .../src/openiked-portable/iked/ikev2.h.html | 2 +- .../openiked-portable/iked/ikev2_pld.c.html | 2 +- .../openiked-portable/iked/imsg_util.c.html | 2 +- .../src/openiked-portable/iked/log.c.html | 2 +- .../src/openiked-portable/iked/types.h.html | 2 +- .../src/openiked-portable/iked/util.c.html | 2 +- .../regress/parser-libfuzzer/common.c.html | 2 +- .../parser-libfuzzer/test_parser_fuzz.c.html | 2 +- .../compat/arc4random.c.html | 2 +- .../compat/arc4random_linux.h.html | 2 +- .../compat/arc4random_uniform.c.html | 2 +- .../compat/chacha_private.h.html | 2 +- .../openiked-portable/compat/freezero.c.html | 2 +- .../compat/getdtablecount.c.html | 2 +- .../openiked-portable/compat/getrtable.c.html | 2 +- .../compat/imsg-buffer.c.html | 2 +- .../src/openiked-portable/compat/imsg.c.html | 2 +- .../src/openiked-portable/compat/imsg.h.html | 2 +- .../compat/openbsd-compat.h.html | 2 +- .../compat/recallocarray.c.html | 2 +- .../compat/setproctitle.c.html | 2 +- .../openiked-portable/compat/strlcat.c.html | 2 +- .../openiked-portable/compat/strlcpy.c.html | 2 +- .../openiked-portable/compat/strtonum.c.html | 2 +- .../openiked-portable/compat/sys/queue.h.html | 2 +- .../openiked-portable/compat/sys/tree.h.html | 2 +- .../src/openiked-portable/compat/vis.c.html | 2 +- .../src/openiked-portable/compat/vis.h.html | 2 +- .../src/openiked-portable/iked/iked.h.html | 2 +- .../src/openiked-portable/iked/ikev2.h.html | 2 +- .../openiked-portable/iked/ikev2_pld.c.html | 2 +- .../openiked-portable/iked/imsg_util.c.html | 2 +- .../src/openiked-portable/iked/log.c.html | 2 +- .../src/openiked-portable/iked/types.h.html | 2 +- .../src/openiked-portable/iked/util.c.html | 2 +- .../regress/parser-libfuzzer/common.c.html | 2 +- .../parser-libfuzzer/test_parser_fuzz.c.html | 2 +- .../textcov_reports/test_libfuzzer.covreport | 1626 ++++++++--------- 62 files changed, 882 insertions(+), 882 deletions(-) diff --git a/coverage/latest/dumps/merged.profdata b/coverage/latest/dumps/merged.profdata index c8b53348002f06996522a5b177135d895243e222..2d86b80cace731f16f5901a80d9878dac59fd602 100644 GIT binary patch delta 1855 zcmY*aUrd`-6u;jsl=h>A{-Hn%D=h`Lq5K)hzbwObrK~Lu%g7*@kzq2!8Y8iDAud^H zb>IVACVDb#YDgd&N8++jh$CjvY$m+G+$4J-kSyt#(>*vV#5ecgcfWHlk-q%yIp=r& ze&^oCPsUG924V|OOoaUeE=_7wIWyI#qG`VhyLJghGV>{(grCqKHFEzAS!GhrPeYb^ z%Iww0NZg@S4cC0=fbN92W^+{iS3#YM=uXJp{d!fN7(u^mRU%~Y7W$_zV+8b4jEx4B zk@8_Fxtu?9$Eci22+4Gy#?1|XkLIbTd3Z;vl`7$LsYqYTZF7*4&dX<9Tr7ZU+F`y~ zh~gD2jEun;9dX=0hT3f<1^a!%(kZ`n1H_68p-OXvuJl7h)86_gXP)EC?qX#6_)L3w zi!V`4{FQh(3%_ep_2XJGG1LlK;Lzq?{m>?O%}y}cb&$yl(0Bv1W_uZ2%3h-V51~=p zZmxR;ef&5&G6ECY8}=%msG5(^ha{2>p`06%5q5Ig96!|IR}(n>S&Patyb2-R+wyEP z`uwAXwX8zbVumaD0uW?DFYYuJ@(lIrd-8OO?LRC+aRs)mL5U9+{Y@v zA_w)ZH!;*YJeI#K7t0h4;0%|pK2Xg+m1B9ox?n1|Q@ROTxqS{%6b2wG1S-XQ` zM9bo-;G8**0)8pLQzgH5A#Nz*SPQh^G`;47!GZ-ke?aNW3H7#CHjejgU2JoIv^fu* z8bbOGza`I4pp4Hf52e6LKb~JK8Vb89mBVnRIFc(~DFwl+j4Eu_DZRH#<8aD8z(~q4 z*%;XqvSmL?7oI?c;{}}<0c*(#z34Owk&>XGt&}tzTE2?O1d1{Sc&n?t=xGmH5>Qj> zW$B`&U6KXvmX1mD;NKUL>R@u;A1v}kXD@4f&FR%BFEqr9ZBSL#WELxZ*o=XCAX?T( zJ8kM3Jugc*#Q)1We_Di`z6?oMkj^&4Ggr_O=QnH@lWZCq5>LWMZYN8eaC_ya-{UrK zybDj=JxtqD9<)z?h^dXQAs*&EMj%<<;TEs`X}&OmovK6j*C2WPtigaMOdoeb(({JW V`ljbL3;#t$7hN4%+^TS9{Rd#pLZtuz delta 1852 zcmZ8iZ%kWN6utBoN`coxOKBCEvP!oieArk=+qG30Y$|9*fJ_$&8M-lzGj7GX zU?PdxJk}B7hix&bN&?wPMz+NSW0pl@Kd@{eF)<=eHxofKml@5XzWdHSi}QW?o&V?D zbI-YNY{%G+W2x-5f`f^V@Vg0v&VSSODX#AE?9I+F721W zs8j!wXW5viSXV4Y(E;5Vt2OO@t%6>~<9kTzppou4) z)0N0hU}5YnILcr3T-u7#H7$ks-W2Jy@2U;5)s?W$u!)cM!jK`}wi-jtZ4csV6=H|% zX;L2XE{fTO5E4(pPlhv*Dg$*4rNk5Fm+qJ6mmuc!fkQRHuf`O=6M?p(n1DBm=6Q1g zqQ!A%_(AkZVC&c`@J?}FZIp?cWD7gch#4VMl2>eSt7Nn1`v$xr{L4bz1r_V931L0A8*VtF^c@PYMlWg1qjJsv6w12A@9Rn;(T z+syxnz_e{U-(7&awoLX`1WgI4%%TsmT;kuBZTx*N$_XivIzkj8&DEfcKck|Y225JR zrP4-E_z-fJ<#;ueBj3MKbapG% z%eIMLyY0^kc-fvZQ|vYP+@ARFQaBvXTj)LvkBNGeJmef7>EQxVu&ZV`=xpWjc9?T+ zQ;*bOZGCco9&jPQ0bJ!5MY2Vs57x@t8dF(Rq~#Rlq~YIk*L|pF9nj^fQX1h!S9hBF z^98*V(&l4{1YcGl6_QJrkqWtsY(4ObU3@VL0~Kfa>_d7@5qFy?Z?C&kjO}M`U-Q}v z==O_TkrQ$%@r|WijE(jpePhm6+0A)&JM>o%S?P(=5Mo-Nx|}9$PvgoFcv|ffMp`FD z55@bjqHf{W3J~(F^4tixyic0xq%XmcH%(?=c{enlp1@>;R7RgX>iiy*yc#6U6F=kMVu zw?0ER{gWR0xm=a+3h~w~Ox30N`4;%GE?s^{jz8hbr09l$Y4}>eClXHvVwU9@9Oc1& z_#v=UNL%aEYGOa8UU(R>Ri1GGrs|Ucdg^z{Nh9mtN6{KU2`0n=Q^78NI|Ea}cJ1ij T1kZ`^?}a+~{GPd$kk9xp=qN&d diff --git a/coverage/latest/dumps/test_libfuzzer.profdata b/coverage/latest/dumps/test_libfuzzer.profdata index c29d358904241fd9985ad79b70c5c61edaa698de..8010f7a2c326d5f0b43b6d3977f140f270784765 100644 GIT binary patch delta 1856 zcmY*aZA@EL7(Vy3biJ1r`az*Bth9W%iSi-H$2Ns^EzlM>*$f~FWRT3T#)O1v$d)X$ zy5SF4Ci+HfYA_JZMs!&y#F52lbP0c8Zj${VkSysi)BSL%EdFyb-gDn`h}=KVdESrn zew_E58$T64H5H02KC%$@30$7iX*@ICqoL)12D^F*DVhBUSHe%okD9svrlMI=Zl4Cd zw#w|4$4K05&=gk#=z#8oc<1(M@-Me9z*Gl8iIWvvT*9RVS<=5A1ZXO)74&x>Vk*<7ML$2XblV`ls&5)K)N)Mn`>0y~q zDq-3C26}J6L*?@lF-#*N?BVj2dz$*k5=`<}FHC25NH<_RyT>i^zzqo5lZX@EH8s-@ z>fl?`n>4ct&rOlo#X2+IdRJzK@L&T->hpVNCV@Fbw1b>3C#!SnlSu zvtB!LBeK|Z2hQfc&4hPyga5x27Rwn$oQJ)UyqJuwTY$zuw-p_ zjTd2V{rvtMv?Ff-yX_l)G={9Z0Wra~gj;)1OxpO22;Po`kb3ynHYmkm$55aReawD1 zESk0=9uL09JVyb)kuDrmEA>FF<1icZVTZ@oHH3E0 z_=S0L9KLkq%d5R8e!BF7qnm0?b%v}M@QoG6e z$lj1`*HOCo2+G_~>BK153y;g9un~wBhK1Q`Vcjb$S1_hPUI6Lmm96nqXG&3%fU2Uf zWP|fXEiCBmqDg51TK7k!8kpMu2iy6Ar<LW;pN9ob__`Qmd@agv z-{Dkmz5`7qVb{!i7~1?Y;t^hB6p|%vKJnc5@%a(fsT#EY3Z&9jR$!>KlRoT#WNC|9 V`c~;J7VXor6Lf88X}ip${}0vKLU;fG delta 1849 zcmZ8iZ)jUp6u<8#?ebpI=3mq1C2i6)(b{Pjmo2puHOrc&d2w!axHTVI+AtlKV#QTu z6SveU6%5GSF|HJmDnfOImaeeUiBOa=6!W2DqacX2sGDFr(J@iR^xb#v9nO6D-Sh9B zbAIofo6&uv`%Y#GSIQ2;egeNQnhg0r7^NHI zHp3&8z*4N-fAX^`{p2TPERC8FH~eW`WjLE#|^DC z?VPSfv519{*WnHNvhTt!)Nbf0*zYx#PXArDLBU%Kn@x|>ksJ(~Qajd@Xu07-T(3jy z;GCv;i?>is&PVX@6#Q(Oi`AI~W2hCfz^RqH^;0X5bOykoTHv}lLvO}lM@5pss}&1$ zYZ>B|DQEOvjOj$`$V>26<&@gO6SZ;*JJ5-kA-ieP_d_#&FM%bs-LP+O0<)!8vO(Um zhenUVoTXbD11f9EVjEttQVGlETIH`+6qhUpK}Goy^_6!qGUEnE0KhOPodnHBG2xk7%E)A+}8s23;_sl(!gDCR29@1IdoF9wWz z!-c9AU-TGC7x{QKyHM`m&dA&)zMz;w>yK!@#P@M%1c?!{*skCZmfA1`1Jx<|w{~Y( zzNzkFTzl+USzNjS&)RcL`Gr08-=%Oko>s*7Fg?WTk*1*J_}I8E6bHL1!%=5DO(kI7 z*`=PS$J+Y%{@mk6c^kN0XOfu$N*bS*61U#w3m!l->EJUWLhhLE&7tCq!X}T?PE?ljf_C{ zc&w>A>6J1>eCxC{3~v7uvS{pi81!qx?Q8$GtsfOJr$F8a>EoR(974_8VZ;|lvvf(Pb`Dow(D}6bTH0f_MjCwt=IoReD!yI+uMM-!e*h4cO zV}Py&$9>|T

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * ChaCha based random number generator for OpenBSD.
24
 */
25
26
#include <fcntl.h>
27
#include <limits.h>
28
#include <signal.h>
29
#include <stdint.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
#include <sys/types.h>
34
#include <sys/time.h>
35
36
#define KEYSTREAM_ONLY
37
#include "chacha_private.h"
38
39
0
#define minimum(a, b) ((a) < (b) ? (a) : (b))
40
41
#if defined(__GNUC__) || defined(_MSC_VER)
42
#define inline __inline
43
#else       /* __GNUC__ || _MSC_VER */
44
#define inline
45
#endif        /* !__GNUC__ && !_MSC_VER */
46
47
0
#define KEYSZ 32
48
0
#define IVSZ  8
49
#define BLOCKSZ 64
50
#define RSBUFSZ (16*BLOCKSZ)
51
52
0
#define REKEY_BASE  (1024*1024) /* NB. should be a power of 2 */
53
54
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
55
static struct _rs {
56
  size_t    rs_have;  /* valid bytes at end of rs_buf */
57
  size_t    rs_count; /* bytes till reseed */
58
} *rs;
59
60
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
61
static struct _rsx {
62
  chacha_ctx  rs_chacha;  /* chacha context for random keystream */
63
  u_char    rs_buf[RSBUFSZ];  /* keystream blocks */
64
} *rsx;
65
66
static inline int _rs_allocate(struct _rs **, struct _rsx **);
67
static inline void _rs_forkdetect(void);
68
#include "arc4random.h"
69
70
static inline void _rs_rekey(u_char *dat, size_t datlen);
71
72
static inline void
73
_rs_init(u_char *buf, size_t n)
74
0
{
75
0
  if (n < KEYSZ + IVSZ)
76
0
    return;
77
78
0
  if (rs == NULL) {
79
0
    if (_rs_allocate(&rs, &rsx) == -1)
80
0
      _exit(1);
81
0
  }
82
83
0
  chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
84
0
  chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
85
0
}
86
87
static void
88
_rs_stir(void)
89
0
{
90
0
  u_char rnd[KEYSZ + IVSZ];
91
0
  uint32_t rekey_fuzz = 0;
92
93
0
  if (getentropy(rnd, sizeof rnd) == -1)
94
0
    _getentropy_fail();
95
96
0
  if (!rs)
97
0
    _rs_init(rnd, sizeof(rnd));
98
0
  else
99
0
    _rs_rekey(rnd, sizeof(rnd));
100
0
  explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
101
102
  /* invalidate rs_buf */
103
0
  rs->rs_have = 0;
104
0
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
105
106
  /* rekey interval should not be predictable */
107
0
  chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
108
0
      (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
109
0
  rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
110
0
}
111
112
static inline void
113
_rs_stir_if_needed(size_t len)
114
0
{
115
0
  _rs_forkdetect();
116
0
  if (!rs || rs->rs_count <= len)
117
0
    _rs_stir();
118
0
  if (rs->rs_count <= len)
119
0
    rs->rs_count = 0;
120
0
  else
121
0
    rs->rs_count -= len;
122
0
}
123
124
static inline void
125
_rs_rekey(u_char *dat, size_t datlen)
126
0
{
127
#ifndef KEYSTREAM_ONLY
128
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
129
#endif
130
  /* fill rs_buf with the keystream */
131
0
  chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
132
0
      rsx->rs_buf, sizeof(rsx->rs_buf));
133
  /* mix in optional user provided data */
134
0
  if (dat) {
135
0
    size_t i, m;
136
137
0
    m = minimum(datlen, KEYSZ + IVSZ);
138
0
    for (i = 0; i < m; i++)
139
0
      rsx->rs_buf[i] ^= dat[i];
140
0
  }
141
  /* immediately reinit for backtracking resistance */
142
0
  _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
143
0
  memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
144
0
  rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
145
0
}
146
147
static inline void
148
_rs_random_buf(void *_buf, size_t n)
149
0
{
150
0
  u_char *buf = (u_char *)_buf;
151
0
  u_char *keystream;
152
0
  size_t m;
153
154
0
  _rs_stir_if_needed(n);
155
0
  while (n > 0) {
156
0
    if (rs->rs_have > 0) {
157
0
      m = minimum(n, rs->rs_have);
158
0
      keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
159
0
          - rs->rs_have;
160
0
      memcpy(buf, keystream, m);
161
0
      memset(keystream, 0, m);
162
0
      buf += m;
163
0
      n -= m;
164
0
      rs->rs_have -= m;
165
0
    }
166
0
    if (rs->rs_have == 0)
167
0
      _rs_rekey(NULL, 0);
168
0
  }
169
0
}
170
171
static inline void
172
_rs_random_u32(uint32_t *val)
173
0
{
174
0
  u_char *keystream;
175
176
0
  _rs_stir_if_needed(sizeof(*val));
177
0
  if (rs->rs_have < sizeof(*val))
178
0
    _rs_rekey(NULL, 0);
179
0
  keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
180
0
  memcpy(val, keystream, sizeof(*val));
181
0
  memset(keystream, 0, sizeof(*val));
182
0
  rs->rs_have -= sizeof(*val);
183
0
}
184
185
uint32_t
186
arc4random(void)
187
0
{
188
0
  uint32_t val;
189
190
0
  _ARC4_LOCK();
191
0
  _rs_random_u32(&val);
192
0
  _ARC4_UNLOCK();
193
0
  return val;
194
0
}
195
196
void
197
arc4random_buf(void *buf, size_t n)
198
0
{
199
0
  _ARC4_LOCK();
200
0
  _rs_random_buf(buf, n);
201
0
  _ARC4_UNLOCK();
202
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * ChaCha based random number generator for OpenBSD.
24
 */
25
26
#include <fcntl.h>
27
#include <limits.h>
28
#include <signal.h>
29
#include <stdint.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
#include <sys/types.h>
34
#include <sys/time.h>
35
36
#define KEYSTREAM_ONLY
37
#include "chacha_private.h"
38
39
0
#define minimum(a, b) ((a) < (b) ? (a) : (b))
40
41
#if defined(__GNUC__) || defined(_MSC_VER)
42
#define inline __inline
43
#else       /* __GNUC__ || _MSC_VER */
44
#define inline
45
#endif        /* !__GNUC__ && !_MSC_VER */
46
47
0
#define KEYSZ 32
48
0
#define IVSZ  8
49
#define BLOCKSZ 64
50
#define RSBUFSZ (16*BLOCKSZ)
51
52
0
#define REKEY_BASE  (1024*1024) /* NB. should be a power of 2 */
53
54
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
55
static struct _rs {
56
  size_t    rs_have;  /* valid bytes at end of rs_buf */
57
  size_t    rs_count; /* bytes till reseed */
58
} *rs;
59
60
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
61
static struct _rsx {
62
  chacha_ctx  rs_chacha;  /* chacha context for random keystream */
63
  u_char    rs_buf[RSBUFSZ];  /* keystream blocks */
64
} *rsx;
65
66
static inline int _rs_allocate(struct _rs **, struct _rsx **);
67
static inline void _rs_forkdetect(void);
68
#include "arc4random.h"
69
70
static inline void _rs_rekey(u_char *dat, size_t datlen);
71
72
static inline void
73
_rs_init(u_char *buf, size_t n)
74
0
{
75
0
  if (n < KEYSZ + IVSZ)
76
0
    return;
77
78
0
  if (rs == NULL) {
79
0
    if (_rs_allocate(&rs, &rsx) == -1)
80
0
      _exit(1);
81
0
  }
82
83
0
  chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
84
0
  chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
85
0
}
86
87
static void
88
_rs_stir(void)
89
0
{
90
0
  u_char rnd[KEYSZ + IVSZ];
91
0
  uint32_t rekey_fuzz = 0;
92
93
0
  if (getentropy(rnd, sizeof rnd) == -1)
94
0
    _getentropy_fail();
95
96
0
  if (!rs)
97
0
    _rs_init(rnd, sizeof(rnd));
98
0
  else
99
0
    _rs_rekey(rnd, sizeof(rnd));
100
0
  explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
101
102
  /* invalidate rs_buf */
103
0
  rs->rs_have = 0;
104
0
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
105
106
  /* rekey interval should not be predictable */
107
0
  chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
108
0
      (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
109
0
  rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
110
0
}
111
112
static inline void
113
_rs_stir_if_needed(size_t len)
114
0
{
115
0
  _rs_forkdetect();
116
0
  if (!rs || rs->rs_count <= len)
117
0
    _rs_stir();
118
0
  if (rs->rs_count <= len)
119
0
    rs->rs_count = 0;
120
0
  else
121
0
    rs->rs_count -= len;
122
0
}
123
124
static inline void
125
_rs_rekey(u_char *dat, size_t datlen)
126
0
{
127
#ifndef KEYSTREAM_ONLY
128
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
129
#endif
130
  /* fill rs_buf with the keystream */
131
0
  chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
132
0
      rsx->rs_buf, sizeof(rsx->rs_buf));
133
  /* mix in optional user provided data */
134
0
  if (dat) {
135
0
    size_t i, m;
136
137
0
    m = minimum(datlen, KEYSZ + IVSZ);
138
0
    for (i = 0; i < m; i++)
139
0
      rsx->rs_buf[i] ^= dat[i];
140
0
  }
141
  /* immediately reinit for backtracking resistance */
142
0
  _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
143
0
  memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
144
0
  rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
145
0
}
146
147
static inline void
148
_rs_random_buf(void *_buf, size_t n)
149
0
{
150
0
  u_char *buf = (u_char *)_buf;
151
0
  u_char *keystream;
152
0
  size_t m;
153
154
0
  _rs_stir_if_needed(n);
155
0
  while (n > 0) {
156
0
    if (rs->rs_have > 0) {
157
0
      m = minimum(n, rs->rs_have);
158
0
      keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
159
0
          - rs->rs_have;
160
0
      memcpy(buf, keystream, m);
161
0
      memset(keystream, 0, m);
162
0
      buf += m;
163
0
      n -= m;
164
0
      rs->rs_have -= m;
165
0
    }
166
0
    if (rs->rs_have == 0)
167
0
      _rs_rekey(NULL, 0);
168
0
  }
169
0
}
170
171
static inline void
172
_rs_random_u32(uint32_t *val)
173
0
{
174
0
  u_char *keystream;
175
176
0
  _rs_stir_if_needed(sizeof(*val));
177
0
  if (rs->rs_have < sizeof(*val))
178
0
    _rs_rekey(NULL, 0);
179
0
  keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
180
0
  memcpy(val, keystream, sizeof(*val));
181
0
  memset(keystream, 0, sizeof(*val));
182
0
  rs->rs_have -= sizeof(*val);
183
0
}
184
185
uint32_t
186
arc4random(void)
187
0
{
188
0
  uint32_t val;
189
190
0
  _ARC4_LOCK();
191
0
  _rs_random_u32(&val);
192
0
  _ARC4_UNLOCK();
193
0
  return val;
194
0
}
195
196
void
197
arc4random_buf(void *buf, size_t n)
198
0
{
199
0
  _ARC4_LOCK();
200
0
  _rs_random_buf(buf, n);
201
0
  _ARC4_UNLOCK();
202
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_linux.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_linux.h.html index 43600e64f..4b322683b 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_linux.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_linux.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random_linux.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * Stub functions for portability.
24
 */
25
26
#include <sys/mman.h>
27
28
#include <pthread.h>
29
#include <signal.h>
30
31
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
32
0
#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
33
0
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
34
35
#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__))
36
extern void *__dso_handle;
37
extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
38
0
#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
39
#else
40
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
41
#endif
42
43
static inline void
44
_getentropy_fail(void)
45
0
{
46
0
  raise(SIGKILL);
47
0
}
48
49
static volatile sig_atomic_t _rs_forked;
50
51
static inline void
52
_rs_forkhandler(void)
53
0
{
54
0
  _rs_forked = 1;
55
0
}
56
57
static inline void
58
_rs_forkdetect(void)
59
0
{
60
0
  static pid_t _rs_pid = 0;
61
0
  pid_t pid = getpid();
62
63
        /* XXX unusual calls to clone() can bypass checks */
64
0
  if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
65
0
    _rs_pid = pid;
66
0
    _rs_forked = 0;
67
0
    if (rs)
68
0
      memset(rs, 0, sizeof(*rs));
69
0
  }
70
0
}
71
72
static inline int
73
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
74
0
{
75
0
  if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
76
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
77
0
    return (-1);
78
79
0
  if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
80
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
81
0
    munmap(*rsp, sizeof(**rsp));
82
0
    *rsp = NULL;
83
0
    return (-1);
84
0
  }
85
86
0
  _ARC4_ATFORK(_rs_forkhandler);
87
0
  return (0);
88
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random_linux.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * Stub functions for portability.
24
 */
25
26
#include <sys/mman.h>
27
28
#include <pthread.h>
29
#include <signal.h>
30
31
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
32
0
#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
33
0
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
34
35
#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__))
36
extern void *__dso_handle;
37
extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
38
0
#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
39
#else
40
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
41
#endif
42
43
static inline void
44
_getentropy_fail(void)
45
0
{
46
0
  raise(SIGKILL);
47
0
}
48
49
static volatile sig_atomic_t _rs_forked;
50
51
static inline void
52
_rs_forkhandler(void)
53
0
{
54
0
  _rs_forked = 1;
55
0
}
56
57
static inline void
58
_rs_forkdetect(void)
59
0
{
60
0
  static pid_t _rs_pid = 0;
61
0
  pid_t pid = getpid();
62
63
        /* XXX unusual calls to clone() can bypass checks */
64
0
  if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
65
0
    _rs_pid = pid;
66
0
    _rs_forked = 0;
67
0
    if (rs)
68
0
      memset(rs, 0, sizeof(*rs));
69
0
  }
70
0
}
71
72
static inline int
73
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
74
0
{
75
0
  if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
76
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
77
0
    return (-1);
78
79
0
  if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
80
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
81
0
    munmap(*rsp, sizeof(**rsp));
82
0
    *rsp = NULL;
83
0
    return (-1);
84
0
  }
85
86
0
  _ARC4_ATFORK(_rs_forkhandler);
87
0
  return (0);
88
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_uniform.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_uniform.c.html index f9faf3081..56708c160 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_uniform.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/arc4random_uniform.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random_uniform.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $  */
2
3
/*
4
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdint.h>
20
#include <stdlib.h>
21
22
/*
23
 * Calculate a uniformly distributed random number less than upper_bound
24
 * avoiding "modulo bias".
25
 *
26
 * Uniformity is achieved by generating new random numbers until the one
27
 * returned is outside the range [0, 2**32 % upper_bound).  This
28
 * guarantees the selected random number will be inside
29
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
30
 * after reduction modulo upper_bound.
31
 */
32
uint32_t
33
arc4random_uniform(uint32_t upper_bound)
34
0
{
35
0
  uint32_t r, min;
36
37
0
  if (upper_bound < 2)
38
0
    return 0;
39
40
  /* 2**32 % x == (2**32 - x) % x */
41
0
  min = -upper_bound % upper_bound;
42
43
  /*
44
   * This could theoretically loop forever but each retry has
45
   * p > 0.5 (worst case, usually far better) of selecting a
46
   * number inside the range we need, so it should rarely need
47
   * to re-roll.
48
   */
49
0
  for (;;) {
50
0
    r = arc4random();
51
0
    if (r >= min)
52
0
      break;
53
0
  }
54
55
0
  return r % upper_bound;
56
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random_uniform.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $  */
2
3
/*
4
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdint.h>
20
#include <stdlib.h>
21
22
/*
23
 * Calculate a uniformly distributed random number less than upper_bound
24
 * avoiding "modulo bias".
25
 *
26
 * Uniformity is achieved by generating new random numbers until the one
27
 * returned is outside the range [0, 2**32 % upper_bound).  This
28
 * guarantees the selected random number will be inside
29
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
30
 * after reduction modulo upper_bound.
31
 */
32
uint32_t
33
arc4random_uniform(uint32_t upper_bound)
34
0
{
35
0
  uint32_t r, min;
36
37
0
  if (upper_bound < 2)
38
0
    return 0;
39
40
  /* 2**32 % x == (2**32 - x) % x */
41
0
  min = -upper_bound % upper_bound;
42
43
  /*
44
   * This could theoretically loop forever but each retry has
45
   * p > 0.5 (worst case, usually far better) of selecting a
46
   * number inside the range we need, so it should rarely need
47
   * to re-roll.
48
   */
49
0
  for (;;) {
50
0
    r = arc4random();
51
0
    if (r >= min)
52
0
      break;
53
0
  }
54
55
0
  return r % upper_bound;
56
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/chacha_private.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/chacha_private.h.html index c9c7d20a3..44c0e7a32 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/chacha_private.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/chacha_private.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/chacha_private.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
  u32 input[16]; /* could be compressed */
15
} chacha_ctx;
16
17
0
#define U8C(v) (v##U)
18
0
#define U32C(v) (v##U)
19
20
0
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
0
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
0
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
0
  (((u32)((p)[0])      ) | \
28
0
   ((u32)((p)[1]) <<  8) | \
29
0
   ((u32)((p)[2]) << 16) | \
30
0
   ((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
0
  do { \
34
0
    (p)[0] = U8V((v)      ); \
35
0
    (p)[1] = U8V((v) >>  8); \
36
0
    (p)[2] = U8V((v) >> 16); \
37
0
    (p)[3] = U8V((v) >> 24); \
38
0
  } while (0)
39
40
0
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
0
#define PLUS(v,w) (U32V((v) + (w)))
43
0
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
56
0
{
57
0
  const char *constants;
58
59
0
  x->input[4] = U8TO32_LITTLE(k + 0);
60
0
  x->input[5] = U8TO32_LITTLE(k + 4);
61
0
  x->input[6] = U8TO32_LITTLE(k + 8);
62
0
  x->input[7] = U8TO32_LITTLE(k + 12);
63
0
  if (kbits == 256) { /* recommended */
64
0
    k += 16;
65
0
    constants = sigma;
66
0
  } else { /* kbits == 128 */
67
0
    constants = tau;
68
0
  }
69
0
  x->input[8] = U8TO32_LITTLE(k + 0);
70
0
  x->input[9] = U8TO32_LITTLE(k + 4);
71
0
  x->input[10] = U8TO32_LITTLE(k + 8);
72
0
  x->input[11] = U8TO32_LITTLE(k + 12);
73
0
  x->input[0] = U8TO32_LITTLE(constants + 0);
74
0
  x->input[1] = U8TO32_LITTLE(constants + 4);
75
0
  x->input[2] = U8TO32_LITTLE(constants + 8);
76
0
  x->input[3] = U8TO32_LITTLE(constants + 12);
77
0
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
0
{
82
0
  x->input[12] = 0;
83
0
  x->input[13] = 0;
84
0
  x->input[14] = U8TO32_LITTLE(iv + 0);
85
0
  x->input[15] = U8TO32_LITTLE(iv + 4);
86
0
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
0
{
91
0
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
0
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
0
  u8 *ctarget = NULL;
94
0
  u8 tmp[64];
95
0
  u_int i;
96
97
0
  if (!bytes) return;
98
99
0
  j0 = x->input[0];
100
0
  j1 = x->input[1];
101
0
  j2 = x->input[2];
102
0
  j3 = x->input[3];
103
0
  j4 = x->input[4];
104
0
  j5 = x->input[5];
105
0
  j6 = x->input[6];
106
0
  j7 = x->input[7];
107
0
  j8 = x->input[8];
108
0
  j9 = x->input[9];
109
0
  j10 = x->input[10];
110
0
  j11 = x->input[11];
111
0
  j12 = x->input[12];
112
0
  j13 = x->input[13];
113
0
  j14 = x->input[14];
114
0
  j15 = x->input[15];
115
116
0
  for (;;) {
117
0
    if (bytes < 64) {
118
0
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
0
      m = tmp;
120
0
      ctarget = c;
121
0
      c = tmp;
122
0
    }
123
0
    x0 = j0;
124
0
    x1 = j1;
125
0
    x2 = j2;
126
0
    x3 = j3;
127
0
    x4 = j4;
128
0
    x5 = j5;
129
0
    x6 = j6;
130
0
    x7 = j7;
131
0
    x8 = j8;
132
0
    x9 = j9;
133
0
    x10 = j10;
134
0
    x11 = j11;
135
0
    x12 = j12;
136
0
    x13 = j13;
137
0
    x14 = j14;
138
0
    x15 = j15;
139
0
    for (i = 20;i > 0;i -= 2) {
140
0
      QUARTERROUND( x0, x4, x8,x12)
141
0
      QUARTERROUND( x1, x5, x9,x13)
142
0
      QUARTERROUND( x2, x6,x10,x14)
143
0
      QUARTERROUND( x3, x7,x11,x15)
144
0
      QUARTERROUND( x0, x5,x10,x15)
145
0
      QUARTERROUND( x1, x6,x11,x12)
146
0
      QUARTERROUND( x2, x7, x8,x13)
147
0
      QUARTERROUND( x3, x4, x9,x14)
148
0
    }
149
0
    x0 = PLUS(x0,j0);
150
0
    x1 = PLUS(x1,j1);
151
0
    x2 = PLUS(x2,j2);
152
0
    x3 = PLUS(x3,j3);
153
0
    x4 = PLUS(x4,j4);
154
0
    x5 = PLUS(x5,j5);
155
0
    x6 = PLUS(x6,j6);
156
0
    x7 = PLUS(x7,j7);
157
0
    x8 = PLUS(x8,j8);
158
0
    x9 = PLUS(x9,j9);
159
0
    x10 = PLUS(x10,j10);
160
0
    x11 = PLUS(x11,j11);
161
0
    x12 = PLUS(x12,j12);
162
0
    x13 = PLUS(x13,j13);
163
0
    x14 = PLUS(x14,j14);
164
0
    x15 = PLUS(x15,j15);
165
166
#ifndef KEYSTREAM_ONLY
167
    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168
    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169
    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170
    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171
    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172
    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173
    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174
    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175
    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176
    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177
    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178
    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179
    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180
    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181
    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182
    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
#endif
184
185
0
    j12 = PLUSONE(j12);
186
0
    if (!j12) {
187
0
      j13 = PLUSONE(j13);
188
      /* stopping at 2^70 bytes per nonce is user's responsibility */
189
0
    }
190
191
0
    U32TO8_LITTLE(c + 0,x0);
192
0
    U32TO8_LITTLE(c + 4,x1);
193
0
    U32TO8_LITTLE(c + 8,x2);
194
0
    U32TO8_LITTLE(c + 12,x3);
195
0
    U32TO8_LITTLE(c + 16,x4);
196
0
    U32TO8_LITTLE(c + 20,x5);
197
0
    U32TO8_LITTLE(c + 24,x6);
198
0
    U32TO8_LITTLE(c + 28,x7);
199
0
    U32TO8_LITTLE(c + 32,x8);
200
0
    U32TO8_LITTLE(c + 36,x9);
201
0
    U32TO8_LITTLE(c + 40,x10);
202
0
    U32TO8_LITTLE(c + 44,x11);
203
0
    U32TO8_LITTLE(c + 48,x12);
204
0
    U32TO8_LITTLE(c + 52,x13);
205
0
    U32TO8_LITTLE(c + 56,x14);
206
0
    U32TO8_LITTLE(c + 60,x15);
207
208
0
    if (bytes <= 64) {
209
0
      if (bytes < 64) {
210
0
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
0
      }
212
0
      x->input[12] = j12;
213
0
      x->input[13] = j13;
214
0
      return;
215
0
    }
216
0
    bytes -= 64;
217
0
    c += 64;
218
#ifndef KEYSTREAM_ONLY
219
    m += 64;
220
#endif
221
0
  }
222
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/chacha_private.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
  u32 input[16]; /* could be compressed */
15
} chacha_ctx;
16
17
0
#define U8C(v) (v##U)
18
0
#define U32C(v) (v##U)
19
20
0
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
0
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
0
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
0
  (((u32)((p)[0])      ) | \
28
0
   ((u32)((p)[1]) <<  8) | \
29
0
   ((u32)((p)[2]) << 16) | \
30
0
   ((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
0
  do { \
34
0
    (p)[0] = U8V((v)      ); \
35
0
    (p)[1] = U8V((v) >>  8); \
36
0
    (p)[2] = U8V((v) >> 16); \
37
0
    (p)[3] = U8V((v) >> 24); \
38
0
  } while (0)
39
40
0
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
0
#define PLUS(v,w) (U32V((v) + (w)))
43
0
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
56
0
{
57
0
  const char *constants;
58
59
0
  x->input[4] = U8TO32_LITTLE(k + 0);
60
0
  x->input[5] = U8TO32_LITTLE(k + 4);
61
0
  x->input[6] = U8TO32_LITTLE(k + 8);
62
0
  x->input[7] = U8TO32_LITTLE(k + 12);
63
0
  if (kbits == 256) { /* recommended */
64
0
    k += 16;
65
0
    constants = sigma;
66
0
  } else { /* kbits == 128 */
67
0
    constants = tau;
68
0
  }
69
0
  x->input[8] = U8TO32_LITTLE(k + 0);
70
0
  x->input[9] = U8TO32_LITTLE(k + 4);
71
0
  x->input[10] = U8TO32_LITTLE(k + 8);
72
0
  x->input[11] = U8TO32_LITTLE(k + 12);
73
0
  x->input[0] = U8TO32_LITTLE(constants + 0);
74
0
  x->input[1] = U8TO32_LITTLE(constants + 4);
75
0
  x->input[2] = U8TO32_LITTLE(constants + 8);
76
0
  x->input[3] = U8TO32_LITTLE(constants + 12);
77
0
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
0
{
82
0
  x->input[12] = 0;
83
0
  x->input[13] = 0;
84
0
  x->input[14] = U8TO32_LITTLE(iv + 0);
85
0
  x->input[15] = U8TO32_LITTLE(iv + 4);
86
0
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
0
{
91
0
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
0
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
0
  u8 *ctarget = NULL;
94
0
  u8 tmp[64];
95
0
  u_int i;
96
97
0
  if (!bytes) return;
98
99
0
  j0 = x->input[0];
100
0
  j1 = x->input[1];
101
0
  j2 = x->input[2];
102
0
  j3 = x->input[3];
103
0
  j4 = x->input[4];
104
0
  j5 = x->input[5];
105
0
  j6 = x->input[6];
106
0
  j7 = x->input[7];
107
0
  j8 = x->input[8];
108
0
  j9 = x->input[9];
109
0
  j10 = x->input[10];
110
0
  j11 = x->input[11];
111
0
  j12 = x->input[12];
112
0
  j13 = x->input[13];
113
0
  j14 = x->input[14];
114
0
  j15 = x->input[15];
115
116
0
  for (;;) {
117
0
    if (bytes < 64) {
118
0
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
0
      m = tmp;
120
0
      ctarget = c;
121
0
      c = tmp;
122
0
    }
123
0
    x0 = j0;
124
0
    x1 = j1;
125
0
    x2 = j2;
126
0
    x3 = j3;
127
0
    x4 = j4;
128
0
    x5 = j5;
129
0
    x6 = j6;
130
0
    x7 = j7;
131
0
    x8 = j8;
132
0
    x9 = j9;
133
0
    x10 = j10;
134
0
    x11 = j11;
135
0
    x12 = j12;
136
0
    x13 = j13;
137
0
    x14 = j14;
138
0
    x15 = j15;
139
0
    for (i = 20;i > 0;i -= 2) {
140
0
      QUARTERROUND( x0, x4, x8,x12)
141
0
      QUARTERROUND( x1, x5, x9,x13)
142
0
      QUARTERROUND( x2, x6,x10,x14)
143
0
      QUARTERROUND( x3, x7,x11,x15)
144
0
      QUARTERROUND( x0, x5,x10,x15)
145
0
      QUARTERROUND( x1, x6,x11,x12)
146
0
      QUARTERROUND( x2, x7, x8,x13)
147
0
      QUARTERROUND( x3, x4, x9,x14)
148
0
    }
149
0
    x0 = PLUS(x0,j0);
150
0
    x1 = PLUS(x1,j1);
151
0
    x2 = PLUS(x2,j2);
152
0
    x3 = PLUS(x3,j3);
153
0
    x4 = PLUS(x4,j4);
154
0
    x5 = PLUS(x5,j5);
155
0
    x6 = PLUS(x6,j6);
156
0
    x7 = PLUS(x7,j7);
157
0
    x8 = PLUS(x8,j8);
158
0
    x9 = PLUS(x9,j9);
159
0
    x10 = PLUS(x10,j10);
160
0
    x11 = PLUS(x11,j11);
161
0
    x12 = PLUS(x12,j12);
162
0
    x13 = PLUS(x13,j13);
163
0
    x14 = PLUS(x14,j14);
164
0
    x15 = PLUS(x15,j15);
165
166
#ifndef KEYSTREAM_ONLY
167
    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168
    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169
    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170
    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171
    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172
    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173
    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174
    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175
    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176
    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177
    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178
    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179
    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180
    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181
    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182
    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
#endif
184
185
0
    j12 = PLUSONE(j12);
186
0
    if (!j12) {
187
0
      j13 = PLUSONE(j13);
188
      /* stopping at 2^70 bytes per nonce is user's responsibility */
189
0
    }
190
191
0
    U32TO8_LITTLE(c + 0,x0);
192
0
    U32TO8_LITTLE(c + 4,x1);
193
0
    U32TO8_LITTLE(c + 8,x2);
194
0
    U32TO8_LITTLE(c + 12,x3);
195
0
    U32TO8_LITTLE(c + 16,x4);
196
0
    U32TO8_LITTLE(c + 20,x5);
197
0
    U32TO8_LITTLE(c + 24,x6);
198
0
    U32TO8_LITTLE(c + 28,x7);
199
0
    U32TO8_LITTLE(c + 32,x8);
200
0
    U32TO8_LITTLE(c + 36,x9);
201
0
    U32TO8_LITTLE(c + 40,x10);
202
0
    U32TO8_LITTLE(c + 44,x11);
203
0
    U32TO8_LITTLE(c + 48,x12);
204
0
    U32TO8_LITTLE(c + 52,x13);
205
0
    U32TO8_LITTLE(c + 56,x14);
206
0
    U32TO8_LITTLE(c + 60,x15);
207
208
0
    if (bytes <= 64) {
209
0
      if (bytes < 64) {
210
0
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
0
      }
212
0
      x->input[12] = j12;
213
0
      x->input[13] = j13;
214
0
      return;
215
0
    }
216
0
    bytes -= 64;
217
0
    c += 64;
218
#ifndef KEYSTREAM_ONLY
219
    m += 64;
220
#endif
221
0
  }
222
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/freezero.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/freezero.c.html index 12fb77b8c..4f2fd0053 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/freezero.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/freezero.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/freezero.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
3
 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
4
 * Copyright (c) 2008 Damien Miller <djm@openbsd.org>
5
 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <string.h>
21
#include <stdlib.h>
22
23
void
24
freezero(void *ptr, size_t sz)
25
20.3k
{
26
  /* This is legal. */
27
20.3k
  if (ptr == NULL)
28
1.41k
    return;
29
30
18.9k
  explicit_bzero(ptr, sz);
31
18.9k
  free(ptr);
32
18.9k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/freezero.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
3
 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
4
 * Copyright (c) 2008 Damien Miller <djm@openbsd.org>
5
 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <string.h>
21
#include <stdlib.h>
22
23
void
24
freezero(void *ptr, size_t sz)
25
20.4k
{
26
  /* This is legal. */
27
20.4k
  if (ptr == NULL)
28
1.41k
    return;
29
30
19.0k
  explicit_bzero(ptr, sz);
31
19.0k
  free(ptr);
32
19.0k
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/getdtablecount.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/getdtablecount.c.html index 6e18c48fc..5cd4a3b0a 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/getdtablecount.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/getdtablecount.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/getdtablecount.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETDTABLECOUNT)
6
int
7
getdtablecount(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/getdtablecount.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETDTABLECOUNT)
6
int
7
getdtablecount(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/getrtable.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/getrtable.c.html index dce343949..49372bac9 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/getrtable.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/getrtable.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/getrtable.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETRTABLE)
6
int
7
getrtable(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
12
13
#if !defined(HAVE_SETRTABLE)
14
int
15
setrtable(int rtableid)
16
0
{
17
0
  if (rtableid == 0)
18
0
    return (0);
19
0
  return (-1);
20
0
}
21
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/getrtable.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETRTABLE)
6
int
7
getrtable(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
12
13
#if !defined(HAVE_SETRTABLE)
14
int
15
setrtable(int rtableid)
16
0
{
17
0
  if (rtableid == 0)
18
0
    return (0);
19
0
  return (-1);
20
0
}
21
#endif
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/imsg-buffer.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/imsg-buffer.c.html index a6b7d70d3..37407254b 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/imsg-buffer.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/imsg-buffer.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg-buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <limits.h>
25
#include <errno.h>
26
#include <endian.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#include "openbsd-compat.h"
32
#include "imsg.h"
33
34
static int  ibuf_realloc(struct ibuf *, size_t);
35
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
36
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
37
static void msgbuf_drain(struct msgbuf *, size_t);
38
39
struct ibuf *
40
ibuf_open(size_t len)
41
0
{
42
0
  struct ibuf *buf;
43
44
0
  if (len == 0) {
45
0
    errno = EINVAL;
46
0
    return (NULL);
47
0
  }
48
0
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
49
0
    return (NULL);
50
0
  if ((buf->buf = calloc(len, 1)) == NULL) {
51
0
    free(buf);
52
0
    return (NULL);
53
0
  }
54
0
  buf->size = buf->max = len;
55
0
  buf->fd = -1;
56
57
0
  return (buf);
58
0
}
59
60
struct ibuf *
61
ibuf_dynamic(size_t len, size_t max)
62
20.3k
{
63
20.3k
  struct ibuf *buf;
64
65
20.3k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
20.3k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
20.3k
  if (len > 0) {
73
18.9k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
18.9k
  }
78
20.3k
  buf->size = len;
79
20.3k
  buf->max = max;
80
20.3k
  buf->fd = -1;
81
82
20.3k
  return (buf);
83
20.3k
}
84
85
static int
86
ibuf_realloc(struct ibuf *buf, size_t len)
87
0
{
88
0
  unsigned char *b;
89
90
  /* on static buffers max is eq size and so the following fails */
91
0
  if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
92
0
    errno = ERANGE;
93
0
    return (-1);
94
0
  }
95
96
0
  b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
97
0
  if (b == NULL)
98
0
    return (-1);
99
0
  buf->buf = b;
100
0
  buf->size = buf->wpos + len;
101
102
0
  return (0);
103
0
}
104
105
void *
106
ibuf_reserve(struct ibuf *buf, size_t len)
107
18.9k
{
108
18.9k
  void  *b;
109
110
18.9k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
18.9k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
18.9k
  b = buf->buf + buf->wpos;
120
18.9k
  buf->wpos += len;
121
18.9k
  memset(b, 0, len);
122
18.9k
  return (b);
123
18.9k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
18.9k
{
128
18.9k
  void *b;
129
130
18.9k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
18.9k
  memcpy(b, data, len);
134
18.9k
  return (0);
135
18.9k
}
136
137
138
int
139
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
140
0
{
141
0
  return ibuf_add(buf, from->buf, from->wpos);
142
0
}
143
144
int
145
ibuf_add_n8(struct ibuf *buf, uint64_t value)
146
0
{
147
0
  uint8_t v;
148
149
0
  if (value > UINT8_MAX) {
150
0
    errno = EINVAL;
151
0
    return (-1);
152
0
  }
153
0
  v = value;
154
0
  return ibuf_add(buf, &v, sizeof(v));
155
0
}
156
157
int
158
ibuf_add_n16(struct ibuf *buf, uint64_t value)
159
0
{
160
0
  uint16_t v;
161
162
0
  if (value > UINT16_MAX) {
163
0
    errno = EINVAL;
164
0
    return (-1);
165
0
  }
166
0
  v = htobe16(value);
167
0
  return ibuf_add(buf, &v, sizeof(v));
168
0
}
169
170
int
171
ibuf_add_n32(struct ibuf *buf, uint64_t value)
172
0
{
173
0
  uint32_t v;
174
175
0
  if (value > UINT32_MAX) {
176
0
    errno = EINVAL;
177
0
    return (-1);
178
0
  }
179
0
  v = htobe32(value);
180
0
  return ibuf_add(buf, &v, sizeof(v));
181
0
}
182
183
int
184
ibuf_add_n64(struct ibuf *buf, uint64_t value)
185
0
{
186
0
  value = htobe64(value);
187
0
  return ibuf_add(buf, &value, sizeof(value));
188
0
}
189
190
int
191
ibuf_add_zero(struct ibuf *buf, size_t len)
192
0
{
193
0
  void *b;
194
195
0
  if ((b = ibuf_reserve(buf, len)) == NULL)
196
0
    return (-1);
197
0
  return (0);
198
0
}
199
200
void *
201
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
202
232k
{
203
  /* only allowed to seek in already written parts */
204
232k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
3.28k
    errno = ERANGE;
206
3.28k
    return (NULL);
207
3.28k
  }
208
209
229k
  return (buf->buf + pos);
210
232k
}
211
212
int
213
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
214
0
{
215
0
  void *b;
216
217
0
  if ((b = ibuf_seek(buf, pos, len)) == NULL)
218
0
    return (-1);
219
220
0
  memcpy(b, data, len);
221
0
  return (0);
222
0
}
223
224
int
225
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
226
0
{
227
0
  uint8_t v;
228
229
0
  if (value > UINT8_MAX) {
230
0
    errno = EINVAL;
231
0
    return (-1);
232
0
  }
233
0
  v = value;
234
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
235
0
}
236
237
int
238
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
239
0
{
240
0
  uint16_t v;
241
242
0
  if (value > UINT16_MAX) {
243
0
    errno = EINVAL;
244
0
    return (-1);
245
0
  }
246
0
  v = htobe16(value);
247
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
248
0
}
249
250
int
251
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
252
0
{
253
0
  uint32_t v;
254
255
0
  if (value > UINT32_MAX) {
256
0
    errno = EINVAL;
257
0
    return (-1);
258
0
  }
259
0
  v = htobe32(value);
260
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
261
0
}
262
263
int
264
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
265
0
{
266
0
  value = htobe64(value);
267
0
  return (ibuf_set(buf, pos, &value, sizeof(value)));
268
0
}
269
270
void *
271
ibuf_data(struct ibuf *buf)
272
707k
{
273
707k
  return (buf->buf);
274
707k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
13.0k
{
279
13.0k
  return (buf->wpos);
280
13.0k
}
281
282
size_t
283
ibuf_left(struct ibuf *buf)
284
0
{
285
0
  return (buf->max - buf->wpos);
286
0
}
287
288
void
289
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
290
0
{
291
0
  ibuf_enqueue(msgbuf, buf);
292
0
}
293
294
void
295
ibuf_free(struct ibuf *buf)
296
175k
{
297
175k
  if (buf == NULL)
298
155k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
20.3k
  freezero(buf->buf, buf->size);
304
20.3k
  free(buf);
305
20.3k
}
306
307
int
308
ibuf_fd_avail(struct ibuf *buf)
309
0
{
310
0
  return (buf->fd != -1);
311
0
}
312
313
int
314
ibuf_fd_get(struct ibuf *buf)
315
0
{
316
0
  int fd;
317
318
0
  fd = buf->fd;
319
#ifdef NOTYET
320
  buf->fd = -1;
321
#endif
322
0
  return (fd);
323
0
}
324
325
void
326
ibuf_fd_set(struct ibuf *buf, int fd)
327
0
{
328
0
  if (buf->fd != -1)
329
0
    close(buf->fd);
330
0
  buf->fd = fd;
331
0
}
332
333
#ifdef _WIN32
334
#define IBUF_WSABUF_WRITE_MAX 16
335
int
336
ibuf_write(struct msgbuf *msgbuf)
337
{
338
  DWORD    bytesSent;
339
  WSABUF     iov[IBUF_WSABUF_WRITE_MAX];
340
  struct ibuf *buf;
341
  unsigned int   i = 0;
342
  ssize_t n;
343
344
  memset(&iov, 0, sizeof(iov));
345
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
346
    if (i >= IBUF_WSABUF_WRITE_MAX)
347
      break;
348
    iov[i].buf = buf->buf + buf->rpos;
349
    iov[i].len = buf->wpos - buf->rpos;
350
    i++;
351
  }
352
353
  if (WSASend(msgbuf->fd, iov, i, &bytesSent, 0, NULL, NULL))
354
    return (-1);
355
  n = bytesSent;
356
357
  if (n == 0) {     /* connection closed */
358
    errno = 0;
359
    return (0);
360
  }
361
362
  msgbuf_drain(msgbuf, n);
363
364
  return (1);
365
}
366
#else
367
int
368
ibuf_write(struct msgbuf *msgbuf)
369
0
{
370
0
  struct iovec   iov[IOV_MAX];
371
0
  struct ibuf *buf;
372
0
  unsigned int   i = 0;
373
0
  ssize_t n;
374
375
0
  memset(&iov, 0, sizeof(iov));
376
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
377
0
    if (i >= IOV_MAX)
378
0
      break;
379
0
    iov[i].iov_base = buf->buf + buf->rpos;
380
0
    iov[i].iov_len = buf->wpos - buf->rpos;
381
0
    i++;
382
0
  }
383
384
0
again:
385
0
  if ((n = writev(msgbuf->fd, iov, i)) == -1) {
386
0
    if (errno == EINTR)
387
0
      goto again;
388
0
    if (errno == ENOBUFS)
389
0
      errno = EAGAIN;
390
0
    return (-1);
391
0
  }
392
393
0
  if (n == 0) {     /* connection closed */
394
0
    errno = 0;
395
0
    return (0);
396
0
  }
397
398
0
  msgbuf_drain(msgbuf, n);
399
400
0
  return (1);
401
0
}
402
#endif /* !_WIN32 */
403
404
void
405
msgbuf_init(struct msgbuf *msgbuf)
406
0
{
407
0
  msgbuf->queued = 0;
408
0
  msgbuf->fd = -1;
409
0
  TAILQ_INIT(&msgbuf->bufs);
410
0
}
411
412
static void
413
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
414
0
{
415
0
  struct ibuf *buf, *next;
416
417
0
  for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
418
0
      buf = next) {
419
0
    next = TAILQ_NEXT(buf, entry);
420
0
    if (n >= buf->wpos - buf->rpos) {
421
0
      n -= buf->wpos - buf->rpos;
422
0
      ibuf_dequeue(msgbuf, buf);
423
0
    } else {
424
0
      buf->rpos += n;
425
0
      n = 0;
426
0
    }
427
0
  }
428
0
}
429
430
void
431
msgbuf_clear(struct msgbuf *msgbuf)
432
0
{
433
0
  struct ibuf *buf;
434
435
0
  while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
436
0
    ibuf_dequeue(msgbuf, buf);
437
0
}
438
439
#ifdef _WIN32
440
int
441
msgbuf_write(struct msgbuf *msgbuf)
442
{
443
  struct ibuf *buf;
444
445
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
446
    if (buf->fd != -1)
447
      return (-1);
448
  return ibuf_write(msgbuf);
449
}
450
#else
451
int
452
msgbuf_write(struct msgbuf *msgbuf)
453
0
{
454
0
  struct iovec   iov[IOV_MAX];
455
0
  struct ibuf *buf, *buf0 = NULL;
456
0
  unsigned int   i = 0;
457
0
  ssize_t    n;
458
0
  struct msghdr  msg;
459
0
  struct cmsghdr  *cmsg;
460
0
  union {
461
0
    struct cmsghdr  hdr;
462
0
    char    buf[CMSG_SPACE(sizeof(int))];
463
0
  } cmsgbuf;
464
465
0
  memset(&iov, 0, sizeof(iov));
466
0
  memset(&msg, 0, sizeof(msg));
467
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
468
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
469
0
    if (i >= IOV_MAX)
470
0
      break;
471
0
    if (i > 0 && buf->fd != -1)
472
0
      break;
473
0
    iov[i].iov_base = buf->buf + buf->rpos;
474
0
    iov[i].iov_len = buf->wpos - buf->rpos;
475
0
    i++;
476
0
    if (buf->fd != -1)
477
0
      buf0 = buf;
478
0
  }
479
480
0
  msg.msg_iov = iov;
481
0
  msg.msg_iovlen = i;
482
483
0
  if (buf0 != NULL) {
484
0
    msg.msg_control = (caddr_t)&cmsgbuf.buf;
485
0
    msg.msg_controllen = sizeof(cmsgbuf.buf);
486
0
    cmsg = CMSG_FIRSTHDR(&msg);
487
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
488
0
    cmsg->cmsg_level = SOL_SOCKET;
489
0
    cmsg->cmsg_type = SCM_RIGHTS;
490
0
    *(int *)CMSG_DATA(cmsg) = buf0->fd;
491
0
  }
492
493
0
again:
494
0
  if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
495
0
    if (errno == EINTR)
496
0
      goto again;
497
0
    if (errno == ENOBUFS)
498
0
      errno = EAGAIN;
499
0
    return (-1);
500
0
  }
501
502
0
  if (n == 0) {     /* connection closed */
503
0
    errno = 0;
504
0
    return (0);
505
0
  }
506
507
  /*
508
   * assumption: fd got sent if sendmsg sent anything
509
   * this works because fds are passed one at a time
510
   */
511
0
  if (buf0 != NULL) {
512
0
    close(buf0->fd);
513
0
    buf0->fd = -1;
514
0
  }
515
516
0
  msgbuf_drain(msgbuf, n);
517
518
0
  return (1);
519
0
}
520
#endif /* !_WIN32 */
521
522
static void
523
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
524
0
{
525
0
  TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
526
0
  msgbuf->queued++;
527
0
}
528
529
static void
530
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
531
0
{
532
0
  TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
533
534
0
  if (buf->fd != -1) {
535
0
    close(buf->fd);
536
0
    buf->fd = -1;
537
0
  }
538
539
0
  msgbuf->queued--;
540
0
  ibuf_free(buf);
541
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg-buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <limits.h>
25
#include <errno.h>
26
#include <endian.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#include "openbsd-compat.h"
32
#include "imsg.h"
33
34
static int  ibuf_realloc(struct ibuf *, size_t);
35
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
36
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
37
static void msgbuf_drain(struct msgbuf *, size_t);
38
39
struct ibuf *
40
ibuf_open(size_t len)
41
0
{
42
0
  struct ibuf *buf;
43
44
0
  if (len == 0) {
45
0
    errno = EINVAL;
46
0
    return (NULL);
47
0
  }
48
0
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
49
0
    return (NULL);
50
0
  if ((buf->buf = calloc(len, 1)) == NULL) {
51
0
    free(buf);
52
0
    return (NULL);
53
0
  }
54
0
  buf->size = buf->max = len;
55
0
  buf->fd = -1;
56
57
0
  return (buf);
58
0
}
59
60
struct ibuf *
61
ibuf_dynamic(size_t len, size_t max)
62
20.4k
{
63
20.4k
  struct ibuf *buf;
64
65
20.4k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
20.4k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
20.4k
  if (len > 0) {
73
19.0k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
19.0k
  }
78
20.4k
  buf->size = len;
79
20.4k
  buf->max = max;
80
20.4k
  buf->fd = -1;
81
82
20.4k
  return (buf);
83
20.4k
}
84
85
static int
86
ibuf_realloc(struct ibuf *buf, size_t len)
87
0
{
88
0
  unsigned char *b;
89
90
  /* on static buffers max is eq size and so the following fails */
91
0
  if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
92
0
    errno = ERANGE;
93
0
    return (-1);
94
0
  }
95
96
0
  b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
97
0
  if (b == NULL)
98
0
    return (-1);
99
0
  buf->buf = b;
100
0
  buf->size = buf->wpos + len;
101
102
0
  return (0);
103
0
}
104
105
void *
106
ibuf_reserve(struct ibuf *buf, size_t len)
107
19.0k
{
108
19.0k
  void  *b;
109
110
19.0k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
19.0k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
19.0k
  b = buf->buf + buf->wpos;
120
19.0k
  buf->wpos += len;
121
19.0k
  memset(b, 0, len);
122
19.0k
  return (b);
123
19.0k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
19.0k
{
128
19.0k
  void *b;
129
130
19.0k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
19.0k
  memcpy(b, data, len);
134
19.0k
  return (0);
135
19.0k
}
136
137
138
int
139
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
140
0
{
141
0
  return ibuf_add(buf, from->buf, from->wpos);
142
0
}
143
144
int
145
ibuf_add_n8(struct ibuf *buf, uint64_t value)
146
0
{
147
0
  uint8_t v;
148
149
0
  if (value > UINT8_MAX) {
150
0
    errno = EINVAL;
151
0
    return (-1);
152
0
  }
153
0
  v = value;
154
0
  return ibuf_add(buf, &v, sizeof(v));
155
0
}
156
157
int
158
ibuf_add_n16(struct ibuf *buf, uint64_t value)
159
0
{
160
0
  uint16_t v;
161
162
0
  if (value > UINT16_MAX) {
163
0
    errno = EINVAL;
164
0
    return (-1);
165
0
  }
166
0
  v = htobe16(value);
167
0
  return ibuf_add(buf, &v, sizeof(v));
168
0
}
169
170
int
171
ibuf_add_n32(struct ibuf *buf, uint64_t value)
172
0
{
173
0
  uint32_t v;
174
175
0
  if (value > UINT32_MAX) {
176
0
    errno = EINVAL;
177
0
    return (-1);
178
0
  }
179
0
  v = htobe32(value);
180
0
  return ibuf_add(buf, &v, sizeof(v));
181
0
}
182
183
int
184
ibuf_add_n64(struct ibuf *buf, uint64_t value)
185
0
{
186
0
  value = htobe64(value);
187
0
  return ibuf_add(buf, &value, sizeof(value));
188
0
}
189
190
int
191
ibuf_add_zero(struct ibuf *buf, size_t len)
192
0
{
193
0
  void *b;
194
195
0
  if ((b = ibuf_reserve(buf, len)) == NULL)
196
0
    return (-1);
197
0
  return (0);
198
0
}
199
200
void *
201
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
202
233k
{
203
  /* only allowed to seek in already written parts */
204
233k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
3.28k
    errno = ERANGE;
206
3.28k
    return (NULL);
207
3.28k
  }
208
209
230k
  return (buf->buf + pos);
210
233k
}
211
212
int
213
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
214
0
{
215
0
  void *b;
216
217
0
  if ((b = ibuf_seek(buf, pos, len)) == NULL)
218
0
    return (-1);
219
220
0
  memcpy(b, data, len);
221
0
  return (0);
222
0
}
223
224
int
225
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
226
0
{
227
0
  uint8_t v;
228
229
0
  if (value > UINT8_MAX) {
230
0
    errno = EINVAL;
231
0
    return (-1);
232
0
  }
233
0
  v = value;
234
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
235
0
}
236
237
int
238
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
239
0
{
240
0
  uint16_t v;
241
242
0
  if (value > UINT16_MAX) {
243
0
    errno = EINVAL;
244
0
    return (-1);
245
0
  }
246
0
  v = htobe16(value);
247
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
248
0
}
249
250
int
251
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
252
0
{
253
0
  uint32_t v;
254
255
0
  if (value > UINT32_MAX) {
256
0
    errno = EINVAL;
257
0
    return (-1);
258
0
  }
259
0
  v = htobe32(value);
260
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
261
0
}
262
263
int
264
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
265
0
{
266
0
  value = htobe64(value);
267
0
  return (ibuf_set(buf, pos, &value, sizeof(value)));
268
0
}
269
270
void *
271
ibuf_data(struct ibuf *buf)
272
711k
{
273
711k
  return (buf->buf);
274
711k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
13.1k
{
279
13.1k
  return (buf->wpos);
280
13.1k
}
281
282
size_t
283
ibuf_left(struct ibuf *buf)
284
0
{
285
0
  return (buf->max - buf->wpos);
286
0
}
287
288
void
289
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
290
0
{
291
0
  ibuf_enqueue(msgbuf, buf);
292
0
}
293
294
void
295
ibuf_free(struct ibuf *buf)
296
177k
{
297
177k
  if (buf == NULL)
298
157k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
20.4k
  freezero(buf->buf, buf->size);
304
20.4k
  free(buf);
305
20.4k
}
306
307
int
308
ibuf_fd_avail(struct ibuf *buf)
309
0
{
310
0
  return (buf->fd != -1);
311
0
}
312
313
int
314
ibuf_fd_get(struct ibuf *buf)
315
0
{
316
0
  int fd;
317
318
0
  fd = buf->fd;
319
#ifdef NOTYET
320
  buf->fd = -1;
321
#endif
322
0
  return (fd);
323
0
}
324
325
void
326
ibuf_fd_set(struct ibuf *buf, int fd)
327
0
{
328
0
  if (buf->fd != -1)
329
0
    close(buf->fd);
330
0
  buf->fd = fd;
331
0
}
332
333
#ifdef _WIN32
334
#define IBUF_WSABUF_WRITE_MAX 16
335
int
336
ibuf_write(struct msgbuf *msgbuf)
337
{
338
  DWORD    bytesSent;
339
  WSABUF     iov[IBUF_WSABUF_WRITE_MAX];
340
  struct ibuf *buf;
341
  unsigned int   i = 0;
342
  ssize_t n;
343
344
  memset(&iov, 0, sizeof(iov));
345
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
346
    if (i >= IBUF_WSABUF_WRITE_MAX)
347
      break;
348
    iov[i].buf = buf->buf + buf->rpos;
349
    iov[i].len = buf->wpos - buf->rpos;
350
    i++;
351
  }
352
353
  if (WSASend(msgbuf->fd, iov, i, &bytesSent, 0, NULL, NULL))
354
    return (-1);
355
  n = bytesSent;
356
357
  if (n == 0) {     /* connection closed */
358
    errno = 0;
359
    return (0);
360
  }
361
362
  msgbuf_drain(msgbuf, n);
363
364
  return (1);
365
}
366
#else
367
int
368
ibuf_write(struct msgbuf *msgbuf)
369
0
{
370
0
  struct iovec   iov[IOV_MAX];
371
0
  struct ibuf *buf;
372
0
  unsigned int   i = 0;
373
0
  ssize_t n;
374
375
0
  memset(&iov, 0, sizeof(iov));
376
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
377
0
    if (i >= IOV_MAX)
378
0
      break;
379
0
    iov[i].iov_base = buf->buf + buf->rpos;
380
0
    iov[i].iov_len = buf->wpos - buf->rpos;
381
0
    i++;
382
0
  }
383
384
0
again:
385
0
  if ((n = writev(msgbuf->fd, iov, i)) == -1) {
386
0
    if (errno == EINTR)
387
0
      goto again;
388
0
    if (errno == ENOBUFS)
389
0
      errno = EAGAIN;
390
0
    return (-1);
391
0
  }
392
393
0
  if (n == 0) {     /* connection closed */
394
0
    errno = 0;
395
0
    return (0);
396
0
  }
397
398
0
  msgbuf_drain(msgbuf, n);
399
400
0
  return (1);
401
0
}
402
#endif /* !_WIN32 */
403
404
void
405
msgbuf_init(struct msgbuf *msgbuf)
406
0
{
407
0
  msgbuf->queued = 0;
408
0
  msgbuf->fd = -1;
409
0
  TAILQ_INIT(&msgbuf->bufs);
410
0
}
411
412
static void
413
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
414
0
{
415
0
  struct ibuf *buf, *next;
416
417
0
  for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
418
0
      buf = next) {
419
0
    next = TAILQ_NEXT(buf, entry);
420
0
    if (n >= buf->wpos - buf->rpos) {
421
0
      n -= buf->wpos - buf->rpos;
422
0
      ibuf_dequeue(msgbuf, buf);
423
0
    } else {
424
0
      buf->rpos += n;
425
0
      n = 0;
426
0
    }
427
0
  }
428
0
}
429
430
void
431
msgbuf_clear(struct msgbuf *msgbuf)
432
0
{
433
0
  struct ibuf *buf;
434
435
0
  while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
436
0
    ibuf_dequeue(msgbuf, buf);
437
0
}
438
439
#ifdef _WIN32
440
int
441
msgbuf_write(struct msgbuf *msgbuf)
442
{
443
  struct ibuf *buf;
444
445
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
446
    if (buf->fd != -1)
447
      return (-1);
448
  return ibuf_write(msgbuf);
449
}
450
#else
451
int
452
msgbuf_write(struct msgbuf *msgbuf)
453
0
{
454
0
  struct iovec   iov[IOV_MAX];
455
0
  struct ibuf *buf, *buf0 = NULL;
456
0
  unsigned int   i = 0;
457
0
  ssize_t    n;
458
0
  struct msghdr  msg;
459
0
  struct cmsghdr  *cmsg;
460
0
  union {
461
0
    struct cmsghdr  hdr;
462
0
    char    buf[CMSG_SPACE(sizeof(int))];
463
0
  } cmsgbuf;
464
465
0
  memset(&iov, 0, sizeof(iov));
466
0
  memset(&msg, 0, sizeof(msg));
467
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
468
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
469
0
    if (i >= IOV_MAX)
470
0
      break;
471
0
    if (i > 0 && buf->fd != -1)
472
0
      break;
473
0
    iov[i].iov_base = buf->buf + buf->rpos;
474
0
    iov[i].iov_len = buf->wpos - buf->rpos;
475
0
    i++;
476
0
    if (buf->fd != -1)
477
0
      buf0 = buf;
478
0
  }
479
480
0
  msg.msg_iov = iov;
481
0
  msg.msg_iovlen = i;
482
483
0
  if (buf0 != NULL) {
484
0
    msg.msg_control = (caddr_t)&cmsgbuf.buf;
485
0
    msg.msg_controllen = sizeof(cmsgbuf.buf);
486
0
    cmsg = CMSG_FIRSTHDR(&msg);
487
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
488
0
    cmsg->cmsg_level = SOL_SOCKET;
489
0
    cmsg->cmsg_type = SCM_RIGHTS;
490
0
    *(int *)CMSG_DATA(cmsg) = buf0->fd;
491
0
  }
492
493
0
again:
494
0
  if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
495
0
    if (errno == EINTR)
496
0
      goto again;
497
0
    if (errno == ENOBUFS)
498
0
      errno = EAGAIN;
499
0
    return (-1);
500
0
  }
501
502
0
  if (n == 0) {     /* connection closed */
503
0
    errno = 0;
504
0
    return (0);
505
0
  }
506
507
  /*
508
   * assumption: fd got sent if sendmsg sent anything
509
   * this works because fds are passed one at a time
510
   */
511
0
  if (buf0 != NULL) {
512
0
    close(buf0->fd);
513
0
    buf0->fd = -1;
514
0
  }
515
516
0
  msgbuf_drain(msgbuf, n);
517
518
0
  return (1);
519
0
}
520
#endif /* !_WIN32 */
521
522
static void
523
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
524
0
{
525
0
  TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
526
0
  msgbuf->queued++;
527
0
}
528
529
static void
530
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
531
0
{
532
0
  TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
533
534
0
  if (buf->fd != -1) {
535
0
    close(buf->fd);
536
0
    buf->fd = -1;
537
0
  }
538
539
0
  msgbuf->queued--;
540
0
  ibuf_free(buf);
541
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/imsg.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/imsg.c.html index 8aa9b3cd1..43e32700f 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/imsg.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/imsg.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <unistd.h>
28
29
#include "openbsd-compat.h"
30
#include "imsg.h"
31
32
int  imsg_fd_overhead = 0;
33
34
static int   imsg_get_fd(struct imsgbuf *);
35
36
void
37
imsg_init(struct imsgbuf *ibuf, int fd)
38
0
{
39
0
  msgbuf_init(&ibuf->w);
40
0
  memset(&ibuf->r, 0, sizeof(ibuf->r));
41
0
  ibuf->fd = fd;
42
0
  ibuf->w.fd = fd;
43
0
  ibuf->pid = getpid();
44
0
  TAILQ_INIT(&ibuf->fds);
45
0
}
46
47
#ifdef _WIN32
48
ssize_t
49
imsg_read(struct imsgbuf *ibuf)
50
{
51
  ssize_t      n;
52
  uint8_t     *base;
53
  size_t       len;
54
55
  base = ibuf->r.buf + ibuf->r.wpos;
56
  len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
57
58
  while ((n = recv(ibuf->fd, base, len, 0)) == -1) {
59
    if (errno != EINTR)
60
      return (-1);
61
  }
62
  ibuf->r.wpos += n;
63
  return (n);
64
}
65
#else
66
ssize_t
67
imsg_read(struct imsgbuf *ibuf)
68
0
{
69
0
  struct msghdr    msg;
70
0
  struct cmsghdr    *cmsg;
71
0
  union {
72
0
    struct cmsghdr hdr;
73
0
    char  buf[CMSG_SPACE(sizeof(int) * 1)];
74
0
  } cmsgbuf;
75
0
  struct iovec     iov;
76
0
  ssize_t      n = -1;
77
0
  int      fd;
78
0
  struct imsg_fd    *ifd;
79
80
0
  memset(&msg, 0, sizeof(msg));
81
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
82
83
0
  iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
84
0
  iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
85
0
  msg.msg_iov = &iov;
86
0
  msg.msg_iovlen = 1;
87
0
  msg.msg_control = &cmsgbuf.buf;
88
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
89
90
0
  if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
91
0
    return (-1);
92
93
0
again:
94
0
  if (getdtablecount() + imsg_fd_overhead +
95
0
      (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
96
0
      >= getdtablesize()) {
97
0
    errno = EAGAIN;
98
0
    free(ifd);
99
0
    return (-1);
100
0
  }
101
102
0
  if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
103
0
    if (errno == EINTR)
104
0
      goto again;
105
0
    goto fail;
106
0
  }
107
108
0
  ibuf->r.wpos += n;
109
110
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
111
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
112
0
    if (cmsg->cmsg_level == SOL_SOCKET &&
113
0
        cmsg->cmsg_type == SCM_RIGHTS) {
114
0
      int i;
115
0
      int j;
116
117
      /*
118
       * We only accept one file descriptor.  Due to C
119
       * padding rules, our control buffer might contain
120
       * more than one fd, and we must close them.
121
       */
122
0
      j = ((char *)cmsg + cmsg->cmsg_len -
123
0
          (char *)CMSG_DATA(cmsg)) / sizeof(int);
124
0
      for (i = 0; i < j; i++) {
125
0
        fd = ((int *)CMSG_DATA(cmsg))[i];
126
0
        if (ifd != NULL) {
127
0
          ifd->fd = fd;
128
0
          TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
129
0
              entry);
130
0
          ifd = NULL;
131
0
        } else
132
0
          close(fd);
133
0
      }
134
0
    }
135
    /* we do not handle other ctl data level */
136
0
  }
137
138
0
fail:
139
0
  free(ifd);
140
0
  return (n);
141
0
}
142
#endif
143
144
ssize_t
145
imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
146
0
{
147
0
  size_t       av, left, datalen;
148
149
0
  av = ibuf->r.wpos;
150
151
0
  if (IMSG_HEADER_SIZE > av)
152
0
    return (0);
153
154
0
  memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
155
0
  if (imsg->hdr.len < IMSG_HEADER_SIZE ||
156
0
      imsg->hdr.len > MAX_IMSGSIZE) {
157
0
    errno = ERANGE;
158
0
    return (-1);
159
0
  }
160
0
  if (imsg->hdr.len > av)
161
0
    return (0);
162
0
  datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
163
0
  ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
164
0
  if (datalen == 0)
165
0
    imsg->data = NULL;
166
0
  else if ((imsg->data = malloc(datalen)) == NULL)
167
0
    return (-1);
168
169
0
  if (imsg->hdr.flags & IMSGF_HASFD)
170
0
    imsg->fd = imsg_get_fd(ibuf);
171
0
  else
172
0
    imsg->fd = -1;
173
174
0
  if (datalen != 0)
175
0
    memcpy(imsg->data, ibuf->r.rptr, datalen);
176
177
0
  if (imsg->hdr.len < av) {
178
0
    left = av - imsg->hdr.len;
179
0
    memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
180
0
    ibuf->r.wpos = left;
181
0
  } else
182
0
    ibuf->r.wpos = 0;
183
184
0
  return (datalen + IMSG_HEADER_SIZE);
185
0
}
186
187
int
188
imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
189
    int fd, const void *data, uint16_t datalen)
190
0
{
191
0
  struct ibuf *wbuf;
192
193
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
194
0
    return (-1);
195
196
0
  if (imsg_add(wbuf, data, datalen) == -1)
197
0
    return (-1);
198
199
0
  ibuf_fd_set(wbuf, fd);
200
201
0
  imsg_close(ibuf, wbuf);
202
203
0
  return (1);
204
0
}
205
206
int
207
imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
208
    int fd, const struct iovec *iov, int iovcnt)
209
0
{
210
0
  struct ibuf *wbuf;
211
0
  int    i, datalen = 0;
212
213
0
  for (i = 0; i < iovcnt; i++)
214
0
    datalen += iov[i].iov_len;
215
216
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
217
0
    return (-1);
218
219
0
  for (i = 0; i < iovcnt; i++)
220
0
    if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
221
0
      return (-1);
222
223
0
  ibuf_fd_set(wbuf, fd);
224
225
0
  imsg_close(ibuf, wbuf);
226
227
0
  return (1);
228
0
}
229
230
int
231
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
232
    pid_t pid, struct ibuf *buf)
233
0
{
234
0
  struct ibuf *wbuf = NULL;
235
0
  struct imsg_hdr  hdr;
236
0
  int save_errno;
237
238
0
  if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
239
0
    errno = ERANGE;
240
0
    goto fail;
241
0
  }
242
243
0
  hdr.type = type;
244
0
  hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
245
0
  hdr.flags = 0;
246
0
  hdr.peerid = peerid;
247
0
  if ((hdr.pid = pid) == 0)
248
0
    hdr.pid = ibuf->pid;
249
250
0
  if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
251
0
    goto fail;
252
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
253
0
    goto fail;
254
255
0
  ibuf_close(&ibuf->w, wbuf);
256
0
  ibuf_close(&ibuf->w, buf);
257
0
  return (1);
258
259
0
 fail:
260
0
  save_errno = errno;
261
0
  ibuf_free(buf);
262
0
  ibuf_free(wbuf);
263
0
  errno = save_errno;
264
0
  return (-1);
265
0
}
266
267
struct ibuf *
268
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
269
    uint16_t datalen)
270
0
{
271
0
  struct ibuf *wbuf;
272
0
  struct imsg_hdr  hdr;
273
274
0
  datalen += IMSG_HEADER_SIZE;
275
0
  if (datalen > MAX_IMSGSIZE) {
276
0
    errno = ERANGE;
277
0
    return (NULL);
278
0
  }
279
280
0
  hdr.type = type;
281
0
  hdr.flags = 0;
282
0
  hdr.peerid = peerid;
283
0
  if ((hdr.pid = pid) == 0)
284
0
    hdr.pid = ibuf->pid;
285
0
  if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
286
0
    return (NULL);
287
0
  }
288
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
289
0
    return (NULL);
290
291
0
  return (wbuf);
292
0
}
293
294
int
295
imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
296
0
{
297
0
  if (datalen)
298
0
    if (ibuf_add(msg, data, datalen) == -1) {
299
0
      ibuf_free(msg);
300
0
      return (-1);
301
0
    }
302
0
  return (datalen);
303
0
}
304
305
void
306
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
307
0
{
308
0
  struct imsg_hdr *hdr;
309
310
0
  hdr = (struct imsg_hdr *)msg->buf;
311
312
0
  hdr->flags &= ~IMSGF_HASFD;
313
0
  if (ibuf_fd_avail(msg))
314
0
    hdr->flags |= IMSGF_HASFD;
315
0
  hdr->len = ibuf_size(msg);
316
317
0
  ibuf_close(&ibuf->w, msg);
318
0
}
319
320
void
321
imsg_free(struct imsg *imsg)
322
0
{
323
0
  freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
324
0
}
325
326
static int
327
imsg_get_fd(struct imsgbuf *ibuf)
328
0
{
329
0
  int    fd;
330
0
  struct imsg_fd  *ifd;
331
332
0
  if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
333
0
    return (-1);
334
335
0
  fd = ifd->fd;
336
0
  TAILQ_REMOVE(&ibuf->fds, ifd, entry);
337
0
  free(ifd);
338
339
0
  return (fd);
340
0
}
341
342
int
343
imsg_flush(struct imsgbuf *ibuf)
344
0
{
345
0
  while (ibuf->w.queued)
346
0
    if (msgbuf_write(&ibuf->w) <= 0)
347
0
      return (-1);
348
0
  return (0);
349
0
}
350
351
void
352
imsg_clear(struct imsgbuf *ibuf)
353
0
{
354
0
  int fd;
355
356
0
  msgbuf_clear(&ibuf->w);
357
0
  while ((fd = imsg_get_fd(ibuf)) != -1)
358
0
    close(fd);
359
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <unistd.h>
28
29
#include "openbsd-compat.h"
30
#include "imsg.h"
31
32
int  imsg_fd_overhead = 0;
33
34
static int   imsg_get_fd(struct imsgbuf *);
35
36
void
37
imsg_init(struct imsgbuf *ibuf, int fd)
38
0
{
39
0
  msgbuf_init(&ibuf->w);
40
0
  memset(&ibuf->r, 0, sizeof(ibuf->r));
41
0
  ibuf->fd = fd;
42
0
  ibuf->w.fd = fd;
43
0
  ibuf->pid = getpid();
44
0
  TAILQ_INIT(&ibuf->fds);
45
0
}
46
47
#ifdef _WIN32
48
ssize_t
49
imsg_read(struct imsgbuf *ibuf)
50
{
51
  ssize_t      n;
52
  uint8_t     *base;
53
  size_t       len;
54
55
  base = ibuf->r.buf + ibuf->r.wpos;
56
  len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
57
58
  while ((n = recv(ibuf->fd, base, len, 0)) == -1) {
59
    if (errno != EINTR)
60
      return (-1);
61
  }
62
  ibuf->r.wpos += n;
63
  return (n);
64
}
65
#else
66
ssize_t
67
imsg_read(struct imsgbuf *ibuf)
68
0
{
69
0
  struct msghdr    msg;
70
0
  struct cmsghdr    *cmsg;
71
0
  union {
72
0
    struct cmsghdr hdr;
73
0
    char  buf[CMSG_SPACE(sizeof(int) * 1)];
74
0
  } cmsgbuf;
75
0
  struct iovec     iov;
76
0
  ssize_t      n = -1;
77
0
  int      fd;
78
0
  struct imsg_fd    *ifd;
79
80
0
  memset(&msg, 0, sizeof(msg));
81
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
82
83
0
  iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
84
0
  iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
85
0
  msg.msg_iov = &iov;
86
0
  msg.msg_iovlen = 1;
87
0
  msg.msg_control = &cmsgbuf.buf;
88
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
89
90
0
  if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
91
0
    return (-1);
92
93
0
again:
94
0
  if (getdtablecount() + imsg_fd_overhead +
95
0
      (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
96
0
      >= getdtablesize()) {
97
0
    errno = EAGAIN;
98
0
    free(ifd);
99
0
    return (-1);
100
0
  }
101
102
0
  if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
103
0
    if (errno == EINTR)
104
0
      goto again;
105
0
    goto fail;
106
0
  }
107
108
0
  ibuf->r.wpos += n;
109
110
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
111
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
112
0
    if (cmsg->cmsg_level == SOL_SOCKET &&
113
0
        cmsg->cmsg_type == SCM_RIGHTS) {
114
0
      int i;
115
0
      int j;
116
117
      /*
118
       * We only accept one file descriptor.  Due to C
119
       * padding rules, our control buffer might contain
120
       * more than one fd, and we must close them.
121
       */
122
0
      j = ((char *)cmsg + cmsg->cmsg_len -
123
0
          (char *)CMSG_DATA(cmsg)) / sizeof(int);
124
0
      for (i = 0; i < j; i++) {
125
0
        fd = ((int *)CMSG_DATA(cmsg))[i];
126
0
        if (ifd != NULL) {
127
0
          ifd->fd = fd;
128
0
          TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
129
0
              entry);
130
0
          ifd = NULL;
131
0
        } else
132
0
          close(fd);
133
0
      }
134
0
    }
135
    /* we do not handle other ctl data level */
136
0
  }
137
138
0
fail:
139
0
  free(ifd);
140
0
  return (n);
141
0
}
142
#endif
143
144
ssize_t
145
imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
146
0
{
147
0
  size_t       av, left, datalen;
148
149
0
  av = ibuf->r.wpos;
150
151
0
  if (IMSG_HEADER_SIZE > av)
152
0
    return (0);
153
154
0
  memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
155
0
  if (imsg->hdr.len < IMSG_HEADER_SIZE ||
156
0
      imsg->hdr.len > MAX_IMSGSIZE) {
157
0
    errno = ERANGE;
158
0
    return (-1);
159
0
  }
160
0
  if (imsg->hdr.len > av)
161
0
    return (0);
162
0
  datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
163
0
  ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
164
0
  if (datalen == 0)
165
0
    imsg->data = NULL;
166
0
  else if ((imsg->data = malloc(datalen)) == NULL)
167
0
    return (-1);
168
169
0
  if (imsg->hdr.flags & IMSGF_HASFD)
170
0
    imsg->fd = imsg_get_fd(ibuf);
171
0
  else
172
0
    imsg->fd = -1;
173
174
0
  if (datalen != 0)
175
0
    memcpy(imsg->data, ibuf->r.rptr, datalen);
176
177
0
  if (imsg->hdr.len < av) {
178
0
    left = av - imsg->hdr.len;
179
0
    memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
180
0
    ibuf->r.wpos = left;
181
0
  } else
182
0
    ibuf->r.wpos = 0;
183
184
0
  return (datalen + IMSG_HEADER_SIZE);
185
0
}
186
187
int
188
imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
189
    int fd, const void *data, uint16_t datalen)
190
0
{
191
0
  struct ibuf *wbuf;
192
193
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
194
0
    return (-1);
195
196
0
  if (imsg_add(wbuf, data, datalen) == -1)
197
0
    return (-1);
198
199
0
  ibuf_fd_set(wbuf, fd);
200
201
0
  imsg_close(ibuf, wbuf);
202
203
0
  return (1);
204
0
}
205
206
int
207
imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
208
    int fd, const struct iovec *iov, int iovcnt)
209
0
{
210
0
  struct ibuf *wbuf;
211
0
  int    i, datalen = 0;
212
213
0
  for (i = 0; i < iovcnt; i++)
214
0
    datalen += iov[i].iov_len;
215
216
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
217
0
    return (-1);
218
219
0
  for (i = 0; i < iovcnt; i++)
220
0
    if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
221
0
      return (-1);
222
223
0
  ibuf_fd_set(wbuf, fd);
224
225
0
  imsg_close(ibuf, wbuf);
226
227
0
  return (1);
228
0
}
229
230
int
231
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
232
    pid_t pid, struct ibuf *buf)
233
0
{
234
0
  struct ibuf *wbuf = NULL;
235
0
  struct imsg_hdr  hdr;
236
0
  int save_errno;
237
238
0
  if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
239
0
    errno = ERANGE;
240
0
    goto fail;
241
0
  }
242
243
0
  hdr.type = type;
244
0
  hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
245
0
  hdr.flags = 0;
246
0
  hdr.peerid = peerid;
247
0
  if ((hdr.pid = pid) == 0)
248
0
    hdr.pid = ibuf->pid;
249
250
0
  if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
251
0
    goto fail;
252
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
253
0
    goto fail;
254
255
0
  ibuf_close(&ibuf->w, wbuf);
256
0
  ibuf_close(&ibuf->w, buf);
257
0
  return (1);
258
259
0
 fail:
260
0
  save_errno = errno;
261
0
  ibuf_free(buf);
262
0
  ibuf_free(wbuf);
263
0
  errno = save_errno;
264
0
  return (-1);
265
0
}
266
267
struct ibuf *
268
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
269
    uint16_t datalen)
270
0
{
271
0
  struct ibuf *wbuf;
272
0
  struct imsg_hdr  hdr;
273
274
0
  datalen += IMSG_HEADER_SIZE;
275
0
  if (datalen > MAX_IMSGSIZE) {
276
0
    errno = ERANGE;
277
0
    return (NULL);
278
0
  }
279
280
0
  hdr.type = type;
281
0
  hdr.flags = 0;
282
0
  hdr.peerid = peerid;
283
0
  if ((hdr.pid = pid) == 0)
284
0
    hdr.pid = ibuf->pid;
285
0
  if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
286
0
    return (NULL);
287
0
  }
288
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
289
0
    return (NULL);
290
291
0
  return (wbuf);
292
0
}
293
294
int
295
imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
296
0
{
297
0
  if (datalen)
298
0
    if (ibuf_add(msg, data, datalen) == -1) {
299
0
      ibuf_free(msg);
300
0
      return (-1);
301
0
    }
302
0
  return (datalen);
303
0
}
304
305
void
306
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
307
0
{
308
0
  struct imsg_hdr *hdr;
309
310
0
  hdr = (struct imsg_hdr *)msg->buf;
311
312
0
  hdr->flags &= ~IMSGF_HASFD;
313
0
  if (ibuf_fd_avail(msg))
314
0
    hdr->flags |= IMSGF_HASFD;
315
0
  hdr->len = ibuf_size(msg);
316
317
0
  ibuf_close(&ibuf->w, msg);
318
0
}
319
320
void
321
imsg_free(struct imsg *imsg)
322
0
{
323
0
  freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
324
0
}
325
326
static int
327
imsg_get_fd(struct imsgbuf *ibuf)
328
0
{
329
0
  int    fd;
330
0
  struct imsg_fd  *ifd;
331
332
0
  if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
333
0
    return (-1);
334
335
0
  fd = ifd->fd;
336
0
  TAILQ_REMOVE(&ibuf->fds, ifd, entry);
337
0
  free(ifd);
338
339
0
  return (fd);
340
0
}
341
342
int
343
imsg_flush(struct imsgbuf *ibuf)
344
0
{
345
0
  while (ibuf->w.queued)
346
0
    if (msgbuf_write(&ibuf->w) <= 0)
347
0
      return (-1);
348
0
  return (0);
349
0
}
350
351
void
352
imsg_clear(struct imsgbuf *ibuf)
353
0
{
354
0
  int fd;
355
356
0
  msgbuf_clear(&ibuf->w);
357
0
  while ((fd = imsg_get_fd(ibuf)) != -1)
358
0
    close(fd);
359
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/imsg.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/imsg.h.html index 729f4879a..b8e4e4302 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/imsg.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/imsg.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
5
 * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#ifndef _IMSG_H_
22
#define _IMSG_H_
23
24
#include <stdint.h>
25
26
#define IBUF_READ_SIZE    65535
27
0
#define IMSG_HEADER_SIZE  sizeof(struct imsg_hdr)
28
0
#define MAX_IMSGSIZE    16384
29
30
struct ibuf {
31
  TAILQ_ENTRY(ibuf)  entry;
32
  unsigned char   *buf;
33
  size_t       size;
34
  size_t       max;
35
  size_t       wpos;
36
  size_t       rpos;
37
  int      fd;
38
};
39
40
struct msgbuf {
41
  TAILQ_HEAD(, ibuf)   bufs;
42
  uint32_t     queued;
43
  int      fd;
44
};
45
46
struct ibuf_read {
47
  unsigned char    buf[IBUF_READ_SIZE];
48
  unsigned char   *rptr;
49
  size_t       wpos;
50
};
51
52
struct imsg_fd {
53
  TAILQ_ENTRY(imsg_fd)  entry;
54
  int     fd;
55
};
56
57
struct imsgbuf {
58
  TAILQ_HEAD(, imsg_fd)  fds;
59
  struct ibuf_read   r;
60
  struct msgbuf    w;
61
  int      fd;
62
  pid_t      pid;
63
};
64
65
0
#define IMSGF_HASFD 1
66
67
struct imsg_hdr {
68
  uint32_t   type;
69
  uint16_t   len;
70
  uint16_t   flags;
71
  uint32_t   peerid;
72
  uint32_t   pid;
73
};
74
75
struct imsg {
76
  struct imsg_hdr  hdr;
77
  int    fd;
78
  void    *data;
79
};
80
81
struct iovec;
82
83
/* imsg-buffer.c */
84
struct ibuf *ibuf_open(size_t);
85
struct ibuf *ibuf_dynamic(size_t, size_t);
86
int    ibuf_add(struct ibuf *, const void *, size_t);
87
int    ibuf_add_buf(struct ibuf *, const struct ibuf *);
88
int    ibuf_add_zero(struct ibuf *, size_t);
89
int    ibuf_add_n8(struct ibuf *, uint64_t);
90
int    ibuf_add_n16(struct ibuf *, uint64_t);
91
int    ibuf_add_n32(struct ibuf *, uint64_t);
92
int    ibuf_add_n64(struct ibuf *, uint64_t);
93
void    *ibuf_reserve(struct ibuf *, size_t);
94
void    *ibuf_seek(struct ibuf *, size_t, size_t);
95
int    ibuf_set(struct ibuf *, size_t, const void *, size_t);
96
int    ibuf_set_n8(struct ibuf *, size_t, uint64_t);
97
int    ibuf_set_n16(struct ibuf *, size_t, uint64_t);
98
int    ibuf_set_n32(struct ibuf *, size_t, uint64_t);
99
int    ibuf_set_n64(struct ibuf *, size_t, uint64_t);
100
void    *ibuf_data(struct ibuf *);
101
size_t     ibuf_size(struct ibuf *);
102
size_t     ibuf_left(struct ibuf *);
103
void     ibuf_close(struct msgbuf *, struct ibuf *);
104
void     ibuf_free(struct ibuf *);
105
int    ibuf_fd_avail(struct ibuf *);
106
int    ibuf_fd_get(struct ibuf *);
107
void     ibuf_fd_set(struct ibuf *, int);
108
int    ibuf_write(struct msgbuf *);
109
void     msgbuf_init(struct msgbuf *);
110
void     msgbuf_clear(struct msgbuf *);
111
int    msgbuf_write(struct msgbuf *);
112
113
/* imsg.c */
114
void   imsg_init(struct imsgbuf *, int);
115
ssize_t  imsg_read(struct imsgbuf *);
116
ssize_t  imsg_get(struct imsgbuf *, struct imsg *);
117
int  imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
118
      const void *, uint16_t);
119
int  imsg_composev(struct imsgbuf *, uint32_t, uint32_t,  pid_t, int,
120
      const struct iovec *, int);
121
int  imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
122
      struct ibuf *);
123
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
124
int  imsg_add(struct ibuf *, const void *, uint16_t);
125
void   imsg_close(struct imsgbuf *, struct ibuf *);
126
void   imsg_free(struct imsg *);
127
int  imsg_flush(struct imsgbuf *);
128
void   imsg_clear(struct imsgbuf *);
129
130
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
5
 * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#ifndef _IMSG_H_
22
#define _IMSG_H_
23
24
#include <stdint.h>
25
26
#define IBUF_READ_SIZE    65535
27
0
#define IMSG_HEADER_SIZE  sizeof(struct imsg_hdr)
28
0
#define MAX_IMSGSIZE    16384
29
30
struct ibuf {
31
  TAILQ_ENTRY(ibuf)  entry;
32
  unsigned char   *buf;
33
  size_t       size;
34
  size_t       max;
35
  size_t       wpos;
36
  size_t       rpos;
37
  int      fd;
38
};
39
40
struct msgbuf {
41
  TAILQ_HEAD(, ibuf)   bufs;
42
  uint32_t     queued;
43
  int      fd;
44
};
45
46
struct ibuf_read {
47
  unsigned char    buf[IBUF_READ_SIZE];
48
  unsigned char   *rptr;
49
  size_t       wpos;
50
};
51
52
struct imsg_fd {
53
  TAILQ_ENTRY(imsg_fd)  entry;
54
  int     fd;
55
};
56
57
struct imsgbuf {
58
  TAILQ_HEAD(, imsg_fd)  fds;
59
  struct ibuf_read   r;
60
  struct msgbuf    w;
61
  int      fd;
62
  pid_t      pid;
63
};
64
65
0
#define IMSGF_HASFD 1
66
67
struct imsg_hdr {
68
  uint32_t   type;
69
  uint16_t   len;
70
  uint16_t   flags;
71
  uint32_t   peerid;
72
  uint32_t   pid;
73
};
74
75
struct imsg {
76
  struct imsg_hdr  hdr;
77
  int    fd;
78
  void    *data;
79
};
80
81
struct iovec;
82
83
/* imsg-buffer.c */
84
struct ibuf *ibuf_open(size_t);
85
struct ibuf *ibuf_dynamic(size_t, size_t);
86
int    ibuf_add(struct ibuf *, const void *, size_t);
87
int    ibuf_add_buf(struct ibuf *, const struct ibuf *);
88
int    ibuf_add_zero(struct ibuf *, size_t);
89
int    ibuf_add_n8(struct ibuf *, uint64_t);
90
int    ibuf_add_n16(struct ibuf *, uint64_t);
91
int    ibuf_add_n32(struct ibuf *, uint64_t);
92
int    ibuf_add_n64(struct ibuf *, uint64_t);
93
void    *ibuf_reserve(struct ibuf *, size_t);
94
void    *ibuf_seek(struct ibuf *, size_t, size_t);
95
int    ibuf_set(struct ibuf *, size_t, const void *, size_t);
96
int    ibuf_set_n8(struct ibuf *, size_t, uint64_t);
97
int    ibuf_set_n16(struct ibuf *, size_t, uint64_t);
98
int    ibuf_set_n32(struct ibuf *, size_t, uint64_t);
99
int    ibuf_set_n64(struct ibuf *, size_t, uint64_t);
100
void    *ibuf_data(struct ibuf *);
101
size_t     ibuf_size(struct ibuf *);
102
size_t     ibuf_left(struct ibuf *);
103
void     ibuf_close(struct msgbuf *, struct ibuf *);
104
void     ibuf_free(struct ibuf *);
105
int    ibuf_fd_avail(struct ibuf *);
106
int    ibuf_fd_get(struct ibuf *);
107
void     ibuf_fd_set(struct ibuf *, int);
108
int    ibuf_write(struct msgbuf *);
109
void     msgbuf_init(struct msgbuf *);
110
void     msgbuf_clear(struct msgbuf *);
111
int    msgbuf_write(struct msgbuf *);
112
113
/* imsg.c */
114
void   imsg_init(struct imsgbuf *, int);
115
ssize_t  imsg_read(struct imsgbuf *);
116
ssize_t  imsg_get(struct imsgbuf *, struct imsg *);
117
int  imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
118
      const void *, uint16_t);
119
int  imsg_composev(struct imsgbuf *, uint32_t, uint32_t,  pid_t, int,
120
      const struct iovec *, int);
121
int  imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
122
      struct ibuf *);
123
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
124
int  imsg_add(struct ibuf *, const void *, uint16_t);
125
void   imsg_close(struct imsgbuf *, struct ibuf *);
126
void   imsg_free(struct imsg *);
127
int  imsg_flush(struct imsgbuf *);
128
void   imsg_clear(struct imsgbuf *);
129
130
#endif
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/openbsd-compat.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/openbsd-compat.h.html index 55a2c973d..e4824fc0a 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/openbsd-compat.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/openbsd-compat.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/openbsd-compat.h
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#ifndef _OPENBSD_COMPAT_H
4
#define _OPENBSD_COMPAT_H
5
6
#define YYSTYPE_IS_DECLARED 1 /* for bison */
7
8
#ifndef LOGIN_NAME_MAX
9
# define LOGIN_NAME_MAX 9
10
#endif
11
12
#include <stdlib.h>
13
14
#if !defined(HAVE_STRLCAT)
15
size_t strlcat(char *, const char *, size_t);
16
#endif
17
18
#if !defined(HAVE_STRLCPY)
19
size_t strlcpy(char *, const char *, size_t);
20
#endif
21
22
#if !defined(HAVE_REALLOCARRAY)
23
void *reallocarray(void *, size_t, size_t);
24
#endif
25
26
#if !defined(HAVE_RECALLOCARRAY)
27
void *recallocarray(void *, size_t, size_t, size_t);
28
#endif
29
30
#if !defined(HAVE_EXPLICIT_BZERO)
31
void explicit_bzero(void *, size_t);
32
#endif
33
34
#if !defined(HAVE_GETPAGESIZE)
35
int getpagesize(void);
36
#endif
37
38
#if !defined(HAVE_TIMINGSAFE_BCMP)
39
int timingsafe_bcmp(const void *, const void *, size_t);
40
#endif
41
42
#if !defined(HAVE_ACCEPT4)
43
#include <sys/socket.h>
44
#define accept4 bsd_accept4
45
int bsd_accept4(int, struct sockaddr *, socklen_t *, int flags);
46
#endif
47
48
#if !defined(HAVE_SOCK_NONBLOCK)
49
#define SOCK_NONBLOCK 0x4000  /* Set O_NONBLOCK */
50
#define SOCK_CLOEXEC  0x8000  /* Set FD_CLOEXEC */
51
#define SOCK_SETFLAGS 0xf000  /* Set flags as checked above */
52
#define socket bsd_socket
53
int bsd_socket(int domain, int type, int protocol);
54
#endif
55
56
#if !defined(HAVE_SETPROCTITLE)
57
void compat_init_setproctitle(int argc, char *argv[]);
58
void setproctitle(const char *fmt, ...);
59
#endif
60
61
#if !defined(HAVE_SETRESGID)
62
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
63
#endif
64
65
#if !defined(HAVE_SETRESUID)
66
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
67
#endif
68
69
#ifdef _WIN32
70
#include <direct.h>
71
uid_t geteuid(void);
72
#endif
73
74
#if !defined(HAVE_GETRTABLE)
75
int getrtable(void);
76
#endif
77
78
#if !defined(HAVE_SETRTABLE)
79
int setrtable(int rtableid);
80
#endif
81
82
#if !defined(HAVE_STRTONUM)
83
long long
84
strtonum(const char *nptr, long long minval, long long maxval,
85
    const char **errstr);
86
#endif
87
88
#if !defined(HAVE_FREEZERO)
89
void freezero(void *ptr, size_t size);
90
#endif
91
92
#if !defined(HAVE_GETDTABLECOUNT)
93
int getdtablecount(void);
94
#endif
95
96
#if !defined(HAVE_GETOPT)
97
#include "getopt.h"
98
#endif
99
100
#if !defined(HAVE_USLEEP)
101
int usleep(unsigned int x);
102
#endif
103
104
#ifdef HAVE_SOCKADDR_SA_LEN
105
#ifndef SA_LEN
106
#define SA_LEN(sa)      (sa)->sa_len
107
#endif
108
#ifndef SS_LEN
109
#define SS_LEN(ss)      (ss).ss_len
110
#endif
111
#else
112
#define SA_LEN(sa)                  \
113
14.0k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
14.0k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
2.24k
  sizeof(struct sockaddr))
116
#define SS_LEN(ss)              \
117
  ((ss.ss_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
118
  (ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
119
  sizeof(struct sockaddr_storage))
120
#endif
121
122
#ifndef HAVE_FFS
123
int ffs(int);
124
#endif
125
126
#ifdef __OpenBSD__
127
typedef int evutil_socket_t;
128
#endif
129
130
#ifndef _PASSWORD_LEN
131
#define _PASSWORD_LEN 120
132
#endif
133
134
#ifdef HAVE_DIRENT_H
135
# include <dirent.h>
136
# define NAMLEN(dirent) strlen((dirent)->d_name)
137
#else
138
# define dirent direct
139
# define NAMLEN(dirent) (dirent)->d_namlen
140
# ifdef HAVE_SYS_NDIR_H
141
#  include <sys/ndir.h>
142
# endif
143
# ifdef HAVE_SYS_DIR_H
144
#  include <sys/dir.h>
145
# endif
146
# ifdef HAVE_NDIR_H
147
#  include <ndir.h>
148
# endif
149
#endif
150
151
#if !defined(AF_LINK) && defined(AF_PACKET)
152
#define AF_LINK AF_PACKET /* XXX workaround on Linux */
153
#endif
154
155
#ifndef HOST_NAME_MAX
156
# include "netdb.h" /* for MAXHOSTNAMELEN */
157
# if defined(_POSIX_HOST_NAME_MAX)
158
#  define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
159
# elif defined(MAXHOSTNAMELEN)
160
#  define HOST_NAME_MAX MAXHOSTNAMELEN
161
# else
162
#  define HOST_NAME_MAX 255
163
# endif
164
#endif /* HOST_NAME_MAX */
165
166
/* FreeBSD */
167
#ifndef CPI_PRIVATE_MIN
168
#define CPI_PRIVATE_MIN   61440
169
#endif
170
#ifndef CPI_PRIVATE_MAX
171
#define CPI_PRIVATE_MAX   65535
172
#endif
173
174
#if !defined(SADB_X_ADDFLOW) && defined(SADB_X_SPDUPDATE)
175
#define SADB_X_ADDFLOW  SADB_X_SPDUPDATE
176
#endif
177
#if !defined(SADB_X_DELFLOW) && defined(SADB_X_SPDDELETE)
178
#define SADB_X_DELFLOW  SADB_X_SPDDELETE
179
#endif
180
#if !defined(SADB_X_FLOW_TYPE_DENY)
181
#define SADB_X_FLOW_TYPE_DENY 1
182
#endif
183
184
#if defined(HAVE_LINUX_PFKEY_H)
185
/* Encryption Algorithms */
186
#define SADB_X_EALG_AES   SADB_X_EALG_AESCBC
187
#define SADB_X_EALG_AESGCM16  SADB_X_EALG_AES_GCM_ICV16
188
#define SADB_X_EALG_AESGMAC SADB_X_EALG_NULL_AES_GMAC
189
190
/* Authentication Algorithms */
191
#define SADB_X_AALG_SHA2_256  SADB_X_AALG_SHA2_256HMAC
192
#define SADB_X_AALG_SHA2_384  SADB_X_AALG_SHA2_384HMAC
193
#define SADB_X_AALG_SHA2_512  SADB_X_AALG_SHA2_512HMAC
194
#endif
195
196
#if !defined(__packed)
197
#define __packed  __attribute__((__packed__))
198
#endif
199
200
#if defined(HAVE_APPLE_NATT) && !defined(SADB_X_EXT_NATT)
201
/*
202
 * These are hidden in Apple XNU's private pfkeyv2.h header
203
 */
204
#define SADB_X_EXT_NATT     0x0002  /* Enable UDP encapsulation */
205
#define SADB_X_EXT_NATT_KEEPALIVE 0x0004  /* Send NAT-T keepalives */
206
#define SADB_X_EXT_NATT_MULTIPLEUSERS 0x0008  /* Use for VPN gateways */
207
#define SADB_X_EXT_NATT_DETECTED_PEER 0x1000  /* Opposite of KEEPALIVE */
208
209
struct sadb_sa_natt {
210
  uint16_t   sadb_sa_natt_port;
211
  union {
212
    uint16_t   sadb_reserved0;
213
    uint16_t   sadb_sa_natt_interval;
214
  };
215
  uint16_t   sadb_sa_natt_offload_interval;
216
  uint16_t   sadb_sa_natt_src_port;
217
};
218
#endif
219
220
#endif /* !_OPENBSD_COMPAT_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/openbsd-compat.h
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#ifndef _OPENBSD_COMPAT_H
4
#define _OPENBSD_COMPAT_H
5
6
#define YYSTYPE_IS_DECLARED 1 /* for bison */
7
8
#ifndef LOGIN_NAME_MAX
9
# define LOGIN_NAME_MAX 9
10
#endif
11
12
#include <stdlib.h>
13
14
#if !defined(HAVE_STRLCAT)
15
size_t strlcat(char *, const char *, size_t);
16
#endif
17
18
#if !defined(HAVE_STRLCPY)
19
size_t strlcpy(char *, const char *, size_t);
20
#endif
21
22
#if !defined(HAVE_REALLOCARRAY)
23
void *reallocarray(void *, size_t, size_t);
24
#endif
25
26
#if !defined(HAVE_RECALLOCARRAY)
27
void *recallocarray(void *, size_t, size_t, size_t);
28
#endif
29
30
#if !defined(HAVE_EXPLICIT_BZERO)
31
void explicit_bzero(void *, size_t);
32
#endif
33
34
#if !defined(HAVE_GETPAGESIZE)
35
int getpagesize(void);
36
#endif
37
38
#if !defined(HAVE_TIMINGSAFE_BCMP)
39
int timingsafe_bcmp(const void *, const void *, size_t);
40
#endif
41
42
#if !defined(HAVE_ACCEPT4)
43
#include <sys/socket.h>
44
#define accept4 bsd_accept4
45
int bsd_accept4(int, struct sockaddr *, socklen_t *, int flags);
46
#endif
47
48
#if !defined(HAVE_SOCK_NONBLOCK)
49
#define SOCK_NONBLOCK 0x4000  /* Set O_NONBLOCK */
50
#define SOCK_CLOEXEC  0x8000  /* Set FD_CLOEXEC */
51
#define SOCK_SETFLAGS 0xf000  /* Set flags as checked above */
52
#define socket bsd_socket
53
int bsd_socket(int domain, int type, int protocol);
54
#endif
55
56
#if !defined(HAVE_SETPROCTITLE)
57
void compat_init_setproctitle(int argc, char *argv[]);
58
void setproctitle(const char *fmt, ...);
59
#endif
60
61
#if !defined(HAVE_SETRESGID)
62
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
63
#endif
64
65
#if !defined(HAVE_SETRESUID)
66
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
67
#endif
68
69
#ifdef _WIN32
70
#include <direct.h>
71
uid_t geteuid(void);
72
#endif
73
74
#if !defined(HAVE_GETRTABLE)
75
int getrtable(void);
76
#endif
77
78
#if !defined(HAVE_SETRTABLE)
79
int setrtable(int rtableid);
80
#endif
81
82
#if !defined(HAVE_STRTONUM)
83
long long
84
strtonum(const char *nptr, long long minval, long long maxval,
85
    const char **errstr);
86
#endif
87
88
#if !defined(HAVE_FREEZERO)
89
void freezero(void *ptr, size_t size);
90
#endif
91
92
#if !defined(HAVE_GETDTABLECOUNT)
93
int getdtablecount(void);
94
#endif
95
96
#if !defined(HAVE_GETOPT)
97
#include "getopt.h"
98
#endif
99
100
#if !defined(HAVE_USLEEP)
101
int usleep(unsigned int x);
102
#endif
103
104
#ifdef HAVE_SOCKADDR_SA_LEN
105
#ifndef SA_LEN
106
#define SA_LEN(sa)      (sa)->sa_len
107
#endif
108
#ifndef SS_LEN
109
#define SS_LEN(ss)      (ss).ss_len
110
#endif
111
#else
112
#define SA_LEN(sa)                  \
113
14.2k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
14.2k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
2.27k
  sizeof(struct sockaddr))
116
#define SS_LEN(ss)              \
117
  ((ss.ss_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
118
  (ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
119
  sizeof(struct sockaddr_storage))
120
#endif
121
122
#ifndef HAVE_FFS
123
int ffs(int);
124
#endif
125
126
#ifdef __OpenBSD__
127
typedef int evutil_socket_t;
128
#endif
129
130
#ifndef _PASSWORD_LEN
131
#define _PASSWORD_LEN 120
132
#endif
133
134
#ifdef HAVE_DIRENT_H
135
# include <dirent.h>
136
# define NAMLEN(dirent) strlen((dirent)->d_name)
137
#else
138
# define dirent direct
139
# define NAMLEN(dirent) (dirent)->d_namlen
140
# ifdef HAVE_SYS_NDIR_H
141
#  include <sys/ndir.h>
142
# endif
143
# ifdef HAVE_SYS_DIR_H
144
#  include <sys/dir.h>
145
# endif
146
# ifdef HAVE_NDIR_H
147
#  include <ndir.h>
148
# endif
149
#endif
150
151
#if !defined(AF_LINK) && defined(AF_PACKET)
152
#define AF_LINK AF_PACKET /* XXX workaround on Linux */
153
#endif
154
155
#ifndef HOST_NAME_MAX
156
# include "netdb.h" /* for MAXHOSTNAMELEN */
157
# if defined(_POSIX_HOST_NAME_MAX)
158
#  define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
159
# elif defined(MAXHOSTNAMELEN)
160
#  define HOST_NAME_MAX MAXHOSTNAMELEN
161
# else
162
#  define HOST_NAME_MAX 255
163
# endif
164
#endif /* HOST_NAME_MAX */
165
166
/* FreeBSD */
167
#ifndef CPI_PRIVATE_MIN
168
#define CPI_PRIVATE_MIN   61440
169
#endif
170
#ifndef CPI_PRIVATE_MAX
171
#define CPI_PRIVATE_MAX   65535
172
#endif
173
174
#if !defined(SADB_X_ADDFLOW) && defined(SADB_X_SPDUPDATE)
175
#define SADB_X_ADDFLOW  SADB_X_SPDUPDATE
176
#endif
177
#if !defined(SADB_X_DELFLOW) && defined(SADB_X_SPDDELETE)
178
#define SADB_X_DELFLOW  SADB_X_SPDDELETE
179
#endif
180
#if !defined(SADB_X_FLOW_TYPE_DENY)
181
#define SADB_X_FLOW_TYPE_DENY 1
182
#endif
183
184
#if defined(HAVE_LINUX_PFKEY_H)
185
/* Encryption Algorithms */
186
#define SADB_X_EALG_AES   SADB_X_EALG_AESCBC
187
#define SADB_X_EALG_AESGCM16  SADB_X_EALG_AES_GCM_ICV16
188
#define SADB_X_EALG_AESGMAC SADB_X_EALG_NULL_AES_GMAC
189
190
/* Authentication Algorithms */
191
#define SADB_X_AALG_SHA2_256  SADB_X_AALG_SHA2_256HMAC
192
#define SADB_X_AALG_SHA2_384  SADB_X_AALG_SHA2_384HMAC
193
#define SADB_X_AALG_SHA2_512  SADB_X_AALG_SHA2_512HMAC
194
#endif
195
196
#if !defined(__packed)
197
#define __packed  __attribute__((__packed__))
198
#endif
199
200
#if defined(HAVE_APPLE_NATT) && !defined(SADB_X_EXT_NATT)
201
/*
202
 * These are hidden in Apple XNU's private pfkeyv2.h header
203
 */
204
#define SADB_X_EXT_NATT     0x0002  /* Enable UDP encapsulation */
205
#define SADB_X_EXT_NATT_KEEPALIVE 0x0004  /* Send NAT-T keepalives */
206
#define SADB_X_EXT_NATT_MULTIPLEUSERS 0x0008  /* Use for VPN gateways */
207
#define SADB_X_EXT_NATT_DETECTED_PEER 0x1000  /* Opposite of KEEPALIVE */
208
209
struct sadb_sa_natt {
210
  uint16_t   sadb_sa_natt_port;
211
  union {
212
    uint16_t   sadb_reserved0;
213
    uint16_t   sadb_sa_natt_interval;
214
  };
215
  uint16_t   sadb_sa_natt_offload_interval;
216
  uint16_t   sadb_sa_natt_src_port;
217
};
218
#endif
219
220
#endif /* !_OPENBSD_COMPAT_H */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/recallocarray.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/recallocarray.c.html index 6156c06a8..3b37b177b 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/recallocarray.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/recallocarray.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/recallocarray.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */
2
/*
3
 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <errno.h>
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <string.h>
22
#include <unistd.h>
23
24
/*
25
 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
26
 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
27
 */
28
0
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
29
30
void *
31
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
32
0
{
33
0
  size_t oldsize, newsize;
34
0
  void *newptr;
35
36
0
  if (ptr == NULL)
37
0
    return calloc(newnmemb, size);
38
39
0
  if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
40
0
      newnmemb > 0 && SIZE_MAX / newnmemb < size) {
41
0
    errno = ENOMEM;
42
0
    return NULL;
43
0
  }
44
0
  newsize = newnmemb * size;
45
46
0
  if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
47
0
      oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
48
0
    errno = EINVAL;
49
0
    return NULL;
50
0
  }
51
0
  oldsize = oldnmemb * size;
52
  
53
  /*
54
   * Don't bother too much if we're shrinking just a bit,
55
   * we do not shrink for series of small steps, oh well.
56
   */
57
0
  if (newsize <= oldsize) {
58
0
    size_t d = oldsize - newsize;
59
60
0
    if (d < oldsize / 2 && d < (size_t)getpagesize()) {
61
0
      memset((char *)ptr + newsize, 0, d);
62
0
      return ptr;
63
0
    }
64
0
  }
65
66
0
  newptr = malloc(newsize);
67
0
  if (newptr == NULL)
68
0
    return NULL;
69
70
0
  if (newsize > oldsize) {
71
0
    memcpy(newptr, ptr, oldsize);
72
0
    memset((char *)newptr + oldsize, 0, newsize - oldsize);
73
0
  } else
74
0
    memcpy(newptr, ptr, newsize);
75
76
0
  explicit_bzero(ptr, oldsize);
77
0
  free(ptr);
78
79
0
  return newptr;
80
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/recallocarray.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */
2
/*
3
 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <errno.h>
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <string.h>
22
#include <unistd.h>
23
24
/*
25
 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
26
 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
27
 */
28
0
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
29
30
void *
31
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
32
0
{
33
0
  size_t oldsize, newsize;
34
0
  void *newptr;
35
36
0
  if (ptr == NULL)
37
0
    return calloc(newnmemb, size);
38
39
0
  if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
40
0
      newnmemb > 0 && SIZE_MAX / newnmemb < size) {
41
0
    errno = ENOMEM;
42
0
    return NULL;
43
0
  }
44
0
  newsize = newnmemb * size;
45
46
0
  if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
47
0
      oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
48
0
    errno = EINVAL;
49
0
    return NULL;
50
0
  }
51
0
  oldsize = oldnmemb * size;
52
  
53
  /*
54
   * Don't bother too much if we're shrinking just a bit,
55
   * we do not shrink for series of small steps, oh well.
56
   */
57
0
  if (newsize <= oldsize) {
58
0
    size_t d = oldsize - newsize;
59
60
0
    if (d < oldsize / 2 && d < (size_t)getpagesize()) {
61
0
      memset((char *)ptr + newsize, 0, d);
62
0
      return ptr;
63
0
    }
64
0
  }
65
66
0
  newptr = malloc(newsize);
67
0
  if (newptr == NULL)
68
0
    return NULL;
69
70
0
  if (newsize > oldsize) {
71
0
    memcpy(newptr, ptr, oldsize);
72
0
    memset((char *)newptr + oldsize, 0, newsize - oldsize);
73
0
  } else
74
0
    memcpy(newptr, ptr, newsize);
75
76
0
  explicit_bzero(ptr, oldsize);
77
0
  free(ptr);
78
79
0
  return newptr;
80
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/setproctitle.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/setproctitle.c.html index 94f1cbf82..8ba52d83b 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/setproctitle.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/setproctitle.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/setproctitle.c
Line
Count
Source (jump to first uncovered line)
1
/* Based on conf.c from UCB sendmail 8.8.8 */
2
3
/*
4
 * Copyright 2003 Damien Miller
5
 * Copyright (c) 1983, 1995-1997 Eric P. Allman
6
 * Copyright (c) 1988, 1993
7
 *  The Regents of the University of California.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 3. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include "openbsd-compat.h"
35
36
#ifndef HAVE_SETPROCTITLE
37
38
#include <stdarg.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
#ifdef HAVE_SYS_PSTAT_H
43
#include <sys/pstat.h>
44
#endif
45
#include <string.h>
46
47
#include <vis.h>
48
49
#define SPT_NONE  0 /* don't use it at all */
50
#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */
51
#define SPT_REUSEARGV 2 /* cover argv with title information */
52
53
#ifndef SPT_TYPE
54
# define SPT_TYPE SPT_NONE
55
#endif
56
57
#ifndef SPT_PADCHAR
58
0
# define SPT_PADCHAR  '\0'
59
#endif
60
61
#if SPT_TYPE == SPT_REUSEARGV
62
static char *argv_start = NULL;
63
static size_t argv_env_len = 0;
64
#endif
65
66
#endif /* HAVE_SETPROCTITLE */
67
68
void
69
compat_init_setproctitle(int argc, char *argv[])
70
0
{
71
0
#if !defined(HAVE_SETPROCTITLE) && \
72
0
    defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
73
0
  extern char **environ;
74
0
  char *lastargv = NULL;
75
0
  char **envp = environ;
76
0
  int i;
77
78
  /*
79
   * NB: This assumes that argv has already been copied out of the
80
   * way. This is true for sshd, but may not be true for other
81
   * programs. Beware.
82
   */
83
84
0
  if (argc == 0 || argv[0] == NULL)
85
0
    return;
86
87
  /* Fail if we can't allocate room for the new environment */
88
0
  for (i = 0; envp[i] != NULL; i++)
89
0
    ;
90
0
  if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
91
0
    environ = envp; /* put it back */
92
0
    return;
93
0
  }
94
95
  /*
96
   * Find the last argv string or environment variable within
97
   * our process memory area.
98
   */
99
0
  for (i = 0; i < argc; i++) {
100
0
    if (lastargv == NULL || lastargv + 1 == argv[i])
101
0
      lastargv = argv[i] + strlen(argv[i]);
102
0
  }
103
0
  for (i = 0; envp[i] != NULL; i++) {
104
0
    if (lastargv + 1 == envp[i])
105
0
      lastargv = envp[i] + strlen(envp[i]);
106
0
  }
107
108
0
  argv[1] = NULL;
109
0
  argv_start = argv[0];
110
0
  argv_env_len = lastargv - argv[0] - 1;
111
112
  /*
113
   * Copy environment
114
   * XXX - will truncate env on strdup fail
115
   */
116
0
  for (i = 0; envp[i] != NULL; i++)
117
0
    environ[i] = strdup(envp[i]);
118
0
  environ[i] = NULL;
119
0
#endif /* SPT_REUSEARGV */
120
0
}
121
122
#ifndef HAVE_SETPROCTITLE
123
void
124
setproctitle(const char *fmt, ...)
125
0
{
126
0
#if SPT_TYPE != SPT_NONE
127
0
  va_list ap;
128
0
  char buf[1024], ptitle[1024];
129
0
  size_t len = 0;
130
0
  int r;
131
0
  extern char *__progname;
132
#if SPT_TYPE == SPT_PSTAT
133
  union pstun pst;
134
#endif
135
136
0
#if SPT_TYPE == SPT_REUSEARGV
137
0
  if (argv_env_len <= 0)
138
0
    return;
139
0
#endif
140
141
0
  strlcpy(buf, __progname, sizeof(buf));
142
143
0
  r = -1;
144
0
  va_start(ap, fmt);
145
0
  if (fmt != NULL) {
146
0
    len = strlcat(buf, ": ", sizeof(buf));
147
0
    if (len < sizeof(buf))
148
0
      r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap);
149
0
  }
150
0
  va_end(ap);
151
0
  if (r == -1 || (size_t)r >= sizeof(buf) - len)
152
0
    return;
153
0
  strnvis(ptitle, buf, sizeof(ptitle),
154
0
      VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL);
155
156
#if SPT_TYPE == SPT_PSTAT
157
  pst.pst_command = ptitle;
158
  pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
159
#elif SPT_TYPE == SPT_REUSEARGV
160
/*  debug("setproctitle: copy \"%s\" into len %d",
161
      buf, argv_env_len); */
162
0
  len = strlcpy(argv_start, ptitle, argv_env_len);
163
0
  for(; len < argv_env_len; len++)
164
0
    argv_start[len] = SPT_PADCHAR;
165
0
#endif
166
167
0
#endif /* SPT_NONE */
168
0
}
169
170
#endif /* HAVE_SETPROCTITLE */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/setproctitle.c
Line
Count
Source (jump to first uncovered line)
1
/* Based on conf.c from UCB sendmail 8.8.8 */
2
3
/*
4
 * Copyright 2003 Damien Miller
5
 * Copyright (c) 1983, 1995-1997 Eric P. Allman
6
 * Copyright (c) 1988, 1993
7
 *  The Regents of the University of California.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 3. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include "openbsd-compat.h"
35
36
#ifndef HAVE_SETPROCTITLE
37
38
#include <stdarg.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
#ifdef HAVE_SYS_PSTAT_H
43
#include <sys/pstat.h>
44
#endif
45
#include <string.h>
46
47
#include <vis.h>
48
49
#define SPT_NONE  0 /* don't use it at all */
50
#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */
51
#define SPT_REUSEARGV 2 /* cover argv with title information */
52
53
#ifndef SPT_TYPE
54
# define SPT_TYPE SPT_NONE
55
#endif
56
57
#ifndef SPT_PADCHAR
58
0
# define SPT_PADCHAR  '\0'
59
#endif
60
61
#if SPT_TYPE == SPT_REUSEARGV
62
static char *argv_start = NULL;
63
static size_t argv_env_len = 0;
64
#endif
65
66
#endif /* HAVE_SETPROCTITLE */
67
68
void
69
compat_init_setproctitle(int argc, char *argv[])
70
0
{
71
0
#if !defined(HAVE_SETPROCTITLE) && \
72
0
    defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
73
0
  extern char **environ;
74
0
  char *lastargv = NULL;
75
0
  char **envp = environ;
76
0
  int i;
77
78
  /*
79
   * NB: This assumes that argv has already been copied out of the
80
   * way. This is true for sshd, but may not be true for other
81
   * programs. Beware.
82
   */
83
84
0
  if (argc == 0 || argv[0] == NULL)
85
0
    return;
86
87
  /* Fail if we can't allocate room for the new environment */
88
0
  for (i = 0; envp[i] != NULL; i++)
89
0
    ;
90
0
  if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
91
0
    environ = envp; /* put it back */
92
0
    return;
93
0
  }
94
95
  /*
96
   * Find the last argv string or environment variable within
97
   * our process memory area.
98
   */
99
0
  for (i = 0; i < argc; i++) {
100
0
    if (lastargv == NULL || lastargv + 1 == argv[i])
101
0
      lastargv = argv[i] + strlen(argv[i]);
102
0
  }
103
0
  for (i = 0; envp[i] != NULL; i++) {
104
0
    if (lastargv + 1 == envp[i])
105
0
      lastargv = envp[i] + strlen(envp[i]);
106
0
  }
107
108
0
  argv[1] = NULL;
109
0
  argv_start = argv[0];
110
0
  argv_env_len = lastargv - argv[0] - 1;
111
112
  /*
113
   * Copy environment
114
   * XXX - will truncate env on strdup fail
115
   */
116
0
  for (i = 0; envp[i] != NULL; i++)
117
0
    environ[i] = strdup(envp[i]);
118
0
  environ[i] = NULL;
119
0
#endif /* SPT_REUSEARGV */
120
0
}
121
122
#ifndef HAVE_SETPROCTITLE
123
void
124
setproctitle(const char *fmt, ...)
125
0
{
126
0
#if SPT_TYPE != SPT_NONE
127
0
  va_list ap;
128
0
  char buf[1024], ptitle[1024];
129
0
  size_t len = 0;
130
0
  int r;
131
0
  extern char *__progname;
132
#if SPT_TYPE == SPT_PSTAT
133
  union pstun pst;
134
#endif
135
136
0
#if SPT_TYPE == SPT_REUSEARGV
137
0
  if (argv_env_len <= 0)
138
0
    return;
139
0
#endif
140
141
0
  strlcpy(buf, __progname, sizeof(buf));
142
143
0
  r = -1;
144
0
  va_start(ap, fmt);
145
0
  if (fmt != NULL) {
146
0
    len = strlcat(buf, ": ", sizeof(buf));
147
0
    if (len < sizeof(buf))
148
0
      r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap);
149
0
  }
150
0
  va_end(ap);
151
0
  if (r == -1 || (size_t)r >= sizeof(buf) - len)
152
0
    return;
153
0
  strnvis(ptitle, buf, sizeof(ptitle),
154
0
      VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL);
155
156
#if SPT_TYPE == SPT_PSTAT
157
  pst.pst_command = ptitle;
158
  pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
159
#elif SPT_TYPE == SPT_REUSEARGV
160
/*  debug("setproctitle: copy \"%s\" into len %d",
161
      buf, argv_env_len); */
162
0
  len = strlcpy(argv_start, ptitle, argv_env_len);
163
0
  for(; len < argv_env_len; len++)
164
0
    argv_start[len] = SPT_PADCHAR;
165
0
#endif
166
167
0
#endif /* SPT_NONE */
168
0
}
169
170
#endif /* HAVE_SETPROCTITLE */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/strlcat.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/strlcat.c.html index a6208c7e0..f094f9bd1 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/strlcat.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/strlcat.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strlcat.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
20
21
#include "openbsd-compat.h"
22
23
#if !defined(HAVE_STRLCAT)
24
25
#include <sys/types.h>
26
#include <string.h>
27
28
/*
29
 * Appends src to string dst of size dsize (unlike strncat, dsize is the
30
 * full size of dst, not space left).  At most dsize-1 characters
31
 * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
32
 * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
33
 * If retval >= dsize, truncation occurred.
34
 */
35
size_t
36
strlcat(char *dst, const char *src, size_t dsize)
37
0
{
38
0
  const char *odst = dst;
39
0
  const char *osrc = src;
40
0
  size_t n = dsize;
41
0
  size_t dlen;
42
43
  /* Find the end of dst and adjust bytes left but don't go past end. */
44
0
  while (n-- != 0 && *dst != '\0')
45
0
    dst++;
46
0
  dlen = dst - odst;
47
0
  n = dsize - dlen;
48
49
0
  if (n-- == 0)
50
0
    return(dlen + strlen(src));
51
0
  while (*src != '\0') {
52
0
    if (n != 0) {
53
0
      *dst++ = *src;
54
0
      n--;
55
0
    }
56
0
    src++;
57
0
  }
58
0
  *dst = '\0';
59
60
0
  return(dlen + (src - osrc));  /* count does not include NUL */
61
0
}
62
63
#endif /* !defined(HAVE_STRLCAT) */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strlcat.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
20
21
#include "openbsd-compat.h"
22
23
#if !defined(HAVE_STRLCAT)
24
25
#include <sys/types.h>
26
#include <string.h>
27
28
/*
29
 * Appends src to string dst of size dsize (unlike strncat, dsize is the
30
 * full size of dst, not space left).  At most dsize-1 characters
31
 * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
32
 * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
33
 * If retval >= dsize, truncation occurred.
34
 */
35
size_t
36
strlcat(char *dst, const char *src, size_t dsize)
37
0
{
38
0
  const char *odst = dst;
39
0
  const char *osrc = src;
40
0
  size_t n = dsize;
41
0
  size_t dlen;
42
43
  /* Find the end of dst and adjust bytes left but don't go past end. */
44
0
  while (n-- != 0 && *dst != '\0')
45
0
    dst++;
46
0
  dlen = dst - odst;
47
0
  n = dsize - dlen;
48
49
0
  if (n-- == 0)
50
0
    return(dlen + strlen(src));
51
0
  while (*src != '\0') {
52
0
    if (n != 0) {
53
0
      *dst++ = *src;
54
0
      n--;
55
0
    }
56
0
    src++;
57
0
  }
58
0
  *dst = '\0';
59
60
0
  return(dlen + (src - osrc));  /* count does not include NUL */
61
0
}
62
63
#endif /* !defined(HAVE_STRLCAT) */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/strlcpy.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/strlcpy.c.html index 993c8b4ea..ccd031536 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/strlcpy.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/strlcpy.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strlcpy.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <string.h>
21
22
/*
23
 * Copy string src to buffer dst of size dsize.  At most dsize-1
24
 * chars will be copied.  Always NUL terminates (unless dsize == 0).
25
 * Returns strlen(src); if retval >= dsize, truncation occurred.
26
 */
27
size_t
28
strlcpy(char *dst, const char *src, size_t dsize)
29
468k
{
30
468k
  const char *osrc = src;
31
468k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
468k
  if (nleft != 0) {
35
3.67M
    while (--nleft != 0) {
36
3.67M
      if ((*dst++ = *src++) == '\0')
37
467k
        break;
38
3.67M
    }
39
468k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
468k
  if (nleft == 0) {
43
1.45k
    if (dsize != 0)
44
1.45k
      *dst = '\0';   /* NUL-terminate dst */
45
1.45k
    while (*src++)
46
0
      ;
47
1.45k
  }
48
49
468k
  return(src - osrc - 1); /* count does not include NUL */
50
468k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strlcpy.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <string.h>
21
22
/*
23
 * Copy string src to buffer dst of size dsize.  At most dsize-1
24
 * chars will be copied.  Always NUL terminates (unless dsize == 0).
25
 * Returns strlen(src); if retval >= dsize, truncation occurred.
26
 */
27
size_t
28
strlcpy(char *dst, const char *src, size_t dsize)
29
471k
{
30
471k
  const char *osrc = src;
31
471k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
471k
  if (nleft != 0) {
35
3.70M
    while (--nleft != 0) {
36
3.70M
      if ((*dst++ = *src++) == '\0')
37
469k
        break;
38
3.70M
    }
39
471k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
471k
  if (nleft == 0) {
43
1.45k
    if (dsize != 0)
44
1.45k
      *dst = '\0';   /* NUL-terminate dst */
45
1.45k
    while (*src++)
46
0
      ;
47
1.45k
  }
48
49
471k
  return(src - osrc - 1); /* count does not include NUL */
50
471k
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/strtonum.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/strtonum.c.html index 16961e932..2051985e8 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/strtonum.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/strtonum.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strtonum.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
2
3
/*
4
 * Copyright (c) 2004 Ted Unangst and Todd Miller
5
 * All rights reserved.
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <errno.h>
21
#include <limits.h>
22
#include <stdlib.h>
23
24
0
#define INVALID   1
25
0
#define TOOSMALL  2
26
0
#define TOOLARGE  3
27
28
long long
29
strtonum(const char *numstr, long long minval, long long maxval,
30
    const char **errstrp)
31
0
{
32
0
  long long ll = 0;
33
0
  int error = 0;
34
0
  char *ep;
35
0
  struct errval {
36
0
    const char *errstr;
37
0
    int err;
38
0
  } ev[4] = {
39
0
    { NULL,   0 },
40
0
    { "invalid",  EINVAL },
41
0
    { "too small",  ERANGE },
42
0
    { "too large",  ERANGE },
43
0
  };
44
45
0
  ev[0].err = errno;
46
0
  errno = 0;
47
0
  if (minval > maxval) {
48
0
    error = INVALID;
49
0
  } else {
50
0
    ll = strtoll(numstr, &ep, 10);
51
0
    if (numstr == ep || *ep != '\0')
52
0
      error = INVALID;
53
0
    else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54
0
      error = TOOSMALL;
55
0
    else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56
0
      error = TOOLARGE;
57
0
  }
58
0
  if (errstrp != NULL)
59
0
    *errstrp = ev[error].errstr;
60
0
  errno = ev[error].err;
61
0
  if (error)
62
0
    ll = 0;
63
64
0
  return (ll);
65
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strtonum.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
2
3
/*
4
 * Copyright (c) 2004 Ted Unangst and Todd Miller
5
 * All rights reserved.
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <errno.h>
21
#include <limits.h>
22
#include <stdlib.h>
23
24
0
#define INVALID   1
25
0
#define TOOSMALL  2
26
0
#define TOOLARGE  3
27
28
long long
29
strtonum(const char *numstr, long long minval, long long maxval,
30
    const char **errstrp)
31
0
{
32
0
  long long ll = 0;
33
0
  int error = 0;
34
0
  char *ep;
35
0
  struct errval {
36
0
    const char *errstr;
37
0
    int err;
38
0
  } ev[4] = {
39
0
    { NULL,   0 },
40
0
    { "invalid",  EINVAL },
41
0
    { "too small",  ERANGE },
42
0
    { "too large",  ERANGE },
43
0
  };
44
45
0
  ev[0].err = errno;
46
0
  errno = 0;
47
0
  if (minval > maxval) {
48
0
    error = INVALID;
49
0
  } else {
50
0
    ll = strtoll(numstr, &ep, 10);
51
0
    if (numstr == ep || *ep != '\0')
52
0
      error = INVALID;
53
0
    else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54
0
      error = TOOSMALL;
55
0
    else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56
0
      error = TOOLARGE;
57
0
  }
58
0
  if (errstrp != NULL)
59
0
    *errstrp = ev[error].errstr;
60
0
  errno = ev[error].err;
61
0
  if (error)
62
0
    ll = 0;
63
64
0
  return (ll);
65
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/sys/queue.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/sys/queue.h.html index 5c83c8cc7..e8ef89344 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/sys/queue.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/sys/queue.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/sys/queue.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: queue.h,v 1.46 2020/12/30 13:33:12 millert Exp $  */
2
/*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
 * Copyright (c) 1991, 1993
6
 *  The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)queue.h 8.5 (Berkeley) 8/20/94
33
 */
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
#include <sys/_null.h>
39
40
/*
41
 * This file defines five types of data structures: singly-linked lists,
42
 * lists, simple queues, tail queues and XOR simple queues.
43
 *
44
 *
45
 * A singly-linked list is headed by a single forward pointer. The elements
46
 * are singly linked for minimum space and pointer manipulation overhead at
47
 * the expense of O(n) removal for arbitrary elements. New elements can be
48
 * added to the list after an existing element or at the head of the list.
49
 * Elements being removed from the head of the list should use the explicit
50
 * macro for this purpose for optimum efficiency. A singly-linked list may
51
 * only be traversed in the forward direction.  Singly-linked lists are ideal
52
 * for applications with large datasets and few or no removals or for
53
 * implementing a LIFO queue.
54
 *
55
 * A list is headed by a single forward pointer (or an array of forward
56
 * pointers for a hash table header). The elements are doubly linked
57
 * so that an arbitrary element can be removed without a need to
58
 * traverse the list. New elements can be added to the list before
59
 * or after an existing element or at the head of the list. A list
60
 * may only be traversed in the forward direction.
61
 *
62
 * A simple queue is headed by a pair of pointers, one to the head of the
63
 * list and the other to the tail of the list. The elements are singly
64
 * linked to save space, so elements can only be removed from the
65
 * head of the list. New elements can be added to the list before or after
66
 * an existing element, at the head of the list, or at the end of the
67
 * list. A simple queue may only be traversed in the forward direction.
68
 *
69
 * A tail queue is headed by a pair of pointers, one to the head of the
70
 * list and the other to the tail of the list. The elements are doubly
71
 * linked so that an arbitrary element can be removed without a need to
72
 * traverse the list. New elements can be added to the list before or
73
 * after an existing element, at the head of the list, or at the end of
74
 * the list. A tail queue may be traversed in either direction.
75
 *
76
 * An XOR simple queue is used in the same way as a regular simple queue.
77
 * The difference is that the head structure also includes a "cookie" that
78
 * is XOR'd with the queue pointer (first, last or next) to generate the
79
 * real pointer value.
80
 *
81
 * For details on the use of these macros, see the queue(3) manual page.
82
 */
83
84
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
85
#define _Q_INVALID ((void *)-1)
86
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
 * Singly-linked List definitions.
93
 */
94
#define SLIST_HEAD(name, type)            \
95
struct name {               \
96
  struct type *slh_first; /* first element */     \
97
}
98
99
#define SLIST_HEAD_INITIALIZER(head)          \
100
  { NULL }
101
102
#define SLIST_ENTRY(type)           \
103
struct {                \
104
  struct type *sle_next;  /* next element */      \
105
}
106
107
/*
108
 * Singly-linked List access methods.
109
 */
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head)   NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field)         \
116
  for((var) = SLIST_FIRST(head);          \
117
      (var) != SLIST_END(head);         \
118
      (var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
121
  for ((var) = SLIST_FIRST(head);       \
122
      (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
123
      (var) = (tvar))
124
125
/*
126
 * Singly-linked List functions.
127
 */
128
#define SLIST_INIT(head) {            \
129
  SLIST_FIRST(head) = SLIST_END(head);        \
130
}
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
133
  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
134
  (slistelm)->field.sle_next = (elm);       \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
138
  (elm)->field.sle_next = (head)->slh_first;      \
139
  (head)->slh_first = (elm);          \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do {       \
143
  (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do {       \
147
  (head)->slh_first = (head)->slh_first->field.sle_next;    \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do {     \
151
  if ((head)->slh_first == (elm)) {       \
152
    SLIST_REMOVE_HEAD((head), field);     \
153
  } else {              \
154
    struct type *curelm = (head)->slh_first;    \
155
                  \
156
    while (curelm->field.sle_next != (elm))     \
157
      curelm = curelm->field.sle_next;    \
158
    curelm->field.sle_next =        \
159
        curelm->field.sle_next->field.sle_next;   \
160
  }               \
161
  _Q_INVALIDATE((elm)->field.sle_next);       \
162
} while (0)
163
164
/*
165
 * List definitions.
166
 */
167
#define LIST_HEAD(name, type)           \
168
struct name {               \
169
  struct type *lh_first;  /* first element */     \
170
}
171
172
#define LIST_HEAD_INITIALIZER(head)         \
173
  { NULL }
174
175
#define LIST_ENTRY(type)            \
176
struct {                \
177
  struct type *le_next; /* next element */      \
178
  struct type **le_prev;  /* address of previous next element */  \
179
}
180
181
/*
182
 * List access methods.
183
 */
184
#define LIST_FIRST(head)    ((head)->lh_first)
185
#define LIST_END(head)      NULL
186
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
187
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field)          \
190
  for((var) = LIST_FIRST(head);         \
191
      (var)!= LIST_END(head);         \
192
      (var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
195
  for ((var) = LIST_FIRST(head);        \
196
      (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
197
      (var) = (tvar))
198
199
/*
200
 * List functions.
201
 */
202
#define LIST_INIT(head) do {            \
203
  LIST_FIRST(head) = LIST_END(head);        \
204
} while (0)
205
206
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
207
  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
208
    (listelm)->field.le_next->field.le_prev =   \
209
        &(elm)->field.le_next;        \
210
  (listelm)->field.le_next = (elm);       \
211
  (elm)->field.le_prev = &(listelm)->field.le_next;   \
212
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
215
  (elm)->field.le_prev = (listelm)->field.le_prev;    \
216
  (elm)->field.le_next = (listelm);       \
217
  *(listelm)->field.le_prev = (elm);        \
218
  (listelm)->field.le_prev = &(elm)->field.le_next;   \
219
} while (0)
220
221
#define LIST_INSERT_HEAD(head, elm, field) do {       \
222
  if (((elm)->field.le_next = (head)->lh_first) != NULL)    \
223
    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
  (head)->lh_first = (elm);         \
225
  (elm)->field.le_prev = &(head)->lh_first;     \
226
} while (0)
227
228
#define LIST_REMOVE(elm, field) do {          \
229
  if ((elm)->field.le_next != NULL)       \
230
    (elm)->field.le_next->field.le_prev =     \
231
        (elm)->field.le_prev;       \
232
  *(elm)->field.le_prev = (elm)->field.le_next;     \
233
  _Q_INVALIDATE((elm)->field.le_prev);        \
234
  _Q_INVALIDATE((elm)->field.le_next);        \
235
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do {       \
238
  if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
    (elm2)->field.le_next->field.le_prev =      \
240
        &(elm2)->field.le_next;       \
241
  (elm2)->field.le_prev = (elm)->field.le_prev;     \
242
  *(elm2)->field.le_prev = (elm2);        \
243
  _Q_INVALIDATE((elm)->field.le_prev);        \
244
  _Q_INVALIDATE((elm)->field.le_next);        \
245
} while (0)
246
247
/*
248
 * Simple queue definitions.
249
 */
250
#define SIMPLEQ_HEAD(name, type)          \
251
struct name {               \
252
  struct type *sqh_first; /* first element */     \
253
  struct type **sqh_last; /* addr of last next element */   \
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
257
  { NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type)           \
260
struct {                \
261
  struct type *sqe_next;  /* next element */      \
262
}
263
264
/*
265
 * Simple queue access methods.
266
 */
267
13.9k
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
268
#define SIMPLEQ_END(head)     NULL
269
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field)       \
273
  for((var) = SIMPLEQ_FIRST(head);        \
274
      (var) != SIMPLEQ_END(head);         \
275
      (var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
278
  for ((var) = SIMPLEQ_FIRST(head);       \
279
      (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);    \
280
      (var) = (tvar))
281
282
/*
283
 * Simple queue functions.
284
 */
285
13.0k
#define SIMPLEQ_INIT(head) do {           \
286
13.0k
  (head)->sqh_first = NULL;         \
287
13.0k
  (head)->sqh_last = &(head)->sqh_first;        \
288
13.0k
} while (0)
289
290
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
291
  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
292
    (head)->sqh_last = &(elm)->field.sqe_next;    \
293
  (head)->sqh_first = (elm);          \
294
} while (0)
295
296
897
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
897
  (elm)->field.sqe_next = NULL;         \
298
897
  *(head)->sqh_last = (elm);          \
299
897
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
897
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
303
  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
    (head)->sqh_last = &(elm)->field.sqe_next;    \
305
  (listelm)->field.sqe_next = (elm);        \
306
} while (0)
307
308
897
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
897
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
897
    (head)->sqh_last = &(head)->sqh_first;     \
311
897
} while (0)
312
313
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
314
  if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
      == NULL)              \
316
    (head)->sqh_last = &(elm)->field.sqe_next;    \
317
} while (0)
318
319
#define SIMPLEQ_CONCAT(head1, head2) do {       \
320
  if (!SIMPLEQ_EMPTY((head2))) {          \
321
    *(head1)->sqh_last = (head2)->sqh_first;    \
322
    (head1)->sqh_last = (head2)->sqh_last;      \
323
    SIMPLEQ_INIT((head2));          \
324
  }               \
325
} while (0)
326
327
/*
328
 * XOR Simple queue definitions.
329
 */
330
#define XSIMPLEQ_HEAD(name, type)         \
331
struct name {               \
332
  struct type *sqx_first; /* first element */     \
333
  struct type **sqx_last; /* addr of last next element */   \
334
  unsigned long sqx_cookie;         \
335
}
336
337
#define XSIMPLEQ_ENTRY(type)            \
338
struct {                \
339
  struct type *sqx_next;  /* next element */      \
340
}
341
342
/*
343
 * XOR Simple queue access methods.
344
 */
345
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
346
          (unsigned long)(ptr)))
347
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
348
#define XSIMPLEQ_END(head)      NULL
349
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
350
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
351
352
353
#define XSIMPLEQ_FOREACH(var, head, field)        \
354
  for ((var) = XSIMPLEQ_FIRST(head);        \
355
      (var) != XSIMPLEQ_END(head);        \
356
      (var) = XSIMPLEQ_NEXT(head, var, field))
357
358
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
359
  for ((var) = XSIMPLEQ_FIRST(head);        \
360
      (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
361
      (var) = (tvar))
362
363
/*
364
 * XOR Simple queue functions.
365
 */
366
#define XSIMPLEQ_INIT(head) do {          \
367
  arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
368
  (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
369
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
370
} while (0)
371
372
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
373
  if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
374
      XSIMPLEQ_XOR(head, NULL))         \
375
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
376
  (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
377
} while (0)
378
379
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
380
  (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
381
  *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
382
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
383
} while (0)
384
385
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
386
  if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
387
      XSIMPLEQ_XOR(head, NULL))         \
388
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
389
  (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
390
} while (0)
391
392
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
393
  if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
394
      (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
395
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
396
} while (0)
397
398
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
399
  if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
400
      (elm)->field.sqx_next)->field.sqx_next)     \
401
      == XSIMPLEQ_XOR(head, NULL))        \
402
    (head)->sqx_last =          \
403
        XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
404
} while (0)
405
406
407
/*
408
 * Tail queue definitions.
409
 */
410
#define TAILQ_HEAD(name, type)            \
411
struct name {               \
412
  struct type *tqh_first; /* first element */     \
413
  struct type **tqh_last; /* addr of last next element */   \
414
}
415
416
#define TAILQ_HEAD_INITIALIZER(head)          \
417
  { NULL, &(head).tqh_first }
418
419
#define TAILQ_ENTRY(type)           \
420
struct {                \
421
  struct type *tqe_next;  /* next element */      \
422
  struct type **tqe_prev; /* address of previous next element */  \
423
}
424
425
/*
426
 * Tail queue access methods.
427
 */
428
13.0k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
26.0k
#define TAILQ_END(head)     NULL
430
0
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
431
#define TAILQ_LAST(head, headname)          \
432
  (*(((struct headname *)((head)->tqh_last))->tqh_last))
433
/* XXX */
434
#define TAILQ_PREV(elm, headname, field)        \
435
  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
436
#define TAILQ_EMPTY(head)           \
437
  (TAILQ_FIRST(head) == TAILQ_END(head))
438
439
#define TAILQ_FOREACH(var, head, field)         \
440
0
  for((var) = TAILQ_FIRST(head);         \
441
0
      (var) != TAILQ_END(head);         \
442
0
      (var) = TAILQ_NEXT(var, field))
443
444
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
445
13.0k
  for ((var) = TAILQ_FIRST(head);         \
446
13.0k
      (var) != TAILQ_END(head) &&         \
447
13.0k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
13.0k
      (var) = (tvar))
449
450
451
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
452
  for((var) = TAILQ_LAST(head, headname);       \
453
      (var) != TAILQ_END(head);         \
454
      (var) = TAILQ_PREV(var, headname, field))
455
456
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
457
  for ((var) = TAILQ_LAST(head, headname);      \
458
      (var) != TAILQ_END(head) &&         \
459
      ((tvar) = TAILQ_PREV(var, headname, field), 1);   \
460
      (var) = (tvar))
461
462
/*
463
 * Tail queue functions.
464
 */
465
13.0k
#define TAILQ_INIT(head) do {           \
466
13.0k
  (head)->tqh_first = NULL;         \
467
13.0k
  (head)->tqh_last = &(head)->tqh_first;        \
468
13.0k
} while (0)
469
470
#define TAILQ_INSERT_HEAD(head, elm, field) do {      \
471
  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)  \
472
    (head)->tqh_first->field.tqe_prev =     \
473
        &(elm)->field.tqe_next;       \
474
  else                \
475
    (head)->tqh_last = &(elm)->field.tqe_next;    \
476
  (head)->tqh_first = (elm);          \
477
  (elm)->field.tqe_prev = &(head)->tqh_first;     \
478
} while (0)
479
480
0
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
481
0
  (elm)->field.tqe_next = NULL;         \
482
0
  (elm)->field.tqe_prev = (head)->tqh_last;     \
483
0
  *(head)->tqh_last = (elm);          \
484
0
  (head)->tqh_last = &(elm)->field.tqe_next;      \
485
0
} while (0)
486
487
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {    \
488
  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
489
    (elm)->field.tqe_next->field.tqe_prev =     \
490
        &(elm)->field.tqe_next;       \
491
  else                \
492
    (head)->tqh_last = &(elm)->field.tqe_next;    \
493
  (listelm)->field.tqe_next = (elm);        \
494
  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
495
} while (0)
496
497
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
498
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
499
  (elm)->field.tqe_next = (listelm);        \
500
  *(listelm)->field.tqe_prev = (elm);       \
501
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
502
} while (0)
503
504
0
#define TAILQ_REMOVE(head, elm, field) do {       \
505
0
  if (((elm)->field.tqe_next) != NULL)       \
506
0
    (elm)->field.tqe_next->field.tqe_prev =     \
507
0
        (elm)->field.tqe_prev;       \
508
0
  else                \
509
0
    (head)->tqh_last = (elm)->field.tqe_prev;   \
510
0
  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
511
0
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
512
0
  _Q_INVALIDATE((elm)->field.tqe_next);       \
513
0
} while (0)
514
515
#define TAILQ_REPLACE(head, elm, elm2, field) do {      \
516
  if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
517
    (elm2)->field.tqe_next->field.tqe_prev =    \
518
        &(elm2)->field.tqe_next;        \
519
  else                \
520
    (head)->tqh_last = &(elm2)->field.tqe_next;   \
521
  (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
522
  *(elm2)->field.tqe_prev = (elm2);       \
523
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
524
  _Q_INVALIDATE((elm)->field.tqe_next);       \
525
} while (0)
526
527
#define TAILQ_CONCAT(head1, head2, field) do {        \
528
  if (!TAILQ_EMPTY(head2)) {          \
529
    *(head1)->tqh_last = (head2)->tqh_first;    \
530
    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
531
    (head1)->tqh_last = (head2)->tqh_last;      \
532
    TAILQ_INIT((head2));          \
533
  }               \
534
} while (0)
535
536
/*
537
 * Singly-linked Tail queue declarations.
538
 */
539
#define STAILQ_HEAD(name, type)           \
540
struct name {               \
541
  struct type *stqh_first;  /* first element */   \
542
  struct type **stqh_last;  /* addr of last next element */ \
543
}
544
545
#define STAILQ_HEAD_INITIALIZER(head)         \
546
  { NULL, &(head).stqh_first }
547
548
#define STAILQ_ENTRY(type)            \
549
struct {                \
550
  struct type *stqe_next; /* next element */      \
551
}
552
553
/*
554
 * Singly-linked Tail queue access methods.
555
 */
556
#define STAILQ_FIRST(head)  ((head)->stqh_first)
557
#define STAILQ_END(head)  NULL
558
#define STAILQ_EMPTY(head)  (STAILQ_FIRST(head) == STAILQ_END(head))
559
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
560
561
#define STAILQ_FOREACH(var, head, field)        \
562
  for ((var) = STAILQ_FIRST(head);        \
563
      (var) != STAILQ_END(head);          \
564
      (var) = STAILQ_NEXT(var, field))
565
566
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)     \
567
  for ((var) = STAILQ_FIRST(head);        \
568
      (var) && ((tvar) = STAILQ_NEXT(var, field), 1);   \
569
      (var) = (tvar))
570
571
/*
572
 * Singly-linked Tail queue functions.
573
 */
574
#define STAILQ_INIT(head) do {            \
575
  STAILQ_FIRST((head)) = NULL;          \
576
  (head)->stqh_last = &STAILQ_FIRST((head));      \
577
} while (0)
578
579
#define STAILQ_INSERT_HEAD(head, elm, field) do {     \
580
  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
581
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
582
  STAILQ_FIRST((head)) = (elm);         \
583
} while (0)
584
585
#define STAILQ_INSERT_TAIL(head, elm, field) do {     \
586
  STAILQ_NEXT((elm), field) = NULL;       \
587
  *(head)->stqh_last = (elm);         \
588
  (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
589
} while (0)
590
591
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
592
  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
593
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
594
  STAILQ_NEXT((elm), field) = (elm);        \
595
} while (0)
596
597
#define STAILQ_REMOVE_HEAD(head, field) do {                            \
598
  if ((STAILQ_FIRST((head)) =         \
599
      STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)    \
600
    (head)->stqh_last = &STAILQ_FIRST((head));    \
601
} while (0)
602
603
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
604
  if ((STAILQ_NEXT(elm, field) =          \
605
      STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
606
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
607
} while (0)
608
609
#define STAILQ_REMOVE(head, elm, type, field) do {      \
610
  if (STAILQ_FIRST((head)) == (elm)) {        \
611
    STAILQ_REMOVE_HEAD((head), field);      \
612
  } else {              \
613
    struct type *curelm = (head)->stqh_first;   \
614
    while (STAILQ_NEXT(curelm, field) != (elm))   \
615
      curelm = STAILQ_NEXT(curelm, field);    \
616
    STAILQ_REMOVE_AFTER(head, curelm, field);   \
617
  }               \
618
} while (0)
619
620
#define STAILQ_CONCAT(head1, head2) do {        \
621
  if (!STAILQ_EMPTY((head2))) {         \
622
    *(head1)->stqh_last = (head2)->stqh_first;    \
623
    (head1)->stqh_last = (head2)->stqh_last;    \
624
    STAILQ_INIT((head2));         \
625
  }               \
626
} while (0)
627
628
#define STAILQ_LAST(head, type, field)          \
629
  (STAILQ_EMPTY((head)) ? NULL :          \
630
          ((struct type *)(void *)        \
631
    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
632
633
#endif  /* !_SYS_QUEUE_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/sys/queue.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: queue.h,v 1.46 2020/12/30 13:33:12 millert Exp $  */
2
/*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
 * Copyright (c) 1991, 1993
6
 *  The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)queue.h 8.5 (Berkeley) 8/20/94
33
 */
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
#include <sys/_null.h>
39
40
/*
41
 * This file defines five types of data structures: singly-linked lists,
42
 * lists, simple queues, tail queues and XOR simple queues.
43
 *
44
 *
45
 * A singly-linked list is headed by a single forward pointer. The elements
46
 * are singly linked for minimum space and pointer manipulation overhead at
47
 * the expense of O(n) removal for arbitrary elements. New elements can be
48
 * added to the list after an existing element or at the head of the list.
49
 * Elements being removed from the head of the list should use the explicit
50
 * macro for this purpose for optimum efficiency. A singly-linked list may
51
 * only be traversed in the forward direction.  Singly-linked lists are ideal
52
 * for applications with large datasets and few or no removals or for
53
 * implementing a LIFO queue.
54
 *
55
 * A list is headed by a single forward pointer (or an array of forward
56
 * pointers for a hash table header). The elements are doubly linked
57
 * so that an arbitrary element can be removed without a need to
58
 * traverse the list. New elements can be added to the list before
59
 * or after an existing element or at the head of the list. A list
60
 * may only be traversed in the forward direction.
61
 *
62
 * A simple queue is headed by a pair of pointers, one to the head of the
63
 * list and the other to the tail of the list. The elements are singly
64
 * linked to save space, so elements can only be removed from the
65
 * head of the list. New elements can be added to the list before or after
66
 * an existing element, at the head of the list, or at the end of the
67
 * list. A simple queue may only be traversed in the forward direction.
68
 *
69
 * A tail queue is headed by a pair of pointers, one to the head of the
70
 * list and the other to the tail of the list. The elements are doubly
71
 * linked so that an arbitrary element can be removed without a need to
72
 * traverse the list. New elements can be added to the list before or
73
 * after an existing element, at the head of the list, or at the end of
74
 * the list. A tail queue may be traversed in either direction.
75
 *
76
 * An XOR simple queue is used in the same way as a regular simple queue.
77
 * The difference is that the head structure also includes a "cookie" that
78
 * is XOR'd with the queue pointer (first, last or next) to generate the
79
 * real pointer value.
80
 *
81
 * For details on the use of these macros, see the queue(3) manual page.
82
 */
83
84
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
85
#define _Q_INVALID ((void *)-1)
86
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
 * Singly-linked List definitions.
93
 */
94
#define SLIST_HEAD(name, type)            \
95
struct name {               \
96
  struct type *slh_first; /* first element */     \
97
}
98
99
#define SLIST_HEAD_INITIALIZER(head)          \
100
  { NULL }
101
102
#define SLIST_ENTRY(type)           \
103
struct {                \
104
  struct type *sle_next;  /* next element */      \
105
}
106
107
/*
108
 * Singly-linked List access methods.
109
 */
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head)   NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field)         \
116
  for((var) = SLIST_FIRST(head);          \
117
      (var) != SLIST_END(head);         \
118
      (var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
121
  for ((var) = SLIST_FIRST(head);       \
122
      (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
123
      (var) = (tvar))
124
125
/*
126
 * Singly-linked List functions.
127
 */
128
#define SLIST_INIT(head) {            \
129
  SLIST_FIRST(head) = SLIST_END(head);        \
130
}
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
133
  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
134
  (slistelm)->field.sle_next = (elm);       \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
138
  (elm)->field.sle_next = (head)->slh_first;      \
139
  (head)->slh_first = (elm);          \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do {       \
143
  (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do {       \
147
  (head)->slh_first = (head)->slh_first->field.sle_next;    \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do {     \
151
  if ((head)->slh_first == (elm)) {       \
152
    SLIST_REMOVE_HEAD((head), field);     \
153
  } else {              \
154
    struct type *curelm = (head)->slh_first;    \
155
                  \
156
    while (curelm->field.sle_next != (elm))     \
157
      curelm = curelm->field.sle_next;    \
158
    curelm->field.sle_next =        \
159
        curelm->field.sle_next->field.sle_next;   \
160
  }               \
161
  _Q_INVALIDATE((elm)->field.sle_next);       \
162
} while (0)
163
164
/*
165
 * List definitions.
166
 */
167
#define LIST_HEAD(name, type)           \
168
struct name {               \
169
  struct type *lh_first;  /* first element */     \
170
}
171
172
#define LIST_HEAD_INITIALIZER(head)         \
173
  { NULL }
174
175
#define LIST_ENTRY(type)            \
176
struct {                \
177
  struct type *le_next; /* next element */      \
178
  struct type **le_prev;  /* address of previous next element */  \
179
}
180
181
/*
182
 * List access methods.
183
 */
184
#define LIST_FIRST(head)    ((head)->lh_first)
185
#define LIST_END(head)      NULL
186
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
187
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field)          \
190
  for((var) = LIST_FIRST(head);         \
191
      (var)!= LIST_END(head);         \
192
      (var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
195
  for ((var) = LIST_FIRST(head);        \
196
      (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
197
      (var) = (tvar))
198
199
/*
200
 * List functions.
201
 */
202
#define LIST_INIT(head) do {            \
203
  LIST_FIRST(head) = LIST_END(head);        \
204
} while (0)
205
206
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
207
  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
208
    (listelm)->field.le_next->field.le_prev =   \
209
        &(elm)->field.le_next;        \
210
  (listelm)->field.le_next = (elm);       \
211
  (elm)->field.le_prev = &(listelm)->field.le_next;   \
212
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
215
  (elm)->field.le_prev = (listelm)->field.le_prev;    \
216
  (elm)->field.le_next = (listelm);       \
217
  *(listelm)->field.le_prev = (elm);        \
218
  (listelm)->field.le_prev = &(elm)->field.le_next;   \
219
} while (0)
220
221
#define LIST_INSERT_HEAD(head, elm, field) do {       \
222
  if (((elm)->field.le_next = (head)->lh_first) != NULL)    \
223
    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
  (head)->lh_first = (elm);         \
225
  (elm)->field.le_prev = &(head)->lh_first;     \
226
} while (0)
227
228
#define LIST_REMOVE(elm, field) do {          \
229
  if ((elm)->field.le_next != NULL)       \
230
    (elm)->field.le_next->field.le_prev =     \
231
        (elm)->field.le_prev;       \
232
  *(elm)->field.le_prev = (elm)->field.le_next;     \
233
  _Q_INVALIDATE((elm)->field.le_prev);        \
234
  _Q_INVALIDATE((elm)->field.le_next);        \
235
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do {       \
238
  if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
    (elm2)->field.le_next->field.le_prev =      \
240
        &(elm2)->field.le_next;       \
241
  (elm2)->field.le_prev = (elm)->field.le_prev;     \
242
  *(elm2)->field.le_prev = (elm2);        \
243
  _Q_INVALIDATE((elm)->field.le_prev);        \
244
  _Q_INVALIDATE((elm)->field.le_next);        \
245
} while (0)
246
247
/*
248
 * Simple queue definitions.
249
 */
250
#define SIMPLEQ_HEAD(name, type)          \
251
struct name {               \
252
  struct type *sqh_first; /* first element */     \
253
  struct type **sqh_last; /* addr of last next element */   \
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
257
  { NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type)           \
260
struct {                \
261
  struct type *sqe_next;  /* next element */      \
262
}
263
264
/*
265
 * Simple queue access methods.
266
 */
267
14.0k
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
268
#define SIMPLEQ_END(head)     NULL
269
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field)       \
273
  for((var) = SIMPLEQ_FIRST(head);        \
274
      (var) != SIMPLEQ_END(head);         \
275
      (var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
278
  for ((var) = SIMPLEQ_FIRST(head);       \
279
      (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);    \
280
      (var) = (tvar))
281
282
/*
283
 * Simple queue functions.
284
 */
285
13.1k
#define SIMPLEQ_INIT(head) do {           \
286
13.1k
  (head)->sqh_first = NULL;         \
287
13.1k
  (head)->sqh_last = &(head)->sqh_first;        \
288
13.1k
} while (0)
289
290
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
291
  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
292
    (head)->sqh_last = &(elm)->field.sqe_next;    \
293
  (head)->sqh_first = (elm);          \
294
} while (0)
295
296
897
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
897
  (elm)->field.sqe_next = NULL;         \
298
897
  *(head)->sqh_last = (elm);          \
299
897
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
897
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
303
  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
    (head)->sqh_last = &(elm)->field.sqe_next;    \
305
  (listelm)->field.sqe_next = (elm);        \
306
} while (0)
307
308
897
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
897
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
897
    (head)->sqh_last = &(head)->sqh_first;     \
311
897
} while (0)
312
313
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
314
  if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
      == NULL)              \
316
    (head)->sqh_last = &(elm)->field.sqe_next;    \
317
} while (0)
318
319
#define SIMPLEQ_CONCAT(head1, head2) do {       \
320
  if (!SIMPLEQ_EMPTY((head2))) {          \
321
    *(head1)->sqh_last = (head2)->sqh_first;    \
322
    (head1)->sqh_last = (head2)->sqh_last;      \
323
    SIMPLEQ_INIT((head2));          \
324
  }               \
325
} while (0)
326
327
/*
328
 * XOR Simple queue definitions.
329
 */
330
#define XSIMPLEQ_HEAD(name, type)         \
331
struct name {               \
332
  struct type *sqx_first; /* first element */     \
333
  struct type **sqx_last; /* addr of last next element */   \
334
  unsigned long sqx_cookie;         \
335
}
336
337
#define XSIMPLEQ_ENTRY(type)            \
338
struct {                \
339
  struct type *sqx_next;  /* next element */      \
340
}
341
342
/*
343
 * XOR Simple queue access methods.
344
 */
345
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
346
          (unsigned long)(ptr)))
347
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
348
#define XSIMPLEQ_END(head)      NULL
349
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
350
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
351
352
353
#define XSIMPLEQ_FOREACH(var, head, field)        \
354
  for ((var) = XSIMPLEQ_FIRST(head);        \
355
      (var) != XSIMPLEQ_END(head);        \
356
      (var) = XSIMPLEQ_NEXT(head, var, field))
357
358
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
359
  for ((var) = XSIMPLEQ_FIRST(head);        \
360
      (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
361
      (var) = (tvar))
362
363
/*
364
 * XOR Simple queue functions.
365
 */
366
#define XSIMPLEQ_INIT(head) do {          \
367
  arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
368
  (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
369
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
370
} while (0)
371
372
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
373
  if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
374
      XSIMPLEQ_XOR(head, NULL))         \
375
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
376
  (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
377
} while (0)
378
379
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
380
  (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
381
  *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
382
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
383
} while (0)
384
385
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
386
  if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
387
      XSIMPLEQ_XOR(head, NULL))         \
388
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
389
  (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
390
} while (0)
391
392
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
393
  if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
394
      (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
395
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
396
} while (0)
397
398
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
399
  if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
400
      (elm)->field.sqx_next)->field.sqx_next)     \
401
      == XSIMPLEQ_XOR(head, NULL))        \
402
    (head)->sqx_last =          \
403
        XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
404
} while (0)
405
406
407
/*
408
 * Tail queue definitions.
409
 */
410
#define TAILQ_HEAD(name, type)            \
411
struct name {               \
412
  struct type *tqh_first; /* first element */     \
413
  struct type **tqh_last; /* addr of last next element */   \
414
}
415
416
#define TAILQ_HEAD_INITIALIZER(head)          \
417
  { NULL, &(head).tqh_first }
418
419
#define TAILQ_ENTRY(type)           \
420
struct {                \
421
  struct type *tqe_next;  /* next element */      \
422
  struct type **tqe_prev; /* address of previous next element */  \
423
}
424
425
/*
426
 * Tail queue access methods.
427
 */
428
13.1k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
26.3k
#define TAILQ_END(head)     NULL
430
0
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
431
#define TAILQ_LAST(head, headname)          \
432
  (*(((struct headname *)((head)->tqh_last))->tqh_last))
433
/* XXX */
434
#define TAILQ_PREV(elm, headname, field)        \
435
  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
436
#define TAILQ_EMPTY(head)           \
437
  (TAILQ_FIRST(head) == TAILQ_END(head))
438
439
#define TAILQ_FOREACH(var, head, field)         \
440
0
  for((var) = TAILQ_FIRST(head);         \
441
0
      (var) != TAILQ_END(head);         \
442
0
      (var) = TAILQ_NEXT(var, field))
443
444
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
445
13.1k
  for ((var) = TAILQ_FIRST(head);         \
446
13.1k
      (var) != TAILQ_END(head) &&         \
447
13.1k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
13.1k
      (var) = (tvar))
449
450
451
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
452
  for((var) = TAILQ_LAST(head, headname);       \
453
      (var) != TAILQ_END(head);         \
454
      (var) = TAILQ_PREV(var, headname, field))
455
456
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
457
  for ((var) = TAILQ_LAST(head, headname);      \
458
      (var) != TAILQ_END(head) &&         \
459
      ((tvar) = TAILQ_PREV(var, headname, field), 1);   \
460
      (var) = (tvar))
461
462
/*
463
 * Tail queue functions.
464
 */
465
13.1k
#define TAILQ_INIT(head) do {           \
466
13.1k
  (head)->tqh_first = NULL;         \
467
13.1k
  (head)->tqh_last = &(head)->tqh_first;        \
468
13.1k
} while (0)
469
470
#define TAILQ_INSERT_HEAD(head, elm, field) do {      \
471
  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)  \
472
    (head)->tqh_first->field.tqe_prev =     \
473
        &(elm)->field.tqe_next;       \
474
  else                \
475
    (head)->tqh_last = &(elm)->field.tqe_next;    \
476
  (head)->tqh_first = (elm);          \
477
  (elm)->field.tqe_prev = &(head)->tqh_first;     \
478
} while (0)
479
480
0
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
481
0
  (elm)->field.tqe_next = NULL;         \
482
0
  (elm)->field.tqe_prev = (head)->tqh_last;     \
483
0
  *(head)->tqh_last = (elm);          \
484
0
  (head)->tqh_last = &(elm)->field.tqe_next;      \
485
0
} while (0)
486
487
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {    \
488
  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
489
    (elm)->field.tqe_next->field.tqe_prev =     \
490
        &(elm)->field.tqe_next;       \
491
  else                \
492
    (head)->tqh_last = &(elm)->field.tqe_next;    \
493
  (listelm)->field.tqe_next = (elm);        \
494
  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
495
} while (0)
496
497
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
498
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
499
  (elm)->field.tqe_next = (listelm);        \
500
  *(listelm)->field.tqe_prev = (elm);       \
501
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
502
} while (0)
503
504
0
#define TAILQ_REMOVE(head, elm, field) do {       \
505
0
  if (((elm)->field.tqe_next) != NULL)       \
506
0
    (elm)->field.tqe_next->field.tqe_prev =     \
507
0
        (elm)->field.tqe_prev;       \
508
0
  else                \
509
0
    (head)->tqh_last = (elm)->field.tqe_prev;   \
510
0
  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
511
0
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
512
0
  _Q_INVALIDATE((elm)->field.tqe_next);       \
513
0
} while (0)
514
515
#define TAILQ_REPLACE(head, elm, elm2, field) do {      \
516
  if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
517
    (elm2)->field.tqe_next->field.tqe_prev =    \
518
        &(elm2)->field.tqe_next;        \
519
  else                \
520
    (head)->tqh_last = &(elm2)->field.tqe_next;   \
521
  (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
522
  *(elm2)->field.tqe_prev = (elm2);       \
523
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
524
  _Q_INVALIDATE((elm)->field.tqe_next);       \
525
} while (0)
526
527
#define TAILQ_CONCAT(head1, head2, field) do {        \
528
  if (!TAILQ_EMPTY(head2)) {          \
529
    *(head1)->tqh_last = (head2)->tqh_first;    \
530
    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
531
    (head1)->tqh_last = (head2)->tqh_last;      \
532
    TAILQ_INIT((head2));          \
533
  }               \
534
} while (0)
535
536
/*
537
 * Singly-linked Tail queue declarations.
538
 */
539
#define STAILQ_HEAD(name, type)           \
540
struct name {               \
541
  struct type *stqh_first;  /* first element */   \
542
  struct type **stqh_last;  /* addr of last next element */ \
543
}
544
545
#define STAILQ_HEAD_INITIALIZER(head)         \
546
  { NULL, &(head).stqh_first }
547
548
#define STAILQ_ENTRY(type)            \
549
struct {                \
550
  struct type *stqe_next; /* next element */      \
551
}
552
553
/*
554
 * Singly-linked Tail queue access methods.
555
 */
556
#define STAILQ_FIRST(head)  ((head)->stqh_first)
557
#define STAILQ_END(head)  NULL
558
#define STAILQ_EMPTY(head)  (STAILQ_FIRST(head) == STAILQ_END(head))
559
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
560
561
#define STAILQ_FOREACH(var, head, field)        \
562
  for ((var) = STAILQ_FIRST(head);        \
563
      (var) != STAILQ_END(head);          \
564
      (var) = STAILQ_NEXT(var, field))
565
566
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)     \
567
  for ((var) = STAILQ_FIRST(head);        \
568
      (var) && ((tvar) = STAILQ_NEXT(var, field), 1);   \
569
      (var) = (tvar))
570
571
/*
572
 * Singly-linked Tail queue functions.
573
 */
574
#define STAILQ_INIT(head) do {            \
575
  STAILQ_FIRST((head)) = NULL;          \
576
  (head)->stqh_last = &STAILQ_FIRST((head));      \
577
} while (0)
578
579
#define STAILQ_INSERT_HEAD(head, elm, field) do {     \
580
  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
581
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
582
  STAILQ_FIRST((head)) = (elm);         \
583
} while (0)
584
585
#define STAILQ_INSERT_TAIL(head, elm, field) do {     \
586
  STAILQ_NEXT((elm), field) = NULL;       \
587
  *(head)->stqh_last = (elm);         \
588
  (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
589
} while (0)
590
591
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
592
  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
593
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
594
  STAILQ_NEXT((elm), field) = (elm);        \
595
} while (0)
596
597
#define STAILQ_REMOVE_HEAD(head, field) do {                            \
598
  if ((STAILQ_FIRST((head)) =         \
599
      STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)    \
600
    (head)->stqh_last = &STAILQ_FIRST((head));    \
601
} while (0)
602
603
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
604
  if ((STAILQ_NEXT(elm, field) =          \
605
      STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
606
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
607
} while (0)
608
609
#define STAILQ_REMOVE(head, elm, type, field) do {      \
610
  if (STAILQ_FIRST((head)) == (elm)) {        \
611
    STAILQ_REMOVE_HEAD((head), field);      \
612
  } else {              \
613
    struct type *curelm = (head)->stqh_first;   \
614
    while (STAILQ_NEXT(curelm, field) != (elm))   \
615
      curelm = STAILQ_NEXT(curelm, field);    \
616
    STAILQ_REMOVE_AFTER(head, curelm, field);   \
617
  }               \
618
} while (0)
619
620
#define STAILQ_CONCAT(head1, head2) do {        \
621
  if (!STAILQ_EMPTY((head2))) {         \
622
    *(head1)->stqh_last = (head2)->stqh_first;    \
623
    (head1)->stqh_last = (head2)->stqh_last;    \
624
    STAILQ_INIT((head2));         \
625
  }               \
626
} while (0)
627
628
#define STAILQ_LAST(head, type, field)          \
629
  (STAILQ_EMPTY((head)) ? NULL :          \
630
          ((struct type *)(void *)        \
631
    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
632
633
#endif  /* !_SYS_QUEUE_H_ */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/sys/tree.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/sys/tree.h.html index 860b3fa8f..8e4b37032 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/sys/tree.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/sys/tree.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/sys/tree.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: tree.h,v 1.31 2023/03/08 04:43:09 guenther Exp $  */
2
/*
3
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#ifndef _SYS_TREE_H_
28
#define _SYS_TREE_H_
29
30
#include <sys/_null.h>
31
32
/*
33
 * This file defines data structures for different types of trees:
34
 * splay trees and red-black trees.
35
 *
36
 * A splay tree is a self-organizing data structure.  Every operation
37
 * on the tree causes a splay to happen.  The splay moves the requested
38
 * node to the root of the tree and partly rebalances it.
39
 *
40
 * This has the benefit that request locality causes faster lookups as
41
 * the requested nodes move to the top of the tree.  On the other hand,
42
 * every lookup causes memory writes.
43
 *
44
 * The Balance Theorem bounds the total access time for m operations
45
 * and n inserts on an initially empty tree as O((m + n)lg n).  The
46
 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
47
 *
48
 * A red-black tree is a binary search tree with the node color as an
49
 * extra attribute.  It fulfills a set of conditions:
50
 *  - every search path from the root to a leaf consists of the
51
 *    same number of black nodes,
52
 *  - each red node (except for the root) has a black parent,
53
 *  - each leaf node is black.
54
 *
55
 * Every operation on a red-black tree is bounded as O(lg n).
56
 * The maximum height of a red-black tree is 2lg (n+1).
57
 */
58
59
#define SPLAY_HEAD(name, type)            \
60
struct name {               \
61
  struct type *sph_root; /* root of the tree */     \
62
}
63
64
#define SPLAY_INITIALIZER(root)           \
65
  { NULL }
66
67
#define SPLAY_INIT(root) do {           \
68
  (root)->sph_root = NULL;          \
69
} while (0)
70
71
#define SPLAY_ENTRY(type)           \
72
struct {                \
73
  struct type *spe_left; /* left element */     \
74
  struct type *spe_right; /* right element */     \
75
}
76
77
#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
78
#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
79
#define SPLAY_ROOT(head)    (head)->sph_root
80
#define SPLAY_EMPTY(head)   (SPLAY_ROOT(head) == NULL)
81
82
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
83
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {     \
84
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \
85
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
86
  (head)->sph_root = tmp;           \
87
} while (0)
88
89
#define SPLAY_ROTATE_LEFT(head, tmp, field) do {      \
90
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \
91
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
92
  (head)->sph_root = tmp;           \
93
} while (0)
94
95
#define SPLAY_LINKLEFT(head, tmp, field) do {       \
96
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
97
  tmp = (head)->sph_root;           \
98
  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);   \
99
} while (0)
100
101
#define SPLAY_LINKRIGHT(head, tmp, field) do {        \
102
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
103
  tmp = (head)->sph_root;           \
104
  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
105
} while (0)
106
107
#define SPLAY_ASSEMBLE(head, node, left, right, field) do {   \
108
  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
109
  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
110
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
111
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
112
} while (0)
113
114
/* Generates prototypes and inline functions */
115
116
#define SPLAY_PROTOTYPE(name, type, field, cmp)       \
117
void name##_SPLAY(struct name *, struct type *);      \
118
void name##_SPLAY_MINMAX(struct name *, int);       \
119
struct type *name##_SPLAY_INSERT(struct name *, struct type *);   \
120
struct type *name##_SPLAY_REMOVE(struct name *, struct type *);   \
121
                  \
122
/* Finds the node with the same key as elm */       \
123
static __unused __inline struct type *          \
124
name##_SPLAY_FIND(struct name *head, struct type *elm)      \
125
{                 \
126
  if (SPLAY_EMPTY(head))            \
127
    return(NULL);           \
128
  name##_SPLAY(head, elm);          \
129
  if ((cmp)(elm, (head)->sph_root) == 0)        \
130
    return (head->sph_root);        \
131
  return (NULL);              \
132
}                 \
133
                  \
134
static __unused __inline struct type *          \
135
name##_SPLAY_NEXT(struct name *head, struct type *elm)      \
136
{                 \
137
  name##_SPLAY(head, elm);          \
138
  if (SPLAY_RIGHT(elm, field) != NULL) {        \
139
    elm = SPLAY_RIGHT(elm, field);        \
140
    while (SPLAY_LEFT(elm, field) != NULL) {    \
141
      elm = SPLAY_LEFT(elm, field);     \
142
    }             \
143
  } else                \
144
    elm = NULL;           \
145
  return (elm);             \
146
}                 \
147
                  \
148
static __unused __inline struct type *          \
149
name##_SPLAY_MIN_MAX(struct name *head, int val)      \
150
{                 \
151
  name##_SPLAY_MINMAX(head, val);         \
152
        return (SPLAY_ROOT(head));          \
153
}
154
155
/* Main splay operation.
156
 * Moves node close to the key of elm to top
157
 */
158
#define SPLAY_GENERATE(name, type, field, cmp)        \
159
struct type *               \
160
name##_SPLAY_INSERT(struct name *head, struct type *elm)    \
161
{                 \
162
    if (SPLAY_EMPTY(head)) {            \
163
      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;  \
164
    } else {                \
165
      int __comp;             \
166
      name##_SPLAY(head, elm);          \
167
      __comp = (cmp)(elm, (head)->sph_root);      \
168
      if(__comp < 0) {            \
169
        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
170
        SPLAY_RIGHT(elm, field) = (head)->sph_root;   \
171
        SPLAY_LEFT((head)->sph_root, field) = NULL;   \
172
      } else if (__comp > 0) {          \
173
        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
174
        SPLAY_LEFT(elm, field) = (head)->sph_root;    \
175
        SPLAY_RIGHT((head)->sph_root, field) = NULL;  \
176
      } else              \
177
        return ((head)->sph_root);        \
178
    }                 \
179
    (head)->sph_root = (elm);           \
180
    return (NULL);              \
181
}                 \
182
                  \
183
struct type *               \
184
name##_SPLAY_REMOVE(struct name *head, struct type *elm)    \
185
{                 \
186
  struct type *__tmp;           \
187
  if (SPLAY_EMPTY(head))            \
188
    return (NULL);            \
189
  name##_SPLAY(head, elm);          \
190
  if ((cmp)(elm, (head)->sph_root) == 0) {      \
191
    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \
192
      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
193
    } else {            \
194
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
195
      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
196
      name##_SPLAY(head, elm);      \
197
      SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
198
    }             \
199
    return (elm);           \
200
  }               \
201
  return (NULL);              \
202
}                 \
203
                  \
204
void                  \
205
name##_SPLAY(struct name *head, struct type *elm)     \
206
{                 \
207
  struct type __node, *__left, *__right, *__tmp;      \
208
  int __comp;             \
209
\
210
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
211
  __left = __right = &__node;         \
212
\
213
  while ((__comp = (cmp)(elm, (head)->sph_root))) {   \
214
    if (__comp < 0) {         \
215
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
216
      if (__tmp == NULL)        \
217
        break;          \
218
      if ((cmp)(elm, __tmp) < 0){     \
219
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
220
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
221
          break;        \
222
      }           \
223
      SPLAY_LINKLEFT(head, __right, field);   \
224
    } else if (__comp > 0) {        \
225
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
226
      if (__tmp == NULL)        \
227
        break;          \
228
      if ((cmp)(elm, __tmp) > 0){     \
229
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
230
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
231
          break;        \
232
      }           \
233
      SPLAY_LINKRIGHT(head, __left, field);   \
234
    }             \
235
  }               \
236
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
237
}                 \
238
                  \
239
/* Splay with either the minimum or the maximum element     \
240
 * Used to find minimum or maximum element in tree.     \
241
 */                 \
242
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
243
{                 \
244
  struct type __node, *__left, *__right, *__tmp;      \
245
\
246
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
247
  __left = __right = &__node;         \
248
\
249
  while (1) {             \
250
    if (__comp < 0) {         \
251
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
252
      if (__tmp == NULL)        \
253
        break;          \
254
      if (__comp < 0){        \
255
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
256
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
257
          break;        \
258
      }           \
259
      SPLAY_LINKLEFT(head, __right, field);   \
260
    } else if (__comp > 0) {        \
261
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
262
      if (__tmp == NULL)        \
263
        break;          \
264
      if (__comp > 0) {       \
265
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
266
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
267
          break;        \
268
      }           \
269
      SPLAY_LINKRIGHT(head, __left, field);   \
270
    }             \
271
  }               \
272
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
273
}
274
275
#define SPLAY_NEGINF  -1
276
#define SPLAY_INF 1
277
278
#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
279
#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
280
#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
281
#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
282
#define SPLAY_MIN(name, x)    (SPLAY_EMPTY(x) ? NULL  \
283
          : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
284
#define SPLAY_MAX(name, x)    (SPLAY_EMPTY(x) ? NULL  \
285
          : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
286
287
#define SPLAY_FOREACH(x, name, head)          \
288
  for ((x) = SPLAY_MIN(name, head);       \
289
       (x) != NULL;           \
290
       (x) = SPLAY_NEXT(name, head, x))
291
292
/* Macros that define a red-black tree */
293
#define RB_HEAD(name, type)           \
294
struct name {               \
295
  struct type *rbh_root; /* root of the tree */     \
296
}
297
298
#define RB_INITIALIZER(root)            \
299
  { NULL }
300
301
#define RB_INIT(root) do {            \
302
  (root)->rbh_root = NULL;          \
303
} while (0)
304
305
#define RB_BLACK  0
306
#define RB_RED    1
307
#define RB_ENTRY(type)              \
308
struct {                \
309
  struct type *rbe_left;    /* left element */    \
310
  struct type *rbe_right;   /* right element */   \
311
  struct type *rbe_parent;  /* parent element */    \
312
  int rbe_color;      /* node color */    \
313
}
314
315
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
316
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
317
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
318
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
319
#define RB_ROOT(head)     (head)->rbh_root
320
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
321
322
#define RB_SET(elm, parent, field) do {         \
323
  RB_PARENT(elm, field) = parent;         \
324
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
325
  RB_COLOR(elm, field) = RB_RED;          \
326
} while (0)
327
328
#define RB_SET_BLACKRED(black, red, field) do {       \
329
  RB_COLOR(black, field) = RB_BLACK;        \
330
  RB_COLOR(red, field) = RB_RED;          \
331
} while (0)
332
333
#ifndef RB_AUGMENT
334
#define RB_AUGMENT(x) do {} while (0)
335
#endif
336
337
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {      \
338
  (tmp) = RB_RIGHT(elm, field);         \
339
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {   \
340
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);    \
341
  }               \
342
  RB_AUGMENT(elm);            \
343
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
344
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
345
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
346
    else              \
347
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
348
  } else                \
349
    (head)->rbh_root = (tmp);       \
350
  RB_LEFT(tmp, field) = (elm);          \
351
  RB_PARENT(elm, field) = (tmp);          \
352
  RB_AUGMENT(tmp);            \
353
  if ((RB_PARENT(tmp, field)))          \
354
    RB_AUGMENT(RB_PARENT(tmp, field));      \
355
} while (0)
356
357
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
358
  (tmp) = RB_LEFT(elm, field);          \
359
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {   \
360
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);   \
361
  }               \
362
  RB_AUGMENT(elm);            \
363
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
364
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
365
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
366
    else              \
367
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
368
  } else                \
369
    (head)->rbh_root = (tmp);       \
370
  RB_RIGHT(tmp, field) = (elm);         \
371
  RB_PARENT(elm, field) = (tmp);          \
372
  RB_AUGMENT(tmp);            \
373
  if ((RB_PARENT(tmp, field)))          \
374
    RB_AUGMENT(RB_PARENT(tmp, field));      \
375
} while (0)
376
377
/* Generates prototypes and inline functions */
378
#define RB_PROTOTYPE(name, type, field, cmp)        \
379
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
380
#define RB_PROTOTYPE_STATIC(name, type, field, cmp)     \
381
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
382
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)   \
383
attr void name##_RB_INSERT_COLOR(struct name *, struct type *);   \
384
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
385
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
386
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
387
attr struct type *name##_RB_FIND(struct name *, struct type *);   \
388
attr struct type *name##_RB_NFIND(struct name *, struct type *);  \
389
attr struct type *name##_RB_NEXT(struct type *);      \
390
attr struct type *name##_RB_PREV(struct type *);      \
391
attr struct type *name##_RB_MINMAX(struct name *, int);     \
392
                  \
393
394
/* Main rb operation.
395
 * Moves node close to the key of elm to top
396
 */
397
#define RB_GENERATE(name, type, field, cmp)       \
398
  RB_GENERATE_INTERNAL(name, type, field, cmp,)
399
#define RB_GENERATE_STATIC(name, type, field, cmp)      \
400
  RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
401
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)    \
402
attr void               \
403
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
404
{                 \
405
  struct type *parent, *gparent, *tmp;        \
406
  while ((parent = RB_PARENT(elm, field)) &&      \
407
      RB_COLOR(parent, field) == RB_RED) {      \
408
    gparent = RB_PARENT(parent, field);     \
409
    if (parent == RB_LEFT(gparent, field)) {    \
410
      tmp = RB_RIGHT(gparent, field);     \
411
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
412
        RB_COLOR(tmp, field) = RB_BLACK;  \
413
        RB_SET_BLACKRED(parent, gparent, field);\
414
        elm = gparent;        \
415
        continue;       \
416
      }           \
417
      if (RB_RIGHT(parent, field) == elm) {   \
418
        RB_ROTATE_LEFT(head, parent, tmp, field);\
419
        tmp = parent;       \
420
        parent = elm;       \
421
        elm = tmp;        \
422
      }           \
423
      RB_SET_BLACKRED(parent, gparent, field);  \
424
      RB_ROTATE_RIGHT(head, gparent, tmp, field); \
425
    } else {            \
426
      tmp = RB_LEFT(gparent, field);      \
427
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
428
        RB_COLOR(tmp, field) = RB_BLACK;  \
429
        RB_SET_BLACKRED(parent, gparent, field);\
430
        elm = gparent;        \
431
        continue;       \
432
      }           \
433
      if (RB_LEFT(parent, field) == elm) {    \
434
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
435
        tmp = parent;       \
436
        parent = elm;       \
437
        elm = tmp;        \
438
      }           \
439
      RB_SET_BLACKRED(parent, gparent, field);  \
440
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
441
    }             \
442
  }               \
443
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
444
}                 \
445
                  \
446
attr void               \
447
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
448
{                 \
449
  struct type *tmp;           \
450
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
451
      elm != RB_ROOT(head)) {         \
452
    if (RB_LEFT(parent, field) == elm) {      \
453
      tmp = RB_RIGHT(parent, field);      \
454
      if (RB_COLOR(tmp, field) == RB_RED) {   \
455
        RB_SET_BLACKRED(tmp, parent, field);  \
456
        RB_ROTATE_LEFT(head, parent, tmp, field);\
457
        tmp = RB_RIGHT(parent, field);    \
458
      }           \
459
      if ((RB_LEFT(tmp, field) == NULL ||   \
460
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
461
          (RB_RIGHT(tmp, field) == NULL ||    \
462
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
463
        RB_COLOR(tmp, field) = RB_RED;    \
464
        elm = parent;       \
465
        parent = RB_PARENT(elm, field);   \
466
      } else {          \
467
        if (RB_RIGHT(tmp, field) == NULL || \
468
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
469
          struct type *oleft;   \
470
          if ((oleft = RB_LEFT(tmp, field)))\
471
            RB_COLOR(oleft, field) = RB_BLACK;\
472
          RB_COLOR(tmp, field) = RB_RED;  \
473
          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
474
          tmp = RB_RIGHT(parent, field);  \
475
        }         \
476
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
477
        RB_COLOR(parent, field) = RB_BLACK; \
478
        if (RB_RIGHT(tmp, field))   \
479
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
480
        RB_ROTATE_LEFT(head, parent, tmp, field);\
481
        elm = RB_ROOT(head);      \
482
        break;          \
483
      }           \
484
    } else {            \
485
      tmp = RB_LEFT(parent, field);     \
486
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
        RB_SET_BLACKRED(tmp, parent, field);  \
488
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
489
        tmp = RB_LEFT(parent, field);   \
490
      }           \
491
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
          (RB_RIGHT(tmp, field) == NULL ||    \
494
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
        RB_COLOR(tmp, field) = RB_RED;    \
496
        elm = parent;       \
497
        parent = RB_PARENT(elm, field);   \
498
      } else {          \
499
        if (RB_LEFT(tmp, field) == NULL ||  \
500
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
501
          struct type *oright;    \
502
          if ((oright = RB_RIGHT(tmp, field)))\
503
            RB_COLOR(oright, field) = RB_BLACK;\
504
          RB_COLOR(tmp, field) = RB_RED;  \
505
          RB_ROTATE_LEFT(head, tmp, oright, field);\
506
          tmp = RB_LEFT(parent, field); \
507
        }         \
508
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
509
        RB_COLOR(parent, field) = RB_BLACK; \
510
        if (RB_LEFT(tmp, field))    \
511
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
512
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
513
        elm = RB_ROOT(head);      \
514
        break;          \
515
      }           \
516
    }             \
517
  }               \
518
  if (elm)              \
519
    RB_COLOR(elm, field) = RB_BLACK;      \
520
}                 \
521
                  \
522
attr struct type *              \
523
name##_RB_REMOVE(struct name *head, struct type *elm)     \
524
{                 \
525
  struct type *child, *parent, *old = elm;      \
526
  int color;              \
527
  if (RB_LEFT(elm, field) == NULL)        \
528
    child = RB_RIGHT(elm, field);       \
529
  else if (RB_RIGHT(elm, field) == NULL)        \
530
    child = RB_LEFT(elm, field);        \
531
  else {                \
532
    struct type *left;          \
533
    elm = RB_RIGHT(elm, field);       \
534
    while ((left = RB_LEFT(elm, field)))      \
535
      elm = left;         \
536
    child = RB_RIGHT(elm, field);       \
537
    parent = RB_PARENT(elm, field);       \
538
    color = RB_COLOR(elm, field);       \
539
    if (child)            \
540
      RB_PARENT(child, field) = parent;   \
541
    if (parent) {           \
542
      if (RB_LEFT(parent, field) == elm)    \
543
        RB_LEFT(parent, field) = child;   \
544
      else            \
545
        RB_RIGHT(parent, field) = child;  \
546
      RB_AUGMENT(parent);       \
547
    } else              \
548
      RB_ROOT(head) = child;        \
549
    if (RB_PARENT(elm, field) == old)     \
550
      parent = elm;         \
551
    (elm)->field = (old)->field;        \
552
    if (RB_PARENT(old, field)) {        \
553
      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
554
        RB_LEFT(RB_PARENT(old, field), field) = elm;\
555
      else            \
556
        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
557
      RB_AUGMENT(RB_PARENT(old, field));    \
558
    } else              \
559
      RB_ROOT(head) = elm;        \
560
    RB_PARENT(RB_LEFT(old, field), field) = elm;    \
561
    if (RB_RIGHT(old, field))       \
562
      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
563
    if (parent) {           \
564
      left = parent;          \
565
      do {            \
566
        RB_AUGMENT(left);     \
567
      } while ((left = RB_PARENT(left, field)));  \
568
    }             \
569
    goto color;           \
570
  }               \
571
  parent = RB_PARENT(elm, field);         \
572
  color = RB_COLOR(elm, field);         \
573
  if (child)              \
574
    RB_PARENT(child, field) = parent;     \
575
  if (parent) {             \
576
    if (RB_LEFT(parent, field) == elm)      \
577
      RB_LEFT(parent, field) = child;     \
578
    else              \
579
      RB_RIGHT(parent, field) = child;    \
580
    RB_AUGMENT(parent);         \
581
  } else                \
582
    RB_ROOT(head) = child;          \
583
color:                  \
584
  if (color == RB_BLACK)            \
585
    name##_RB_REMOVE_COLOR(head, parent, child);    \
586
  return (old);             \
587
}                 \
588
                  \
589
/* Inserts a node into the RB tree */         \
590
attr struct type *              \
591
name##_RB_INSERT(struct name *head, struct type *elm)     \
592
{                 \
593
  struct type *tmp;           \
594
  struct type *parent = NULL;         \
595
  int comp = 0;             \
596
  tmp = RB_ROOT(head);            \
597
  while (tmp) {             \
598
    parent = tmp;           \
599
    comp = (cmp)(elm, parent);        \
600
    if (comp < 0)           \
601
      tmp = RB_LEFT(tmp, field);      \
602
    else if (comp > 0)          \
603
      tmp = RB_RIGHT(tmp, field);     \
604
    else              \
605
      return (tmp);         \
606
  }               \
607
  RB_SET(elm, parent, field);         \
608
  if (parent != NULL) {           \
609
    if (comp < 0)           \
610
      RB_LEFT(parent, field) = elm;     \
611
    else              \
612
      RB_RIGHT(parent, field) = elm;      \
613
    RB_AUGMENT(parent);         \
614
  } else                \
615
    RB_ROOT(head) = elm;          \
616
  name##_RB_INSERT_COLOR(head, elm);        \
617
  return (NULL);              \
618
}                 \
619
                  \
620
/* Finds the node with the same key as elm */       \
621
attr struct type *              \
622
name##_RB_FIND(struct name *head, struct type *elm)     \
623
{                 \
624
  struct type *tmp = RB_ROOT(head);       \
625
  int comp;             \
626
  while (tmp) {             \
627
    comp = cmp(elm, tmp);         \
628
    if (comp < 0)           \
629
      tmp = RB_LEFT(tmp, field);      \
630
    else if (comp > 0)          \
631
      tmp = RB_RIGHT(tmp, field);     \
632
    else              \
633
      return (tmp);         \
634
  }               \
635
  return (NULL);              \
636
}                 \
637
                  \
638
/* Finds the first node greater than or equal to the search key */  \
639
attr struct type *              \
640
name##_RB_NFIND(struct name *head, struct type *elm)      \
641
{                 \
642
  struct type *tmp = RB_ROOT(head);       \
643
  struct type *res = NULL;          \
644
  int comp;             \
645
  while (tmp) {             \
646
    comp = cmp(elm, tmp);         \
647
    if (comp < 0) {           \
648
      res = tmp;          \
649
      tmp = RB_LEFT(tmp, field);      \
650
    }             \
651
    else if (comp > 0)          \
652
      tmp = RB_RIGHT(tmp, field);     \
653
    else              \
654
      return (tmp);         \
655
  }               \
656
  return (res);             \
657
}                 \
658
                  \
659
attr struct type *              \
660
name##_RB_NEXT(struct type *elm)          \
661
{                 \
662
  if (RB_RIGHT(elm, field)) {         \
663
    elm = RB_RIGHT(elm, field);       \
664
    while (RB_LEFT(elm, field))       \
665
      elm = RB_LEFT(elm, field);      \
666
  } else {              \
667
    if (RB_PARENT(elm, field) &&        \
668
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
669
      elm = RB_PARENT(elm, field);      \
670
    else {              \
671
      while (RB_PARENT(elm, field) &&     \
672
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
673
        elm = RB_PARENT(elm, field);    \
674
      elm = RB_PARENT(elm, field);      \
675
    }             \
676
  }               \
677
  return (elm);             \
678
}                 \
679
                  \
680
attr struct type *              \
681
name##_RB_PREV(struct type *elm)          \
682
{                 \
683
  if (RB_LEFT(elm, field)) {          \
684
    elm = RB_LEFT(elm, field);        \
685
    while (RB_RIGHT(elm, field))        \
686
      elm = RB_RIGHT(elm, field);     \
687
  } else {              \
688
    if (RB_PARENT(elm, field) &&        \
689
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))  \
690
      elm = RB_PARENT(elm, field);      \
691
    else {              \
692
      while (RB_PARENT(elm, field) &&     \
693
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
694
        elm = RB_PARENT(elm, field);    \
695
      elm = RB_PARENT(elm, field);      \
696
    }             \
697
  }               \
698
  return (elm);             \
699
}                 \
700
                  \
701
attr struct type *              \
702
name##_RB_MINMAX(struct name *head, int val)        \
703
{                 \
704
  struct type *tmp = RB_ROOT(head);       \
705
  struct type *parent = NULL;         \
706
  while (tmp) {             \
707
    parent = tmp;           \
708
    if (val < 0)            \
709
      tmp = RB_LEFT(tmp, field);      \
710
    else              \
711
      tmp = RB_RIGHT(tmp, field);     \
712
  }               \
713
  return (parent);            \
714
}
715
716
#define RB_NEGINF -1
717
#define RB_INF  1
718
719
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
720
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
721
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
722
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
723
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
724
#define RB_PREV(name, x, y) name##_RB_PREV(y)
725
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
726
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
727
728
#define RB_FOREACH(x, name, head)         \
729
  for ((x) = RB_MIN(name, head);          \
730
       (x) != NULL;           \
731
       (x) = name##_RB_NEXT(x))
732
733
#define RB_FOREACH_SAFE(x, name, head, y)       \
734
  for ((x) = RB_MIN(name, head);          \
735
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);    \
736
       (x) = (y))
737
738
#define RB_FOREACH_REVERSE(x, name, head)       \
739
  for ((x) = RB_MAX(name, head);          \
740
       (x) != NULL;           \
741
       (x) = name##_RB_PREV(x))
742
743
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)     \
744
  for ((x) = RB_MAX(name, head);          \
745
      ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);    \
746
       (x) = (y))
747
748
749
/*
750
 * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
751
 *
752
 * Permission to use, copy, modify, and distribute this software for any
753
 * purpose with or without fee is hereby granted, provided that the above
754
 * copyright notice and this permission notice appear in all copies.
755
 *
756
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
757
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
758
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
759
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
760
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
761
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
762
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
763
 */
764
765
struct rb_type {
766
  int   (*t_compare)(const void *, const void *);
767
  void    (*t_augment)(void *);
768
  unsigned int    t_offset; /* offset of rb_entry in type */
769
};
770
771
struct rb_tree {
772
  struct rb_entry *rbt_root;
773
};
774
775
struct rb_entry {
776
  struct rb_entry  *rbt_parent;
777
  struct rb_entry  *rbt_left;
778
  struct rb_entry  *rbt_right;
779
  unsigned int    rbt_color;
780
};
781
782
#define RBT_HEAD(_name, _type)            \
783
struct _name {                \
784
  struct rb_tree rbh_root;          \
785
}
786
787
#define RBT_ENTRY(_type)  struct rb_entry
788
789
static inline void
790
_rb_init(struct rb_tree *rbt)
791
0
{
792
0
  rbt->rbt_root = NULL;
793
0
}
Unexecuted instantiation: common.c:_rb_init
Unexecuted instantiation: test_parser_fuzz.c:_rb_init
Unexecuted instantiation: ikev2_pld.c:_rb_init
Unexecuted instantiation: imsg_util.c:_rb_init
Unexecuted instantiation: util.c:_rb_init
794
795
static inline int
796
_rb_empty(struct rb_tree *rbt)
797
0
{
798
0
  return (rbt->rbt_root == NULL);
799
0
}
Unexecuted instantiation: common.c:_rb_empty
Unexecuted instantiation: test_parser_fuzz.c:_rb_empty
Unexecuted instantiation: ikev2_pld.c:_rb_empty
Unexecuted instantiation: imsg_util.c:_rb_empty
Unexecuted instantiation: util.c:_rb_empty
800
801
void  *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
802
void  *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
803
void  *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
804
void  *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
805
void  *_rb_root(const struct rb_type *, struct rb_tree *);
806
void  *_rb_min(const struct rb_type *, struct rb_tree *);
807
void  *_rb_max(const struct rb_type *, struct rb_tree *);
808
void  *_rb_next(const struct rb_type *, void *);
809
void  *_rb_prev(const struct rb_type *, void *);
810
void  *_rb_left(const struct rb_type *, void *);
811
void  *_rb_right(const struct rb_type *, void *);
812
void  *_rb_parent(const struct rb_type *, void *);
813
void   _rb_set_left(const struct rb_type *, void *, void *);
814
void   _rb_set_right(const struct rb_type *, void *, void *);
815
void   _rb_set_parent(const struct rb_type *, void *, void *);
816
void   _rb_poison(const struct rb_type *, void *, unsigned long);
817
int  _rb_check(const struct rb_type *, void *, unsigned long);
818
819
#define RBT_INITIALIZER(_head)  { { NULL } }
820
821
#define RBT_PROTOTYPE(_name, _type, _field, _cmp)     \
822
extern const struct rb_type *const _name##_RBT_TYPE;      \
823
                  \
824
__unused static inline void           \
825
_name##_RBT_INIT(struct _name *head)          \
826
{                 \
827
  _rb_init(&head->rbh_root);          \
828
}                 \
829
                  \
830
__unused static inline struct _type *         \
831
_name##_RBT_INSERT(struct _name *head, struct _type *elm)   \
832
{                 \
833
  return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm);  \
834
}                 \
835
                  \
836
__unused static inline struct _type *         \
837
_name##_RBT_REMOVE(struct _name *head, struct _type *elm)   \
838
{                 \
839
  return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm);  \
840
}                 \
841
                  \
842
__unused static inline struct _type *         \
843
_name##_RBT_FIND(struct _name *head, const struct _type *key)   \
844
{                 \
845
  return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key);  \
846
}                 \
847
                  \
848
__unused static inline struct _type *         \
849
_name##_RBT_NFIND(struct _name *head, const struct _type *key)    \
850
{                 \
851
  return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
852
}                 \
853
                  \
854
__unused static inline struct _type *         \
855
_name##_RBT_ROOT(struct _name *head)          \
856
{                 \
857
  return _rb_root(_name##_RBT_TYPE, &head->rbh_root);   \
858
}                 \
859
                  \
860
__unused static inline int            \
861
_name##_RBT_EMPTY(struct _name *head)         \
862
{                 \
863
  return _rb_empty(&head->rbh_root);        \
864
}                 \
865
                  \
866
__unused static inline struct _type *         \
867
_name##_RBT_MIN(struct _name *head)         \
868
{                 \
869
  return _rb_min(_name##_RBT_TYPE, &head->rbh_root);    \
870
}                 \
871
                  \
872
__unused static inline struct _type *         \
873
_name##_RBT_MAX(struct _name *head)         \
874
{                 \
875
  return _rb_max(_name##_RBT_TYPE, &head->rbh_root);    \
876
}                 \
877
                  \
878
__unused static inline struct _type *         \
879
_name##_RBT_NEXT(struct _type *elm)         \
880
{                 \
881
  return _rb_next(_name##_RBT_TYPE, elm);       \
882
}                 \
883
                  \
884
__unused static inline struct _type *         \
885
_name##_RBT_PREV(struct _type *elm)         \
886
{                 \
887
  return _rb_prev(_name##_RBT_TYPE, elm);       \
888
}                 \
889
                  \
890
__unused static inline struct _type *         \
891
_name##_RBT_LEFT(struct _type *elm)         \
892
{                 \
893
  return _rb_left(_name##_RBT_TYPE, elm);       \
894
}                 \
895
                  \
896
__unused static inline struct _type *         \
897
_name##_RBT_RIGHT(struct _type *elm)          \
898
{                 \
899
  return _rb_right(_name##_RBT_TYPE, elm);      \
900
}                 \
901
                  \
902
__unused static inline struct _type *         \
903
_name##_RBT_PARENT(struct _type *elm)         \
904
{                 \
905
  return _rb_parent(_name##_RBT_TYPE, elm);     \
906
}                 \
907
                  \
908
__unused static inline void           \
909
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left)   \
910
{                 \
911
  _rb_set_left(_name##_RBT_TYPE, elm, left);      \
912
}                 \
913
                  \
914
__unused static inline void           \
915
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right)   \
916
{                 \
917
  _rb_set_right(_name##_RBT_TYPE, elm, right);      \
918
}                 \
919
                  \
920
__unused static inline void           \
921
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent)   \
922
{                 \
923
  _rb_set_parent(_name##_RBT_TYPE, elm, parent);      \
924
}                 \
925
                  \
926
__unused static inline void           \
927
_name##_RBT_POISON(struct _type *elm, unsigned long poison)   \
928
{                 \
929
  _rb_poison(_name##_RBT_TYPE, elm, poison);      \
930
}                 \
931
                  \
932
__unused static inline int            \
933
_name##_RBT_CHECK(struct _type *elm, unsigned long poison)    \
934
{                 \
935
  return _rb_check(_name##_RBT_TYPE, elm, poison);    \
936
}
937
938
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug)   \
939
static int                \
940
_name##_RBT_COMPARE(const void *lptr, const void *rptr)     \
941
{                 \
942
  const struct _type *l = lptr, *r = rptr;      \
943
  return _cmp(l, r);            \
944
}                 \
945
static const struct rb_type _name##_RBT_INFO = {      \
946
  _name##_RBT_COMPARE,            \
947
  _aug,               \
948
  offsetof(struct _type, _field),         \
949
};                  \
950
const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
951
952
#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug)    \
953
static void               \
954
_name##_RBT_AUGMENT(void *ptr)            \
955
{                 \
956
  struct _type *p = ptr;            \
957
  return _aug(p);             \
958
}                 \
959
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
960
961
#define RBT_GENERATE(_name, _type, _field, _cmp)      \
962
    RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
963
964
#define RBT_INIT(_name, _head)    _name##_RBT_INIT(_head)
965
#define RBT_INSERT(_name, _head, _elm)  _name##_RBT_INSERT(_head, _elm)
966
#define RBT_REMOVE(_name, _head, _elm)  _name##_RBT_REMOVE(_head, _elm)
967
#define RBT_FIND(_name, _head, _key)  _name##_RBT_FIND(_head, _key)
968
#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)
969
#define RBT_ROOT(_name, _head)    _name##_RBT_ROOT(_head)
970
#define RBT_EMPTY(_name, _head)   _name##_RBT_EMPTY(_head)
971
#define RBT_MIN(_name, _head)   _name##_RBT_MIN(_head)
972
#define RBT_MAX(_name, _head)   _name##_RBT_MAX(_head)
973
#define RBT_NEXT(_name, _elm)   _name##_RBT_NEXT(_elm)
974
#define RBT_PREV(_name, _elm)   _name##_RBT_PREV(_elm)
975
#define RBT_LEFT(_name, _elm)   _name##_RBT_LEFT(_elm)
976
#define RBT_RIGHT(_name, _elm)    _name##_RBT_RIGHT(_elm)
977
#define RBT_PARENT(_name, _elm)   _name##_RBT_PARENT(_elm)
978
#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)
979
#define RBT_SET_RIGHT(_name, _elm, _r)  _name##_RBT_SET_RIGHT(_elm, _r)
980
#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)
981
#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
982
#define RBT_CHECK(_name, _elm, _p)  _name##_RBT_CHECK(_elm, _p)
983
984
#define RBT_FOREACH(_e, _name, _head)         \
985
  for ((_e) = RBT_MIN(_name, (_head));        \
986
       (_e) != NULL;            \
987
       (_e) = RBT_NEXT(_name, (_e)))
988
989
#define RBT_FOREACH_SAFE(_e, _name, _head, _n)        \
990
  for ((_e) = RBT_MIN(_name, (_head));        \
991
       (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \
992
       (_e) = (_n))
993
994
#define RBT_FOREACH_REVERSE(_e, _name, _head)       \
995
  for ((_e) = RBT_MAX(_name, (_head));        \
996
       (_e) != NULL;            \
997
       (_e) = RBT_PREV(_name, (_e)))
998
999
#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n)      \
1000
  for ((_e) = RBT_MAX(_name, (_head));        \
1001
       (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \
1002
       (_e) = (_n))
1003
1004
#endif  /* _SYS_TREE_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/sys/tree.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: tree.h,v 1.31 2023/03/08 04:43:09 guenther Exp $  */
2
/*
3
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#ifndef _SYS_TREE_H_
28
#define _SYS_TREE_H_
29
30
#include <sys/_null.h>
31
32
/*
33
 * This file defines data structures for different types of trees:
34
 * splay trees and red-black trees.
35
 *
36
 * A splay tree is a self-organizing data structure.  Every operation
37
 * on the tree causes a splay to happen.  The splay moves the requested
38
 * node to the root of the tree and partly rebalances it.
39
 *
40
 * This has the benefit that request locality causes faster lookups as
41
 * the requested nodes move to the top of the tree.  On the other hand,
42
 * every lookup causes memory writes.
43
 *
44
 * The Balance Theorem bounds the total access time for m operations
45
 * and n inserts on an initially empty tree as O((m + n)lg n).  The
46
 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
47
 *
48
 * A red-black tree is a binary search tree with the node color as an
49
 * extra attribute.  It fulfills a set of conditions:
50
 *  - every search path from the root to a leaf consists of the
51
 *    same number of black nodes,
52
 *  - each red node (except for the root) has a black parent,
53
 *  - each leaf node is black.
54
 *
55
 * Every operation on a red-black tree is bounded as O(lg n).
56
 * The maximum height of a red-black tree is 2lg (n+1).
57
 */
58
59
#define SPLAY_HEAD(name, type)            \
60
struct name {               \
61
  struct type *sph_root; /* root of the tree */     \
62
}
63
64
#define SPLAY_INITIALIZER(root)           \
65
  { NULL }
66
67
#define SPLAY_INIT(root) do {           \
68
  (root)->sph_root = NULL;          \
69
} while (0)
70
71
#define SPLAY_ENTRY(type)           \
72
struct {                \
73
  struct type *spe_left; /* left element */     \
74
  struct type *spe_right; /* right element */     \
75
}
76
77
#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
78
#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
79
#define SPLAY_ROOT(head)    (head)->sph_root
80
#define SPLAY_EMPTY(head)   (SPLAY_ROOT(head) == NULL)
81
82
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
83
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {     \
84
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \
85
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
86
  (head)->sph_root = tmp;           \
87
} while (0)
88
89
#define SPLAY_ROTATE_LEFT(head, tmp, field) do {      \
90
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \
91
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
92
  (head)->sph_root = tmp;           \
93
} while (0)
94
95
#define SPLAY_LINKLEFT(head, tmp, field) do {       \
96
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
97
  tmp = (head)->sph_root;           \
98
  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);   \
99
} while (0)
100
101
#define SPLAY_LINKRIGHT(head, tmp, field) do {        \
102
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
103
  tmp = (head)->sph_root;           \
104
  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
105
} while (0)
106
107
#define SPLAY_ASSEMBLE(head, node, left, right, field) do {   \
108
  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
109
  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
110
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
111
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
112
} while (0)
113
114
/* Generates prototypes and inline functions */
115
116
#define SPLAY_PROTOTYPE(name, type, field, cmp)       \
117
void name##_SPLAY(struct name *, struct type *);      \
118
void name##_SPLAY_MINMAX(struct name *, int);       \
119
struct type *name##_SPLAY_INSERT(struct name *, struct type *);   \
120
struct type *name##_SPLAY_REMOVE(struct name *, struct type *);   \
121
                  \
122
/* Finds the node with the same key as elm */       \
123
static __unused __inline struct type *          \
124
name##_SPLAY_FIND(struct name *head, struct type *elm)      \
125
{                 \
126
  if (SPLAY_EMPTY(head))            \
127
    return(NULL);           \
128
  name##_SPLAY(head, elm);          \
129
  if ((cmp)(elm, (head)->sph_root) == 0)        \
130
    return (head->sph_root);        \
131
  return (NULL);              \
132
}                 \
133
                  \
134
static __unused __inline struct type *          \
135
name##_SPLAY_NEXT(struct name *head, struct type *elm)      \
136
{                 \
137
  name##_SPLAY(head, elm);          \
138
  if (SPLAY_RIGHT(elm, field) != NULL) {        \
139
    elm = SPLAY_RIGHT(elm, field);        \
140
    while (SPLAY_LEFT(elm, field) != NULL) {    \
141
      elm = SPLAY_LEFT(elm, field);     \
142
    }             \
143
  } else                \
144
    elm = NULL;           \
145
  return (elm);             \
146
}                 \
147
                  \
148
static __unused __inline struct type *          \
149
name##_SPLAY_MIN_MAX(struct name *head, int val)      \
150
{                 \
151
  name##_SPLAY_MINMAX(head, val);         \
152
        return (SPLAY_ROOT(head));          \
153
}
154
155
/* Main splay operation.
156
 * Moves node close to the key of elm to top
157
 */
158
#define SPLAY_GENERATE(name, type, field, cmp)        \
159
struct type *               \
160
name##_SPLAY_INSERT(struct name *head, struct type *elm)    \
161
{                 \
162
    if (SPLAY_EMPTY(head)) {            \
163
      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;  \
164
    } else {                \
165
      int __comp;             \
166
      name##_SPLAY(head, elm);          \
167
      __comp = (cmp)(elm, (head)->sph_root);      \
168
      if(__comp < 0) {            \
169
        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
170
        SPLAY_RIGHT(elm, field) = (head)->sph_root;   \
171
        SPLAY_LEFT((head)->sph_root, field) = NULL;   \
172
      } else if (__comp > 0) {          \
173
        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
174
        SPLAY_LEFT(elm, field) = (head)->sph_root;    \
175
        SPLAY_RIGHT((head)->sph_root, field) = NULL;  \
176
      } else              \
177
        return ((head)->sph_root);        \
178
    }                 \
179
    (head)->sph_root = (elm);           \
180
    return (NULL);              \
181
}                 \
182
                  \
183
struct type *               \
184
name##_SPLAY_REMOVE(struct name *head, struct type *elm)    \
185
{                 \
186
  struct type *__tmp;           \
187
  if (SPLAY_EMPTY(head))            \
188
    return (NULL);            \
189
  name##_SPLAY(head, elm);          \
190
  if ((cmp)(elm, (head)->sph_root) == 0) {      \
191
    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \
192
      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
193
    } else {            \
194
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
195
      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
196
      name##_SPLAY(head, elm);      \
197
      SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
198
    }             \
199
    return (elm);           \
200
  }               \
201
  return (NULL);              \
202
}                 \
203
                  \
204
void                  \
205
name##_SPLAY(struct name *head, struct type *elm)     \
206
{                 \
207
  struct type __node, *__left, *__right, *__tmp;      \
208
  int __comp;             \
209
\
210
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
211
  __left = __right = &__node;         \
212
\
213
  while ((__comp = (cmp)(elm, (head)->sph_root))) {   \
214
    if (__comp < 0) {         \
215
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
216
      if (__tmp == NULL)        \
217
        break;          \
218
      if ((cmp)(elm, __tmp) < 0){     \
219
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
220
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
221
          break;        \
222
      }           \
223
      SPLAY_LINKLEFT(head, __right, field);   \
224
    } else if (__comp > 0) {        \
225
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
226
      if (__tmp == NULL)        \
227
        break;          \
228
      if ((cmp)(elm, __tmp) > 0){     \
229
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
230
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
231
          break;        \
232
      }           \
233
      SPLAY_LINKRIGHT(head, __left, field);   \
234
    }             \
235
  }               \
236
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
237
}                 \
238
                  \
239
/* Splay with either the minimum or the maximum element     \
240
 * Used to find minimum or maximum element in tree.     \
241
 */                 \
242
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
243
{                 \
244
  struct type __node, *__left, *__right, *__tmp;      \
245
\
246
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
247
  __left = __right = &__node;         \
248
\
249
  while (1) {             \
250
    if (__comp < 0) {         \
251
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
252
      if (__tmp == NULL)        \
253
        break;          \
254
      if (__comp < 0){        \
255
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
256
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
257
          break;        \
258
      }           \
259
      SPLAY_LINKLEFT(head, __right, field);   \
260
    } else if (__comp > 0) {        \
261
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
262
      if (__tmp == NULL)        \
263
        break;          \
264
      if (__comp > 0) {       \
265
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
266
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
267
          break;        \
268
      }           \
269
      SPLAY_LINKRIGHT(head, __left, field);   \
270
    }             \
271
  }               \
272
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
273
}
274
275
#define SPLAY_NEGINF  -1
276
#define SPLAY_INF 1
277
278
#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
279
#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
280
#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
281
#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
282
#define SPLAY_MIN(name, x)    (SPLAY_EMPTY(x) ? NULL  \
283
          : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
284
#define SPLAY_MAX(name, x)    (SPLAY_EMPTY(x) ? NULL  \
285
          : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
286
287
#define SPLAY_FOREACH(x, name, head)          \
288
  for ((x) = SPLAY_MIN(name, head);       \
289
       (x) != NULL;           \
290
       (x) = SPLAY_NEXT(name, head, x))
291
292
/* Macros that define a red-black tree */
293
#define RB_HEAD(name, type)           \
294
struct name {               \
295
  struct type *rbh_root; /* root of the tree */     \
296
}
297
298
#define RB_INITIALIZER(root)            \
299
  { NULL }
300
301
#define RB_INIT(root) do {            \
302
  (root)->rbh_root = NULL;          \
303
} while (0)
304
305
#define RB_BLACK  0
306
#define RB_RED    1
307
#define RB_ENTRY(type)              \
308
struct {                \
309
  struct type *rbe_left;    /* left element */    \
310
  struct type *rbe_right;   /* right element */   \
311
  struct type *rbe_parent;  /* parent element */    \
312
  int rbe_color;      /* node color */    \
313
}
314
315
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
316
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
317
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
318
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
319
#define RB_ROOT(head)     (head)->rbh_root
320
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
321
322
#define RB_SET(elm, parent, field) do {         \
323
  RB_PARENT(elm, field) = parent;         \
324
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
325
  RB_COLOR(elm, field) = RB_RED;          \
326
} while (0)
327
328
#define RB_SET_BLACKRED(black, red, field) do {       \
329
  RB_COLOR(black, field) = RB_BLACK;        \
330
  RB_COLOR(red, field) = RB_RED;          \
331
} while (0)
332
333
#ifndef RB_AUGMENT
334
#define RB_AUGMENT(x) do {} while (0)
335
#endif
336
337
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {      \
338
  (tmp) = RB_RIGHT(elm, field);         \
339
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {   \
340
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);    \
341
  }               \
342
  RB_AUGMENT(elm);            \
343
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
344
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
345
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
346
    else              \
347
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
348
  } else                \
349
    (head)->rbh_root = (tmp);       \
350
  RB_LEFT(tmp, field) = (elm);          \
351
  RB_PARENT(elm, field) = (tmp);          \
352
  RB_AUGMENT(tmp);            \
353
  if ((RB_PARENT(tmp, field)))          \
354
    RB_AUGMENT(RB_PARENT(tmp, field));      \
355
} while (0)
356
357
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
358
  (tmp) = RB_LEFT(elm, field);          \
359
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {   \
360
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);   \
361
  }               \
362
  RB_AUGMENT(elm);            \
363
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
364
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
365
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
366
    else              \
367
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
368
  } else                \
369
    (head)->rbh_root = (tmp);       \
370
  RB_RIGHT(tmp, field) = (elm);         \
371
  RB_PARENT(elm, field) = (tmp);          \
372
  RB_AUGMENT(tmp);            \
373
  if ((RB_PARENT(tmp, field)))          \
374
    RB_AUGMENT(RB_PARENT(tmp, field));      \
375
} while (0)
376
377
/* Generates prototypes and inline functions */
378
#define RB_PROTOTYPE(name, type, field, cmp)        \
379
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
380
#define RB_PROTOTYPE_STATIC(name, type, field, cmp)     \
381
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
382
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)   \
383
attr void name##_RB_INSERT_COLOR(struct name *, struct type *);   \
384
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
385
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
386
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
387
attr struct type *name##_RB_FIND(struct name *, struct type *);   \
388
attr struct type *name##_RB_NFIND(struct name *, struct type *);  \
389
attr struct type *name##_RB_NEXT(struct type *);      \
390
attr struct type *name##_RB_PREV(struct type *);      \
391
attr struct type *name##_RB_MINMAX(struct name *, int);     \
392
                  \
393
394
/* Main rb operation.
395
 * Moves node close to the key of elm to top
396
 */
397
#define RB_GENERATE(name, type, field, cmp)       \
398
  RB_GENERATE_INTERNAL(name, type, field, cmp,)
399
#define RB_GENERATE_STATIC(name, type, field, cmp)      \
400
  RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
401
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)    \
402
attr void               \
403
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
404
{                 \
405
  struct type *parent, *gparent, *tmp;        \
406
  while ((parent = RB_PARENT(elm, field)) &&      \
407
      RB_COLOR(parent, field) == RB_RED) {      \
408
    gparent = RB_PARENT(parent, field);     \
409
    if (parent == RB_LEFT(gparent, field)) {    \
410
      tmp = RB_RIGHT(gparent, field);     \
411
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
412
        RB_COLOR(tmp, field) = RB_BLACK;  \
413
        RB_SET_BLACKRED(parent, gparent, field);\
414
        elm = gparent;        \
415
        continue;       \
416
      }           \
417
      if (RB_RIGHT(parent, field) == elm) {   \
418
        RB_ROTATE_LEFT(head, parent, tmp, field);\
419
        tmp = parent;       \
420
        parent = elm;       \
421
        elm = tmp;        \
422
      }           \
423
      RB_SET_BLACKRED(parent, gparent, field);  \
424
      RB_ROTATE_RIGHT(head, gparent, tmp, field); \
425
    } else {            \
426
      tmp = RB_LEFT(gparent, field);      \
427
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
428
        RB_COLOR(tmp, field) = RB_BLACK;  \
429
        RB_SET_BLACKRED(parent, gparent, field);\
430
        elm = gparent;        \
431
        continue;       \
432
      }           \
433
      if (RB_LEFT(parent, field) == elm) {    \
434
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
435
        tmp = parent;       \
436
        parent = elm;       \
437
        elm = tmp;        \
438
      }           \
439
      RB_SET_BLACKRED(parent, gparent, field);  \
440
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
441
    }             \
442
  }               \
443
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
444
}                 \
445
                  \
446
attr void               \
447
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
448
{                 \
449
  struct type *tmp;           \
450
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
451
      elm != RB_ROOT(head)) {         \
452
    if (RB_LEFT(parent, field) == elm) {      \
453
      tmp = RB_RIGHT(parent, field);      \
454
      if (RB_COLOR(tmp, field) == RB_RED) {   \
455
        RB_SET_BLACKRED(tmp, parent, field);  \
456
        RB_ROTATE_LEFT(head, parent, tmp, field);\
457
        tmp = RB_RIGHT(parent, field);    \
458
      }           \
459
      if ((RB_LEFT(tmp, field) == NULL ||   \
460
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
461
          (RB_RIGHT(tmp, field) == NULL ||    \
462
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
463
        RB_COLOR(tmp, field) = RB_RED;    \
464
        elm = parent;       \
465
        parent = RB_PARENT(elm, field);   \
466
      } else {          \
467
        if (RB_RIGHT(tmp, field) == NULL || \
468
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
469
          struct type *oleft;   \
470
          if ((oleft = RB_LEFT(tmp, field)))\
471
            RB_COLOR(oleft, field) = RB_BLACK;\
472
          RB_COLOR(tmp, field) = RB_RED;  \
473
          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
474
          tmp = RB_RIGHT(parent, field);  \
475
        }         \
476
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
477
        RB_COLOR(parent, field) = RB_BLACK; \
478
        if (RB_RIGHT(tmp, field))   \
479
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
480
        RB_ROTATE_LEFT(head, parent, tmp, field);\
481
        elm = RB_ROOT(head);      \
482
        break;          \
483
      }           \
484
    } else {            \
485
      tmp = RB_LEFT(parent, field);     \
486
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
        RB_SET_BLACKRED(tmp, parent, field);  \
488
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
489
        tmp = RB_LEFT(parent, field);   \
490
      }           \
491
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
          (RB_RIGHT(tmp, field) == NULL ||    \
494
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
        RB_COLOR(tmp, field) = RB_RED;    \
496
        elm = parent;       \
497
        parent = RB_PARENT(elm, field);   \
498
      } else {          \
499
        if (RB_LEFT(tmp, field) == NULL ||  \
500
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
501
          struct type *oright;    \
502
          if ((oright = RB_RIGHT(tmp, field)))\
503
            RB_COLOR(oright, field) = RB_BLACK;\
504
          RB_COLOR(tmp, field) = RB_RED;  \
505
          RB_ROTATE_LEFT(head, tmp, oright, field);\
506
          tmp = RB_LEFT(parent, field); \
507
        }         \
508
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
509
        RB_COLOR(parent, field) = RB_BLACK; \
510
        if (RB_LEFT(tmp, field))    \
511
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
512
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
513
        elm = RB_ROOT(head);      \
514
        break;          \
515
      }           \
516
    }             \
517
  }               \
518
  if (elm)              \
519
    RB_COLOR(elm, field) = RB_BLACK;      \
520
}                 \
521
                  \
522
attr struct type *              \
523
name##_RB_REMOVE(struct name *head, struct type *elm)     \
524
{                 \
525
  struct type *child, *parent, *old = elm;      \
526
  int color;              \
527
  if (RB_LEFT(elm, field) == NULL)        \
528
    child = RB_RIGHT(elm, field);       \
529
  else if (RB_RIGHT(elm, field) == NULL)        \
530
    child = RB_LEFT(elm, field);        \
531
  else {                \
532
    struct type *left;          \
533
    elm = RB_RIGHT(elm, field);       \
534
    while ((left = RB_LEFT(elm, field)))      \
535
      elm = left;         \
536
    child = RB_RIGHT(elm, field);       \
537
    parent = RB_PARENT(elm, field);       \
538
    color = RB_COLOR(elm, field);       \
539
    if (child)            \
540
      RB_PARENT(child, field) = parent;   \
541
    if (parent) {           \
542
      if (RB_LEFT(parent, field) == elm)    \
543
        RB_LEFT(parent, field) = child;   \
544
      else            \
545
        RB_RIGHT(parent, field) = child;  \
546
      RB_AUGMENT(parent);       \
547
    } else              \
548
      RB_ROOT(head) = child;        \
549
    if (RB_PARENT(elm, field) == old)     \
550
      parent = elm;         \
551
    (elm)->field = (old)->field;        \
552
    if (RB_PARENT(old, field)) {        \
553
      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
554
        RB_LEFT(RB_PARENT(old, field), field) = elm;\
555
      else            \
556
        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
557
      RB_AUGMENT(RB_PARENT(old, field));    \
558
    } else              \
559
      RB_ROOT(head) = elm;        \
560
    RB_PARENT(RB_LEFT(old, field), field) = elm;    \
561
    if (RB_RIGHT(old, field))       \
562
      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
563
    if (parent) {           \
564
      left = parent;          \
565
      do {            \
566
        RB_AUGMENT(left);     \
567
      } while ((left = RB_PARENT(left, field)));  \
568
    }             \
569
    goto color;           \
570
  }               \
571
  parent = RB_PARENT(elm, field);         \
572
  color = RB_COLOR(elm, field);         \
573
  if (child)              \
574
    RB_PARENT(child, field) = parent;     \
575
  if (parent) {             \
576
    if (RB_LEFT(parent, field) == elm)      \
577
      RB_LEFT(parent, field) = child;     \
578
    else              \
579
      RB_RIGHT(parent, field) = child;    \
580
    RB_AUGMENT(parent);         \
581
  } else                \
582
    RB_ROOT(head) = child;          \
583
color:                  \
584
  if (color == RB_BLACK)            \
585
    name##_RB_REMOVE_COLOR(head, parent, child);    \
586
  return (old);             \
587
}                 \
588
                  \
589
/* Inserts a node into the RB tree */         \
590
attr struct type *              \
591
name##_RB_INSERT(struct name *head, struct type *elm)     \
592
{                 \
593
  struct type *tmp;           \
594
  struct type *parent = NULL;         \
595
  int comp = 0;             \
596
  tmp = RB_ROOT(head);            \
597
  while (tmp) {             \
598
    parent = tmp;           \
599
    comp = (cmp)(elm, parent);        \
600
    if (comp < 0)           \
601
      tmp = RB_LEFT(tmp, field);      \
602
    else if (comp > 0)          \
603
      tmp = RB_RIGHT(tmp, field);     \
604
    else              \
605
      return (tmp);         \
606
  }               \
607
  RB_SET(elm, parent, field);         \
608
  if (parent != NULL) {           \
609
    if (comp < 0)           \
610
      RB_LEFT(parent, field) = elm;     \
611
    else              \
612
      RB_RIGHT(parent, field) = elm;      \
613
    RB_AUGMENT(parent);         \
614
  } else                \
615
    RB_ROOT(head) = elm;          \
616
  name##_RB_INSERT_COLOR(head, elm);        \
617
  return (NULL);              \
618
}                 \
619
                  \
620
/* Finds the node with the same key as elm */       \
621
attr struct type *              \
622
name##_RB_FIND(struct name *head, struct type *elm)     \
623
{                 \
624
  struct type *tmp = RB_ROOT(head);       \
625
  int comp;             \
626
  while (tmp) {             \
627
    comp = cmp(elm, tmp);         \
628
    if (comp < 0)           \
629
      tmp = RB_LEFT(tmp, field);      \
630
    else if (comp > 0)          \
631
      tmp = RB_RIGHT(tmp, field);     \
632
    else              \
633
      return (tmp);         \
634
  }               \
635
  return (NULL);              \
636
}                 \
637
                  \
638
/* Finds the first node greater than or equal to the search key */  \
639
attr struct type *              \
640
name##_RB_NFIND(struct name *head, struct type *elm)      \
641
{                 \
642
  struct type *tmp = RB_ROOT(head);       \
643
  struct type *res = NULL;          \
644
  int comp;             \
645
  while (tmp) {             \
646
    comp = cmp(elm, tmp);         \
647
    if (comp < 0) {           \
648
      res = tmp;          \
649
      tmp = RB_LEFT(tmp, field);      \
650
    }             \
651
    else if (comp > 0)          \
652
      tmp = RB_RIGHT(tmp, field);     \
653
    else              \
654
      return (tmp);         \
655
  }               \
656
  return (res);             \
657
}                 \
658
                  \
659
attr struct type *              \
660
name##_RB_NEXT(struct type *elm)          \
661
{                 \
662
  if (RB_RIGHT(elm, field)) {         \
663
    elm = RB_RIGHT(elm, field);       \
664
    while (RB_LEFT(elm, field))       \
665
      elm = RB_LEFT(elm, field);      \
666
  } else {              \
667
    if (RB_PARENT(elm, field) &&        \
668
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
669
      elm = RB_PARENT(elm, field);      \
670
    else {              \
671
      while (RB_PARENT(elm, field) &&     \
672
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
673
        elm = RB_PARENT(elm, field);    \
674
      elm = RB_PARENT(elm, field);      \
675
    }             \
676
  }               \
677
  return (elm);             \
678
}                 \
679
                  \
680
attr struct type *              \
681
name##_RB_PREV(struct type *elm)          \
682
{                 \
683
  if (RB_LEFT(elm, field)) {          \
684
    elm = RB_LEFT(elm, field);        \
685
    while (RB_RIGHT(elm, field))        \
686
      elm = RB_RIGHT(elm, field);     \
687
  } else {              \
688
    if (RB_PARENT(elm, field) &&        \
689
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))  \
690
      elm = RB_PARENT(elm, field);      \
691
    else {              \
692
      while (RB_PARENT(elm, field) &&     \
693
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
694
        elm = RB_PARENT(elm, field);    \
695
      elm = RB_PARENT(elm, field);      \
696
    }             \
697
  }               \
698
  return (elm);             \
699
}                 \
700
                  \
701
attr struct type *              \
702
name##_RB_MINMAX(struct name *head, int val)        \
703
{                 \
704
  struct type *tmp = RB_ROOT(head);       \
705
  struct type *parent = NULL;         \
706
  while (tmp) {             \
707
    parent = tmp;           \
708
    if (val < 0)            \
709
      tmp = RB_LEFT(tmp, field);      \
710
    else              \
711
      tmp = RB_RIGHT(tmp, field);     \
712
  }               \
713
  return (parent);            \
714
}
715
716
#define RB_NEGINF -1
717
#define RB_INF  1
718
719
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
720
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
721
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
722
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
723
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
724
#define RB_PREV(name, x, y) name##_RB_PREV(y)
725
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
726
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
727
728
#define RB_FOREACH(x, name, head)         \
729
  for ((x) = RB_MIN(name, head);          \
730
       (x) != NULL;           \
731
       (x) = name##_RB_NEXT(x))
732
733
#define RB_FOREACH_SAFE(x, name, head, y)       \
734
  for ((x) = RB_MIN(name, head);          \
735
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);    \
736
       (x) = (y))
737
738
#define RB_FOREACH_REVERSE(x, name, head)       \
739
  for ((x) = RB_MAX(name, head);          \
740
       (x) != NULL;           \
741
       (x) = name##_RB_PREV(x))
742
743
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)     \
744
  for ((x) = RB_MAX(name, head);          \
745
      ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);    \
746
       (x) = (y))
747
748
749
/*
750
 * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
751
 *
752
 * Permission to use, copy, modify, and distribute this software for any
753
 * purpose with or without fee is hereby granted, provided that the above
754
 * copyright notice and this permission notice appear in all copies.
755
 *
756
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
757
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
758
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
759
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
760
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
761
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
762
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
763
 */
764
765
struct rb_type {
766
  int   (*t_compare)(const void *, const void *);
767
  void    (*t_augment)(void *);
768
  unsigned int    t_offset; /* offset of rb_entry in type */
769
};
770
771
struct rb_tree {
772
  struct rb_entry *rbt_root;
773
};
774
775
struct rb_entry {
776
  struct rb_entry  *rbt_parent;
777
  struct rb_entry  *rbt_left;
778
  struct rb_entry  *rbt_right;
779
  unsigned int    rbt_color;
780
};
781
782
#define RBT_HEAD(_name, _type)            \
783
struct _name {                \
784
  struct rb_tree rbh_root;          \
785
}
786
787
#define RBT_ENTRY(_type)  struct rb_entry
788
789
static inline void
790
_rb_init(struct rb_tree *rbt)
791
0
{
792
0
  rbt->rbt_root = NULL;
793
0
}
Unexecuted instantiation: common.c:_rb_init
Unexecuted instantiation: test_parser_fuzz.c:_rb_init
Unexecuted instantiation: ikev2_pld.c:_rb_init
Unexecuted instantiation: imsg_util.c:_rb_init
Unexecuted instantiation: util.c:_rb_init
794
795
static inline int
796
_rb_empty(struct rb_tree *rbt)
797
0
{
798
0
  return (rbt->rbt_root == NULL);
799
0
}
Unexecuted instantiation: common.c:_rb_empty
Unexecuted instantiation: test_parser_fuzz.c:_rb_empty
Unexecuted instantiation: ikev2_pld.c:_rb_empty
Unexecuted instantiation: imsg_util.c:_rb_empty
Unexecuted instantiation: util.c:_rb_empty
800
801
void  *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
802
void  *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
803
void  *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
804
void  *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
805
void  *_rb_root(const struct rb_type *, struct rb_tree *);
806
void  *_rb_min(const struct rb_type *, struct rb_tree *);
807
void  *_rb_max(const struct rb_type *, struct rb_tree *);
808
void  *_rb_next(const struct rb_type *, void *);
809
void  *_rb_prev(const struct rb_type *, void *);
810
void  *_rb_left(const struct rb_type *, void *);
811
void  *_rb_right(const struct rb_type *, void *);
812
void  *_rb_parent(const struct rb_type *, void *);
813
void   _rb_set_left(const struct rb_type *, void *, void *);
814
void   _rb_set_right(const struct rb_type *, void *, void *);
815
void   _rb_set_parent(const struct rb_type *, void *, void *);
816
void   _rb_poison(const struct rb_type *, void *, unsigned long);
817
int  _rb_check(const struct rb_type *, void *, unsigned long);
818
819
#define RBT_INITIALIZER(_head)  { { NULL } }
820
821
#define RBT_PROTOTYPE(_name, _type, _field, _cmp)     \
822
extern const struct rb_type *const _name##_RBT_TYPE;      \
823
                  \
824
__unused static inline void           \
825
_name##_RBT_INIT(struct _name *head)          \
826
{                 \
827
  _rb_init(&head->rbh_root);          \
828
}                 \
829
                  \
830
__unused static inline struct _type *         \
831
_name##_RBT_INSERT(struct _name *head, struct _type *elm)   \
832
{                 \
833
  return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm);  \
834
}                 \
835
                  \
836
__unused static inline struct _type *         \
837
_name##_RBT_REMOVE(struct _name *head, struct _type *elm)   \
838
{                 \
839
  return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm);  \
840
}                 \
841
                  \
842
__unused static inline struct _type *         \
843
_name##_RBT_FIND(struct _name *head, const struct _type *key)   \
844
{                 \
845
  return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key);  \
846
}                 \
847
                  \
848
__unused static inline struct _type *         \
849
_name##_RBT_NFIND(struct _name *head, const struct _type *key)    \
850
{                 \
851
  return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
852
}                 \
853
                  \
854
__unused static inline struct _type *         \
855
_name##_RBT_ROOT(struct _name *head)          \
856
{                 \
857
  return _rb_root(_name##_RBT_TYPE, &head->rbh_root);   \
858
}                 \
859
                  \
860
__unused static inline int            \
861
_name##_RBT_EMPTY(struct _name *head)         \
862
{                 \
863
  return _rb_empty(&head->rbh_root);        \
864
}                 \
865
                  \
866
__unused static inline struct _type *         \
867
_name##_RBT_MIN(struct _name *head)         \
868
{                 \
869
  return _rb_min(_name##_RBT_TYPE, &head->rbh_root);    \
870
}                 \
871
                  \
872
__unused static inline struct _type *         \
873
_name##_RBT_MAX(struct _name *head)         \
874
{                 \
875
  return _rb_max(_name##_RBT_TYPE, &head->rbh_root);    \
876
}                 \
877
                  \
878
__unused static inline struct _type *         \
879
_name##_RBT_NEXT(struct _type *elm)         \
880
{                 \
881
  return _rb_next(_name##_RBT_TYPE, elm);       \
882
}                 \
883
                  \
884
__unused static inline struct _type *         \
885
_name##_RBT_PREV(struct _type *elm)         \
886
{                 \
887
  return _rb_prev(_name##_RBT_TYPE, elm);       \
888
}                 \
889
                  \
890
__unused static inline struct _type *         \
891
_name##_RBT_LEFT(struct _type *elm)         \
892
{                 \
893
  return _rb_left(_name##_RBT_TYPE, elm);       \
894
}                 \
895
                  \
896
__unused static inline struct _type *         \
897
_name##_RBT_RIGHT(struct _type *elm)          \
898
{                 \
899
  return _rb_right(_name##_RBT_TYPE, elm);      \
900
}                 \
901
                  \
902
__unused static inline struct _type *         \
903
_name##_RBT_PARENT(struct _type *elm)         \
904
{                 \
905
  return _rb_parent(_name##_RBT_TYPE, elm);     \
906
}                 \
907
                  \
908
__unused static inline void           \
909
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left)   \
910
{                 \
911
  _rb_set_left(_name##_RBT_TYPE, elm, left);      \
912
}                 \
913
                  \
914
__unused static inline void           \
915
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right)   \
916
{                 \
917
  _rb_set_right(_name##_RBT_TYPE, elm, right);      \
918
}                 \
919
                  \
920
__unused static inline void           \
921
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent)   \
922
{                 \
923
  _rb_set_parent(_name##_RBT_TYPE, elm, parent);      \
924
}                 \
925
                  \
926
__unused static inline void           \
927
_name##_RBT_POISON(struct _type *elm, unsigned long poison)   \
928
{                 \
929
  _rb_poison(_name##_RBT_TYPE, elm, poison);      \
930
}                 \
931
                  \
932
__unused static inline int            \
933
_name##_RBT_CHECK(struct _type *elm, unsigned long poison)    \
934
{                 \
935
  return _rb_check(_name##_RBT_TYPE, elm, poison);    \
936
}
937
938
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug)   \
939
static int                \
940
_name##_RBT_COMPARE(const void *lptr, const void *rptr)     \
941
{                 \
942
  const struct _type *l = lptr, *r = rptr;      \
943
  return _cmp(l, r);            \
944
}                 \
945
static const struct rb_type _name##_RBT_INFO = {      \
946
  _name##_RBT_COMPARE,            \
947
  _aug,               \
948
  offsetof(struct _type, _field),         \
949
};                  \
950
const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
951
952
#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug)    \
953
static void               \
954
_name##_RBT_AUGMENT(void *ptr)            \
955
{                 \
956
  struct _type *p = ptr;            \
957
  return _aug(p);             \
958
}                 \
959
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
960
961
#define RBT_GENERATE(_name, _type, _field, _cmp)      \
962
    RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
963
964
#define RBT_INIT(_name, _head)    _name##_RBT_INIT(_head)
965
#define RBT_INSERT(_name, _head, _elm)  _name##_RBT_INSERT(_head, _elm)
966
#define RBT_REMOVE(_name, _head, _elm)  _name##_RBT_REMOVE(_head, _elm)
967
#define RBT_FIND(_name, _head, _key)  _name##_RBT_FIND(_head, _key)
968
#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)
969
#define RBT_ROOT(_name, _head)    _name##_RBT_ROOT(_head)
970
#define RBT_EMPTY(_name, _head)   _name##_RBT_EMPTY(_head)
971
#define RBT_MIN(_name, _head)   _name##_RBT_MIN(_head)
972
#define RBT_MAX(_name, _head)   _name##_RBT_MAX(_head)
973
#define RBT_NEXT(_name, _elm)   _name##_RBT_NEXT(_elm)
974
#define RBT_PREV(_name, _elm)   _name##_RBT_PREV(_elm)
975
#define RBT_LEFT(_name, _elm)   _name##_RBT_LEFT(_elm)
976
#define RBT_RIGHT(_name, _elm)    _name##_RBT_RIGHT(_elm)
977
#define RBT_PARENT(_name, _elm)   _name##_RBT_PARENT(_elm)
978
#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)
979
#define RBT_SET_RIGHT(_name, _elm, _r)  _name##_RBT_SET_RIGHT(_elm, _r)
980
#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)
981
#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
982
#define RBT_CHECK(_name, _elm, _p)  _name##_RBT_CHECK(_elm, _p)
983
984
#define RBT_FOREACH(_e, _name, _head)         \
985
  for ((_e) = RBT_MIN(_name, (_head));        \
986
       (_e) != NULL;            \
987
       (_e) = RBT_NEXT(_name, (_e)))
988
989
#define RBT_FOREACH_SAFE(_e, _name, _head, _n)        \
990
  for ((_e) = RBT_MIN(_name, (_head));        \
991
       (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \
992
       (_e) = (_n))
993
994
#define RBT_FOREACH_REVERSE(_e, _name, _head)       \
995
  for ((_e) = RBT_MAX(_name, (_head));        \
996
       (_e) != NULL;            \
997
       (_e) = RBT_PREV(_name, (_e)))
998
999
#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n)      \
1000
  for ((_e) = RBT_MAX(_name, (_head));        \
1001
       (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \
1002
       (_e) = (_n))
1003
1004
#endif  /* _SYS_TREE_H_ */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/vis.c.html b/coverage/latest/report/linux/src/openiked-portable/compat/vis.c.html index 462a8a191..29d83c21c 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/vis.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/vis.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/vis.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.c,v 1.26 2022/05/04 18:57:50 deraadt Exp $ */
2
/*-
3
 * Copyright (c) 1989, 1993
4
 *  The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
32
33
#if !defined(HAVE_STRNVIS)
34
35
#include <sys/types.h>
36
#include <errno.h>
37
#include <ctype.h>
38
#include <limits.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <vis.h>
42
43
static int
44
isoctal(int c)
45
0
{
46
0
  u_char uc = c;
47
48
0
  return uc >= '0' && uc <= '7';
49
0
}
50
51
static int
52
isvisible(int c, int flag)
53
0
{
54
0
  int vis_sp = flag & VIS_SP;
55
0
  int vis_tab = flag & VIS_TAB;
56
0
  int vis_nl = flag & VIS_NL;
57
0
  int vis_safe = flag & VIS_SAFE;
58
0
  int vis_glob = flag & VIS_GLOB;
59
0
  int vis_all = flag & VIS_ALL;
60
0
  u_char uc = c;
61
62
0
  if (c == '\\' || !vis_all) {
63
0
    if ((u_int)c <= UCHAR_MAX && isascii(uc) &&
64
0
        ((c != '*' && c != '?' && c != '[' && c != '#') || !vis_glob) &&
65
0
        isgraph(uc))
66
0
      return 1;
67
0
    if (!vis_sp && c == ' ')
68
0
      return 1;
69
0
    if (!vis_tab && c == '\t')
70
0
      return 1;
71
0
    if (!vis_nl && c == '\n')
72
0
      return 1;
73
0
    if (vis_safe && (c == '\b' || c == '\007' || c == '\r' || isgraph(uc)))
74
0
      return 1;
75
0
  }
76
0
  return 0;
77
0
}
78
79
/*
80
 * vis - visually encode characters
81
 */
82
char *
83
vis(char *dst, int c, int flag, int nextc)
84
0
{
85
0
  int vis_dq = flag & VIS_DQ;
86
0
  int vis_noslash = flag & VIS_NOSLASH;
87
0
  int vis_cstyle = flag & VIS_CSTYLE;
88
0
  int vis_octal = flag & VIS_OCTAL;
89
0
  int vis_glob = flag & VIS_GLOB;
90
91
0
  if (isvisible(c, flag)) {
92
0
    if ((c == '"' && vis_dq) ||
93
0
        (c == '\\' && !vis_noslash))
94
0
      *dst++ = '\\';
95
0
    *dst++ = c;
96
0
    *dst = '\0';
97
0
    return (dst);
98
0
  }
99
100
0
  if (vis_cstyle) {
101
0
    switch (c) {
102
0
    case '\n':
103
0
      *dst++ = '\\';
104
0
      *dst++ = 'n';
105
0
      goto done;
106
0
    case '\r':
107
0
      *dst++ = '\\';
108
0
      *dst++ = 'r';
109
0
      goto done;
110
0
    case '\b':
111
0
      *dst++ = '\\';
112
0
      *dst++ = 'b';
113
0
      goto done;
114
0
    case '\a':
115
0
      *dst++ = '\\';
116
0
      *dst++ = 'a';
117
0
      goto done;
118
0
    case '\v':
119
0
      *dst++ = '\\';
120
0
      *dst++ = 'v';
121
0
      goto done;
122
0
    case '\t':
123
0
      *dst++ = '\\';
124
0
      *dst++ = 't';
125
0
      goto done;
126
0
    case '\f':
127
0
      *dst++ = '\\';
128
0
      *dst++ = 'f';
129
0
      goto done;
130
0
    case ' ':
131
0
      *dst++ = '\\';
132
0
      *dst++ = 's';
133
0
      goto done;
134
0
    case '\0':
135
0
      *dst++ = '\\';
136
0
      *dst++ = '0';
137
0
      if (isoctal(nextc)) {
138
0
        *dst++ = '0';
139
0
        *dst++ = '0';
140
0
      }
141
0
      goto done;
142
0
    }
143
0
  }
144
0
  if (((c & 0177) == ' ') || vis_octal ||
145
0
      (vis_glob && (c == '*' || c == '?' || c == '[' || c == '#'))) {
146
0
    *dst++ = '\\';
147
0
    *dst++ = ((u_char)c >> 6 & 07) + '0';
148
0
    *dst++ = ((u_char)c >> 3 & 07) + '0';
149
0
    *dst++ = ((u_char)c & 07) + '0';
150
0
    goto done;
151
0
  }
152
0
  if (!vis_noslash)
153
0
    *dst++ = '\\';
154
0
  if (c & 0200) {
155
0
    c &= 0177;
156
0
    *dst++ = 'M';
157
0
  }
158
0
  if (iscntrl((u_char)c)) {
159
0
    *dst++ = '^';
160
0
    if (c == 0177)
161
0
      *dst++ = '?';
162
0
    else
163
0
      *dst++ = c + '@';
164
0
  } else {
165
0
    *dst++ = '-';
166
0
    *dst++ = c;
167
0
  }
168
0
done:
169
0
  *dst = '\0';
170
0
  return (dst);
171
0
}
172
173
/*
174
 * strvis, strnvis, strvisx - visually encode characters from src into dst
175
 *  
176
 *  Dst must be 4 times the size of src to account for possible
177
 *  expansion.  The length of dst, not including the trailing NULL,
178
 *  is returned. 
179
 *
180
 *  Strnvis will write no more than siz-1 bytes (and will NULL terminate).
181
 *  The number of bytes needed to fully encode the string is returned.
182
 *
183
 *  Strvisx encodes exactly len bytes from src into dst.
184
 *  This is useful for encoding a block of data.
185
 */
186
int
187
strvis(char *dst, const char *src, int flag)
188
0
{
189
0
  char c;
190
0
  char *start;
191
192
0
  for (start = dst; (c = *src);)
193
0
    dst = vis(dst, c, flag, *++src);
194
0
  *dst = '\0';
195
0
  return (dst - start);
196
0
}
197
198
int
199
strnvis(char *dst, const char *src, size_t siz, int flag)
200
0
{
201
0
  int vis_dq = flag & VIS_DQ;
202
0
  int vis_noslash = flag & VIS_NOSLASH;
203
0
  char *start, *end;
204
0
  char tbuf[5];
205
0
  int c, i;
206
207
0
  i = 0;
208
0
  for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
209
0
    if (isvisible(c, flag)) {
210
0
      if ((c == '"' && vis_dq) ||
211
0
          (c == '\\' && !vis_noslash)) {
212
        /* need space for the extra '\\' */
213
0
        if (dst + 1 >= end) {
214
0
          i = 2;
215
0
          break;
216
0
        }
217
0
        *dst++ = '\\';
218
0
      }
219
0
      i = 1;
220
0
      *dst++ = c;
221
0
      src++;
222
0
    } else {
223
0
      i = vis(tbuf, c, flag, *++src) - tbuf;
224
0
      if (dst + i <= end) {
225
0
        memcpy(dst, tbuf, i);
226
0
        dst += i;
227
0
      } else {
228
0
        src--;
229
0
        break;
230
0
      }
231
0
    }
232
0
  }
233
0
  if (siz > 0)
234
0
    *dst = '\0';
235
0
  if (dst + i > end) {
236
    /* adjust return value for truncation */
237
0
    while ((c = *src))
238
0
      dst += vis(tbuf, c, flag, *++src) - tbuf;
239
0
  }
240
0
  return (dst - start);
241
0
}
242
243
int
244
stravis(char **outp, const char *src, int flag)
245
0
{
246
0
  char *buf;
247
0
  int len, serrno;
248
249
0
  buf = reallocarray(NULL, 4, strlen(src) + 1);
250
0
  if (buf == NULL)
251
0
    return -1;
252
0
  len = strvis(buf, src, flag);
253
0
  serrno = errno;
254
0
  *outp = realloc(buf, len + 1);
255
0
  if (*outp == NULL) {
256
0
    *outp = buf;
257
0
    errno = serrno;
258
0
  }
259
0
  return (len);
260
0
}
261
262
int
263
strvisx(char *dst, const char *src, size_t len, int flag)
264
0
{
265
0
  char c;
266
0
  char *start;
267
268
0
  for (start = dst; len > 1; len--) {
269
0
    c = *src;
270
0
    dst = vis(dst, c, flag, *++src);
271
0
  }
272
0
  if (len)
273
0
    dst = vis(dst, *src, flag, '\0');
274
0
  *dst = '\0';
275
0
  return (dst - start);
276
0
}
277
278
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/vis.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.c,v 1.26 2022/05/04 18:57:50 deraadt Exp $ */
2
/*-
3
 * Copyright (c) 1989, 1993
4
 *  The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
32
33
#if !defined(HAVE_STRNVIS)
34
35
#include <sys/types.h>
36
#include <errno.h>
37
#include <ctype.h>
38
#include <limits.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <vis.h>
42
43
static int
44
isoctal(int c)
45
0
{
46
0
  u_char uc = c;
47
48
0
  return uc >= '0' && uc <= '7';
49
0
}
50
51
static int
52
isvisible(int c, int flag)
53
0
{
54
0
  int vis_sp = flag & VIS_SP;
55
0
  int vis_tab = flag & VIS_TAB;
56
0
  int vis_nl = flag & VIS_NL;
57
0
  int vis_safe = flag & VIS_SAFE;
58
0
  int vis_glob = flag & VIS_GLOB;
59
0
  int vis_all = flag & VIS_ALL;
60
0
  u_char uc = c;
61
62
0
  if (c == '\\' || !vis_all) {
63
0
    if ((u_int)c <= UCHAR_MAX && isascii(uc) &&
64
0
        ((c != '*' && c != '?' && c != '[' && c != '#') || !vis_glob) &&
65
0
        isgraph(uc))
66
0
      return 1;
67
0
    if (!vis_sp && c == ' ')
68
0
      return 1;
69
0
    if (!vis_tab && c == '\t')
70
0
      return 1;
71
0
    if (!vis_nl && c == '\n')
72
0
      return 1;
73
0
    if (vis_safe && (c == '\b' || c == '\007' || c == '\r' || isgraph(uc)))
74
0
      return 1;
75
0
  }
76
0
  return 0;
77
0
}
78
79
/*
80
 * vis - visually encode characters
81
 */
82
char *
83
vis(char *dst, int c, int flag, int nextc)
84
0
{
85
0
  int vis_dq = flag & VIS_DQ;
86
0
  int vis_noslash = flag & VIS_NOSLASH;
87
0
  int vis_cstyle = flag & VIS_CSTYLE;
88
0
  int vis_octal = flag & VIS_OCTAL;
89
0
  int vis_glob = flag & VIS_GLOB;
90
91
0
  if (isvisible(c, flag)) {
92
0
    if ((c == '"' && vis_dq) ||
93
0
        (c == '\\' && !vis_noslash))
94
0
      *dst++ = '\\';
95
0
    *dst++ = c;
96
0
    *dst = '\0';
97
0
    return (dst);
98
0
  }
99
100
0
  if (vis_cstyle) {
101
0
    switch (c) {
102
0
    case '\n':
103
0
      *dst++ = '\\';
104
0
      *dst++ = 'n';
105
0
      goto done;
106
0
    case '\r':
107
0
      *dst++ = '\\';
108
0
      *dst++ = 'r';
109
0
      goto done;
110
0
    case '\b':
111
0
      *dst++ = '\\';
112
0
      *dst++ = 'b';
113
0
      goto done;
114
0
    case '\a':
115
0
      *dst++ = '\\';
116
0
      *dst++ = 'a';
117
0
      goto done;
118
0
    case '\v':
119
0
      *dst++ = '\\';
120
0
      *dst++ = 'v';
121
0
      goto done;
122
0
    case '\t':
123
0
      *dst++ = '\\';
124
0
      *dst++ = 't';
125
0
      goto done;
126
0
    case '\f':
127
0
      *dst++ = '\\';
128
0
      *dst++ = 'f';
129
0
      goto done;
130
0
    case ' ':
131
0
      *dst++ = '\\';
132
0
      *dst++ = 's';
133
0
      goto done;
134
0
    case '\0':
135
0
      *dst++ = '\\';
136
0
      *dst++ = '0';
137
0
      if (isoctal(nextc)) {
138
0
        *dst++ = '0';
139
0
        *dst++ = '0';
140
0
      }
141
0
      goto done;
142
0
    }
143
0
  }
144
0
  if (((c & 0177) == ' ') || vis_octal ||
145
0
      (vis_glob && (c == '*' || c == '?' || c == '[' || c == '#'))) {
146
0
    *dst++ = '\\';
147
0
    *dst++ = ((u_char)c >> 6 & 07) + '0';
148
0
    *dst++ = ((u_char)c >> 3 & 07) + '0';
149
0
    *dst++ = ((u_char)c & 07) + '0';
150
0
    goto done;
151
0
  }
152
0
  if (!vis_noslash)
153
0
    *dst++ = '\\';
154
0
  if (c & 0200) {
155
0
    c &= 0177;
156
0
    *dst++ = 'M';
157
0
  }
158
0
  if (iscntrl((u_char)c)) {
159
0
    *dst++ = '^';
160
0
    if (c == 0177)
161
0
      *dst++ = '?';
162
0
    else
163
0
      *dst++ = c + '@';
164
0
  } else {
165
0
    *dst++ = '-';
166
0
    *dst++ = c;
167
0
  }
168
0
done:
169
0
  *dst = '\0';
170
0
  return (dst);
171
0
}
172
173
/*
174
 * strvis, strnvis, strvisx - visually encode characters from src into dst
175
 *  
176
 *  Dst must be 4 times the size of src to account for possible
177
 *  expansion.  The length of dst, not including the trailing NULL,
178
 *  is returned. 
179
 *
180
 *  Strnvis will write no more than siz-1 bytes (and will NULL terminate).
181
 *  The number of bytes needed to fully encode the string is returned.
182
 *
183
 *  Strvisx encodes exactly len bytes from src into dst.
184
 *  This is useful for encoding a block of data.
185
 */
186
int
187
strvis(char *dst, const char *src, int flag)
188
0
{
189
0
  char c;
190
0
  char *start;
191
192
0
  for (start = dst; (c = *src);)
193
0
    dst = vis(dst, c, flag, *++src);
194
0
  *dst = '\0';
195
0
  return (dst - start);
196
0
}
197
198
int
199
strnvis(char *dst, const char *src, size_t siz, int flag)
200
0
{
201
0
  int vis_dq = flag & VIS_DQ;
202
0
  int vis_noslash = flag & VIS_NOSLASH;
203
0
  char *start, *end;
204
0
  char tbuf[5];
205
0
  int c, i;
206
207
0
  i = 0;
208
0
  for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
209
0
    if (isvisible(c, flag)) {
210
0
      if ((c == '"' && vis_dq) ||
211
0
          (c == '\\' && !vis_noslash)) {
212
        /* need space for the extra '\\' */
213
0
        if (dst + 1 >= end) {
214
0
          i = 2;
215
0
          break;
216
0
        }
217
0
        *dst++ = '\\';
218
0
      }
219
0
      i = 1;
220
0
      *dst++ = c;
221
0
      src++;
222
0
    } else {
223
0
      i = vis(tbuf, c, flag, *++src) - tbuf;
224
0
      if (dst + i <= end) {
225
0
        memcpy(dst, tbuf, i);
226
0
        dst += i;
227
0
      } else {
228
0
        src--;
229
0
        break;
230
0
      }
231
0
    }
232
0
  }
233
0
  if (siz > 0)
234
0
    *dst = '\0';
235
0
  if (dst + i > end) {
236
    /* adjust return value for truncation */
237
0
    while ((c = *src))
238
0
      dst += vis(tbuf, c, flag, *++src) - tbuf;
239
0
  }
240
0
  return (dst - start);
241
0
}
242
243
int
244
stravis(char **outp, const char *src, int flag)
245
0
{
246
0
  char *buf;
247
0
  int len, serrno;
248
249
0
  buf = reallocarray(NULL, 4, strlen(src) + 1);
250
0
  if (buf == NULL)
251
0
    return -1;
252
0
  len = strvis(buf, src, flag);
253
0
  serrno = errno;
254
0
  *outp = realloc(buf, len + 1);
255
0
  if (*outp == NULL) {
256
0
    *outp = buf;
257
0
    errno = serrno;
258
0
  }
259
0
  return (len);
260
0
}
261
262
int
263
strvisx(char *dst, const char *src, size_t len, int flag)
264
0
{
265
0
  char c;
266
0
  char *start;
267
268
0
  for (start = dst; len > 1; len--) {
269
0
    c = *src;
270
0
    dst = vis(dst, c, flag, *++src);
271
0
  }
272
0
  if (len)
273
0
    dst = vis(dst, *src, flag, '\0');
274
0
  *dst = '\0';
275
0
  return (dst - start);
276
0
}
277
278
#endif
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/compat/vis.h.html b/coverage/latest/report/linux/src/openiked-portable/compat/vis.h.html index 526ccd38c..bc110eeea 100644 --- a/coverage/latest/report/linux/src/openiked-portable/compat/vis.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/compat/vis.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/vis.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $  */
2
/*  $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $  */
3
4
/*-
5
 * Copyright (c) 1990 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)vis.h 5.9 (Berkeley) 4/3/91
33
 */
34
35
/* OPENBSD ORIGINAL: include/vis.h */
36
37
#ifdef HAVE_CONFIG_H
38
#include "includes.h"
39
#endif
40
41
#ifndef _VIS_H_
42
#define _VIS_H_
43
44
#include <sys/types.h>
45
#include <limits.h>
46
47
/*
48
 * to select alternate encoding format
49
 */
50
0
#define VIS_OCTAL 0x01  /* use octal \ddd format */
51
0
#define VIS_CSTYLE  0x02  /* use \[nrft0..] where appropriate */
52
53
/*
54
 * to alter set of characters encoded (default is to encode all
55
 * non-graphic except space, tab, and newline).
56
 */
57
0
#define VIS_SP    0x04  /* also encode space */
58
0
#define VIS_TAB   0x08  /* also encode tab */
59
0
#define VIS_NL    0x10  /* also encode newline */
60
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
61
0
#define VIS_SAFE  0x20  /* only encode "unsafe" characters */
62
0
#define VIS_DQ    0x200  /* backslash-escape double quotes */
63
0
#define VIS_ALL   0x400  /* encode all characters */
64
65
/*
66
 * other
67
 */
68
0
#define VIS_NOSLASH 0x40  /* inhibit printing '\' */
69
0
#define VIS_GLOB  0x100  /* encode glob(3) magics and '#' */
70
71
/*
72
 * unvis return codes
73
 */
74
#define UNVIS_VALID  1  /* character valid */
75
#define UNVIS_VALIDPUSH  2  /* character valid, push back passed char */
76
#define UNVIS_NOCHAR   3  /* valid sequence, no character produced */
77
#define UNVIS_SYNBAD  -1  /* unrecognized escape sequence */
78
#define UNVIS_ERROR -2  /* decoder in unknown state (unrecoverable) */
79
80
/*
81
 * unvis flags
82
 */
83
#define UNVIS_END 1 /* no more characters */
84
85
char  *vis(char *, int, int, int);
86
int strvis(char *, const char *, int);
87
int stravis(char **, const char *, int);
88
int strnvis(char *, const char *, size_t, int)
89
    __attribute__ ((__bounded__(__string__,1,3)));
90
int strvisx(char *, const char *, size_t, int)
91
    __attribute__ ((__bounded__(__string__,1,3)));
92
int strunvis(char *, const char *);
93
int unvis(char *, char, int *, int);
94
ssize_t strnunvis(char *, const char *, size_t)
95
    __attribute__ ((__bounded__(__string__,1,3)));
96
97
#endif /* !_VIS_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/vis.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $  */
2
/*  $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $  */
3
4
/*-
5
 * Copyright (c) 1990 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)vis.h 5.9 (Berkeley) 4/3/91
33
 */
34
35
/* OPENBSD ORIGINAL: include/vis.h */
36
37
#ifdef HAVE_CONFIG_H
38
#include "includes.h"
39
#endif
40
41
#ifndef _VIS_H_
42
#define _VIS_H_
43
44
#include <sys/types.h>
45
#include <limits.h>
46
47
/*
48
 * to select alternate encoding format
49
 */
50
0
#define VIS_OCTAL 0x01  /* use octal \ddd format */
51
0
#define VIS_CSTYLE  0x02  /* use \[nrft0..] where appropriate */
52
53
/*
54
 * to alter set of characters encoded (default is to encode all
55
 * non-graphic except space, tab, and newline).
56
 */
57
0
#define VIS_SP    0x04  /* also encode space */
58
0
#define VIS_TAB   0x08  /* also encode tab */
59
0
#define VIS_NL    0x10  /* also encode newline */
60
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
61
0
#define VIS_SAFE  0x20  /* only encode "unsafe" characters */
62
0
#define VIS_DQ    0x200  /* backslash-escape double quotes */
63
0
#define VIS_ALL   0x400  /* encode all characters */
64
65
/*
66
 * other
67
 */
68
0
#define VIS_NOSLASH 0x40  /* inhibit printing '\' */
69
0
#define VIS_GLOB  0x100  /* encode glob(3) magics and '#' */
70
71
/*
72
 * unvis return codes
73
 */
74
#define UNVIS_VALID  1  /* character valid */
75
#define UNVIS_VALIDPUSH  2  /* character valid, push back passed char */
76
#define UNVIS_NOCHAR   3  /* valid sequence, no character produced */
77
#define UNVIS_SYNBAD  -1  /* unrecognized escape sequence */
78
#define UNVIS_ERROR -2  /* decoder in unknown state (unrecoverable) */
79
80
/*
81
 * unvis flags
82
 */
83
#define UNVIS_END 1 /* no more characters */
84
85
char  *vis(char *, int, int, int);
86
int strvis(char *, const char *, int);
87
int stravis(char **, const char *, int);
88
int strnvis(char *, const char *, size_t, int)
89
    __attribute__ ((__bounded__(__string__,1,3)));
90
int strvisx(char *, const char *, size_t, int)
91
    __attribute__ ((__bounded__(__string__,1,3)));
92
int strunvis(char *, const char *);
93
int unvis(char *, char, int *, int);
94
ssize_t strnunvis(char *, const char *, size_t)
95
    __attribute__ ((__bounded__(__string__,1,3)));
96
97
#endif /* !_VIS_H_ */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/iked.h.html b/coverage/latest/report/linux/src/openiked-portable/iked/iked.h.html index 77fa25cb1..adc6251f3 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/iked.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/iked.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/iked.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: iked.h,v 1.224 2023/08/11 11:24:55 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019-2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/tree.h>
22
#include <sys/queue.h>
23
#include <arpa/inet.h>
24
#include <limits.h>
25
#include <imsg.h>
26
27
#include <openssl/evp.h>
28
29
#include "openbsd-compat.h"
30
31
#include "types.h"
32
#include "dh.h"
33
34
#define MAXIMUM(a,b) (((a)>(b))?(a):(b))
35
#define MINIMUM(a,b) (((a)<(b))?(a):(b))
36
#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
37
38
#ifndef IKED_H
39
#define IKED_H
40
41
/*
42
 * Common IKEv1/IKEv2 header
43
 */
44
45
struct ike_header {
46
  uint64_t   ike_ispi;    /* Initiator cookie */
47
  uint64_t   ike_rspi;    /* Responder cookie */
48
  uint8_t    ike_nextpayload; /* Next payload type */
49
  uint8_t    ike_version;   /* Major/Minor version number */
50
  uint8_t    ike_exchange;    /* Exchange type */
51
  uint8_t    ike_flags;   /* Message options */
52
  uint32_t   ike_msgid;   /* Message identifier */
53
  uint32_t   ike_length;    /* Total message length */
54
} __packed;
55
56
/*
57
 * Common daemon infrastructure, local imsg etc.
58
 */
59
60
struct imsgev {
61
  struct imsgbuf     ibuf;
62
  void      (*handler)(int, short, void *);
63
  struct event     ev;
64
  struct privsep_proc *proc;
65
  void      *data;
66
  short      events;
67
  const char    *name;
68
};
69
70
#define IMSG_SIZE_CHECK(imsg, p) do {       \
71
  if (IMSG_DATA_SIZE(imsg) < sizeof(*p))      \
72
    fatalx("bad length imsg received");   \
73
} while (0)
74
#define IMSG_DATA_SIZE(imsg)  ((imsg)->hdr.len - IMSG_HEADER_SIZE)
75
76
#define IKED_ADDR_EQ(_a, _b)            \
77
  ((_a)->addr_mask == (_b)->addr_mask &&        \
78
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
79
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) == 0)
80
81
#define IKED_ADDR_NEQ(_a, _b)           \
82
  ((_a)->addr_mask != (_b)->addr_mask ||        \
83
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
84
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) != 0)
85
86
/* initially control.h */
87
struct control_sock {
88
  const char  *cs_name;
89
  struct event   cs_ev;
90
  struct event   cs_evt;
91
  int    cs_fd;
92
  int    cs_restricted;
93
  void    *cs_env;
94
95
  TAILQ_ENTRY(control_sock) cs_entry;
96
};
97
TAILQ_HEAD(control_socks, control_sock);
98
99
struct ctl_conn {
100
  TAILQ_ENTRY(ctl_conn)  entry;
101
  uint8_t      flags;
102
#define CTL_CONN_NOTIFY    0x01
103
  struct imsgev    iev;
104
};
105
TAILQ_HEAD(ctl_connlist, ctl_conn);
106
107
extern enum privsep_procid privsep_process;
108
109
/*
110
 * Runtime structures
111
 */
112
113
struct iked_timer {
114
  struct event   tmr_ev;
115
  struct iked *tmr_env;
116
  void    (*tmr_cb)(struct iked *, void *);
117
  void    *tmr_cbarg;
118
};
119
120
struct iked_spi {
121
  uint64_t   spi;
122
  uint8_t    spi_size;
123
  uint8_t    spi_protoid;
124
};
125
126
struct iked_proposal {
127
  uint8_t        prop_id;
128
  uint8_t        prop_protoid;
129
130
  struct iked_spi      prop_localspi;
131
  struct iked_spi      prop_peerspi;
132
133
  struct iked_transform   *prop_xforms;
134
  unsigned int       prop_nxforms;
135
136
  TAILQ_ENTRY(iked_proposal)   prop_entry;
137
};
138
TAILQ_HEAD(iked_proposals, iked_proposal);
139
140
struct iked_addr {
141
  int        addr_af;
142
  struct sockaddr_storage    addr;
143
  uint8_t        addr_mask;
144
  int        addr_net;
145
  in_port_t      addr_port;
146
};
147
148
struct iked_ts {
149
  struct iked_addr     ts_addr;
150
  uint8_t        ts_ipproto;
151
  TAILQ_ENTRY(iked_ts)     ts_entry;
152
};
153
TAILQ_HEAD(iked_tss, iked_ts);
154
155
struct iked_flow {
156
  struct iked_addr     flow_src;
157
  struct iked_addr     flow_dst;
158
  unsigned int       flow_dir;  /* in/out */
159
  int        flow_rdomain;
160
  struct iked_addr     flow_prenat;
161
  int        flow_fixed;
162
163
  unsigned int       flow_loaded; /* pfkey done */
164
165
  uint8_t        flow_saproto;
166
  uint8_t        flow_ipproto;
167
168
  struct iked_addr    *flow_local;  /* outer source */
169
  struct iked_addr    *flow_peer; /* outer dest */
170
  struct iked_sa      *flow_ikesa;  /* parent SA */
171
172
  int        flow_transport;
173
174
  RB_ENTRY(iked_flow)    flow_node;
175
  TAILQ_ENTRY(iked_flow)     flow_entry;
176
};
177
RB_HEAD(iked_flows, iked_flow);
178
TAILQ_HEAD(iked_saflows, iked_flow);
179
180
struct iked_childsa {
181
  uint8_t        csa_saproto; /* IPsec protocol */
182
  unsigned int       csa_dir; /* in/out */
183
184
  uint64_t       csa_peerspi; /* peer relation */
185
  uint8_t        csa_loaded;  /* pfkey done */
186
  uint8_t        csa_rekey; /* will be deleted */
187
  uint8_t        csa_allocated; /* from the kernel */
188
  uint8_t        csa_persistent;/* do not rekey */
189
  uint8_t        csa_esn; /* use ESN */
190
  uint8_t        csa_transport; /* transport mode */
191
192
  struct iked_spi      csa_spi;
193
194
  struct ibuf     *csa_encrkey; /* encryption key */
195
  uint16_t       csa_encrid;  /* encryption xform id */
196
197
  struct ibuf     *csa_integrkey; /* auth key */
198
  uint16_t       csa_integrid;  /* auth xform id */
199
200
  struct iked_addr    *csa_local; /* outer source */
201
  struct iked_addr    *csa_peer;  /* outer dest */
202
  struct iked_sa      *csa_ikesa; /* parent SA */
203
204
  struct iked_childsa   *csa_peersa;  /* peer */
205
206
  struct iked_childsa   *csa_bundled; /* IPCOMP */
207
208
  uint16_t       csa_pfsgrpid;  /* pfs group id */
209
210
  RB_ENTRY(iked_childsa)     csa_node;
211
  TAILQ_ENTRY(iked_childsa)  csa_entry;
212
};
213
RB_HEAD(iked_activesas, iked_childsa);
214
TAILQ_HEAD(iked_childsas, iked_childsa);
215
216
217
struct iked_static_id {
218
  uint8_t   id_type;
219
  uint8_t   id_length;
220
  uint8_t   id_offset;
221
  uint8_t   id_data[IKED_ID_SIZE];
222
};
223
224
struct iked_auth {
225
  uint8_t   auth_method;
226
  uint8_t   auth_eap;     /* optional EAP */
227
  uint8_t   auth_length;      /* zero if EAP */
228
  uint8_t   auth_data[IKED_PSK_SIZE];
229
};
230
231
struct iked_cfg {
232
  uint8_t        cfg_action;
233
  uint16_t       cfg_type;
234
  union {
235
    struct iked_addr   address;
236
  } cfg;
237
};
238
239
TAILQ_HEAD(iked_sapeers, iked_sa);
240
241
struct iked_lifetime {
242
  uint64_t       lt_bytes;
243
  uint64_t       lt_seconds;
244
};
245
246
struct iked_policy {
247
  unsigned int       pol_id;
248
  char         pol_name[IKED_ID_SIZE];
249
  unsigned int       pol_iface;
250
251
#define IKED_SKIP_FLAGS      0
252
#define IKED_SKIP_AF       1
253
#define IKED_SKIP_SRC_ADDR     2
254
#define IKED_SKIP_DST_ADDR     3
255
#define IKED_SKIP_COUNT      4
256
  struct iked_policy    *pol_skip[IKED_SKIP_COUNT];
257
258
  uint8_t        pol_flags;
259
#define IKED_POLICY_PASSIVE    0x00
260
#define IKED_POLICY_DEFAULT    0x01
261
#define IKED_POLICY_ACTIVE     0x02
262
#define IKED_POLICY_REFCNT     0x04
263
#define IKED_POLICY_QUICK    0x08
264
#define IKED_POLICY_SKIP     0x10
265
#define IKED_POLICY_IPCOMP     0x20
266
0
#define IKED_POLICY_TRANSPORT    0x40
267
#define IKED_POLICY_ROUTING    0x80
268
269
  int        pol_refcnt;
270
271
  uint8_t        pol_certreqtype;
272
273
  int        pol_af;
274
  int        pol_rdomain;
275
  uint8_t        pol_saproto;
276
  unsigned int       pol_ipproto[IKED_IPPROTO_MAX];
277
  unsigned int       pol_nipproto;
278
279
  struct iked_addr     pol_peer;
280
  struct iked_static_id    pol_peerid;
281
  uint32_t       pol_peerdh;
282
283
  struct iked_addr     pol_local;
284
  struct iked_static_id    pol_localid;
285
286
  struct iked_auth     pol_auth;
287
288
  char         pol_tag[IKED_TAG_SIZE];
289
  unsigned int       pol_tap;
290
291
  struct iked_proposals    pol_proposals;
292
  size_t         pol_nproposals;
293
294
  struct iked_flows    pol_flows;
295
  size_t         pol_nflows;
296
  struct iked_tss      pol_tssrc; /* Traffic Selectors Initiator*/
297
  size_t         pol_tssrc_count;
298
  struct iked_tss      pol_tsdst; /* Traffic Selectors Responder*/
299
  size_t         pol_tsdst_count;
300
301
  struct iked_cfg      pol_cfg[IKED_CFG_MAX];
302
  unsigned int       pol_ncfg;
303
304
  uint32_t       pol_rekey; /* ike SA lifetime */
305
  struct iked_lifetime     pol_lifetime;  /* child SA lifetime */
306
307
  struct iked_sapeers    pol_sapeers;
308
309
  TAILQ_ENTRY(iked_policy)   pol_entry;
310
};
311
TAILQ_HEAD(iked_policies, iked_policy);
312
313
struct iked_hash {
314
  uint8_t    hash_type; /* PRF or INTEGR */
315
  uint16_t   hash_id; /* IKE PRF/INTEGR hash id */
316
  const void  *hash_priv; /* Identifying the hash alg */
317
  void    *hash_ctx;  /* Context of the current invocation */
318
  int    hash_fixedkey; /* Requires fixed key length */
319
  struct ibuf *hash_key;  /* MAC key derived from key seed */
320
  size_t     hash_length; /* Output length */
321
  size_t     hash_trunc;  /* Truncate the output length */
322
  struct iked_hash *hash_prf; /* PRF pointer */
323
  int    hash_isaead;
324
};
325
326
struct iked_cipher {
327
  uint8_t    encr_type; /* ENCR */
328
  uint16_t   encr_id; /* IKE ENCR hash id */
329
  const void  *encr_priv; /* Identifying the hash alg */
330
  void    *encr_ctx;  /* Context of the current invocation */
331
  int    encr_fixedkey; /* Requires fixed key length */
332
  struct ibuf *encr_key;  /* MAC key derived from key seed */
333
  struct ibuf *encr_iv; /* Initialization Vector */
334
  uint64_t   encr_civ;  /* Counter IV for GCM */
335
  size_t     encr_ivlength; /* IV length */
336
  size_t     encr_length; /* Block length */
337
  size_t     encr_saltlength; /* IV salt length */
338
  uint16_t   encr_authid; /* ID of associated authentication */
339
};
340
341
struct iked_dsa {
342
  uint8_t    dsa_method;  /* AUTH method */
343
  const void  *dsa_priv;  /* PRF or signature hash function */
344
  void    *dsa_ctx; /* PRF or signature hash ctx */
345
  struct ibuf *dsa_keydata; /* public, private or shared key */
346
  void    *dsa_key; /* parsed public or private key */
347
  int    dsa_hmac;  /* HMAC or public/private key */
348
  int    dsa_sign;  /* Sign or verify operation */
349
  uint32_t   dsa_flags; /* State flags */
350
};
351
352
struct iked_id {
353
  uint8_t    id_type;
354
  uint8_t    id_offset;
355
  struct ibuf *id_buf;
356
};
357
358
#define IKED_REQ_CERT   0x0001  /* get local certificate (if required) */
359
#define IKED_REQ_CERTVALID  0x0002  /* validated the peer cert */
360
#define IKED_REQ_CERTREQ  0x0004  /* CERTREQ has been received */
361
#define IKED_REQ_AUTH   0x0008  /* AUTH payload */
362
#define IKED_REQ_AUTHVALID  0x0010  /* AUTH payload has been verified */
363
#define IKED_REQ_SA   0x0020  /* SA available */
364
#define IKED_REQ_EAPVALID 0x0040  /* EAP payload has been verified */
365
#define IKED_REQ_CHILDSA  0x0080  /* Child SA initiated */
366
#define IKED_REQ_INF    0x0100  /* Informational exchange initiated */
367
368
#define IKED_REQ_BITS \
369
    "\20\01CERT\02CERTVALID\03CERTREQ\04AUTH\05AUTHVALID\06SA\07EAPVALID" \
370
    "\10CHILDSA\11INF"
371
372
TAILQ_HEAD(iked_msgqueue, iked_msg_retransmit);
373
TAILQ_HEAD(iked_msg_fragqueue, iked_message);
374
375
struct iked_sahdr {
376
  uint64_t       sh_ispi; /* Initiator SPI */
377
  uint64_t       sh_rspi; /* Responder SPI */
378
  unsigned int       sh_initiator;  /* Is initiator? */
379
} __packed;
380
381
struct iked_kex {
382
  struct ibuf     *kex_inonce;  /* Ni */
383
  struct ibuf     *kex_rnonce;  /* Nr */
384
385
  struct dh_group     *kex_dhgroup; /* DH group */
386
  struct ibuf     *kex_dhiexchange;
387
  struct ibuf     *kex_dhrexchange;
388
  struct ibuf     *kex_dhpeer;  /* pointer to i or r */
389
};
390
391
struct iked_frag_entry {
392
  uint8_t *frag_data;
393
  size_t   frag_size;
394
};
395
396
struct iked_frag {
397
  struct iked_frag_entry  **frag_arr; /* list of fragment buffers */
398
  size_t        frag_count; /* number of fragments received */
399
0
#define IKED_FRAG_TOTAL_MAX   111    /* upper limit (64kB / 576B) */
400
  size_t        frag_total; /* total numbe of fragments */
401
  size_t        frag_total_size;
402
  uint8_t       frag_nextpayload;
403
404
};
405
406
struct iked_ipcomp {
407
  uint16_t       ic_cpi_out;  /* outgoing CPI */
408
  uint16_t       ic_cpi_in; /* incoming CPI */
409
  uint8_t        ic_transform;  /* transform */
410
};
411
412
struct iked_sa {
413
  struct iked_sahdr    sa_hdr;
414
  uint32_t       sa_msgid;  /* Last request rcvd */
415
  int        sa_msgid_set;  /* msgid initialized */
416
  uint32_t       sa_msgid_current;  /* Current requested rcvd */
417
  uint32_t       sa_reqid;  /* Next request sent */
418
419
  int        sa_type;
420
#define IKED_SATYPE_LOOKUP     0    /* Used for lookup */
421
#define IKED_SATYPE_LOCAL    1    /* Local SA */
422
423
  struct iked_addr     sa_peer;
424
  struct iked_addr     sa_peer_loaded;/* MOBIKE */
425
  struct iked_addr     sa_local;
426
  int        sa_fd;
427
428
  struct iked_frag     sa_fragments;
429
430
  int        sa_natt; /* for IKE messages */
431
  int        sa_udpencap; /* for pfkey */
432
  int        sa_usekeepalive;/* NAT-T keepalive */
433
434
  int        sa_state;
435
  unsigned int       sa_stateflags;
436
  unsigned int       sa_stateinit;  /* SA_INIT */
437
  unsigned int       sa_statevalid; /* IKE_AUTH */
438
439
  int        sa_cp;   /* XXX */
440
  struct iked_addr    *sa_cp_addr;  /* requested address */
441
  struct iked_addr    *sa_cp_addr6; /* requested address */
442
  struct iked_addr    *sa_cp_dns; /* requested dns */
443
444
  struct iked_policy    *sa_policy;
445
  struct timeval       sa_timecreated;
446
  struct timeval       sa_timeused;
447
448
  char        *sa_tag;
449
  const char      *sa_reason; /* reason for close */
450
451
  struct iked_kex      sa_kex;
452
/* XXX compat defines until everything is converted */
453
#define sa_inonce   sa_kex.kex_inonce
454
#define sa_rnonce   sa_kex.kex_rnonce
455
#define sa_dhgroup    sa_kex.kex_dhgroup
456
#define sa_dhiexchange    sa_kex.kex_dhiexchange
457
#define sa_dhrexchange    sa_kex.kex_dhrexchange
458
#define sa_dhpeer   sa_kex.kex_dhpeer
459
460
  struct iked_hash    *sa_prf;  /* PRF alg */
461
  struct iked_hash    *sa_integr; /* integrity alg */
462
  struct iked_cipher    *sa_encr; /* encryption alg */
463
464
  struct ibuf     *sa_key_d;  /* SK_d */
465
  struct ibuf     *sa_key_iauth;  /* SK_ai */
466
  struct ibuf     *sa_key_rauth;  /* SK_ar */
467
  struct ibuf     *sa_key_iencr;  /* SK_ei */
468
  struct ibuf     *sa_key_rencr;  /* SK_er */
469
  struct ibuf     *sa_key_iprf; /* SK_pi */
470
  struct ibuf     *sa_key_rprf; /* SK_pr */
471
472
  struct ibuf     *sa_1stmsg; /* for initiator AUTH */
473
  struct ibuf     *sa_2ndmsg; /* for responder AUTH */
474
  struct iked_id       sa_localauth;  /* local AUTH message */
475
  struct iked_id       sa_peerauth; /* peer AUTH message */
476
  int        sa_sigsha2;  /* use SHA2 for signatures */
477
108k
#define IKED_SCERT_MAX  3 /* max # of supplemental cert payloads */
478
479
  struct iked_id       sa_iid;  /* initiator id */
480
  struct iked_id       sa_rid;  /* responder id */
481
  struct iked_id       sa_icert;  /* initiator cert */
482
  struct iked_id       sa_rcert;  /* responder cert */
483
  struct iked_id       sa_scert[IKED_SCERT_MAX]; /* supplemental certs */
484
#define IKESA_SRCID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_iid : &(x)->sa_rid)
485
#define IKESA_DSTID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_rid : &(x)->sa_iid)
486
487
  char        *sa_eapid;  /* EAP identity */
488
  struct iked_id       sa_eap;  /* EAP challenge */
489
  struct ibuf     *sa_eapmsk; /* EAK session key */
490
491
  struct iked_proposals    sa_proposals;  /* SA proposals */
492
  struct iked_childsas     sa_childsas; /* IPsec Child SAs */
493
  struct iked_saflows    sa_flows;  /* IPsec flows */
494
495
  struct iked_sa      *sa_nexti;  /* initiated IKE SA */
496
  struct iked_sa      *sa_previ;  /* matching back pointer */
497
  struct iked_sa      *sa_nextr;  /* simultaneous rekey */
498
  struct iked_sa      *sa_prevr;  /* matching back pointer */
499
  uint64_t       sa_rekeyspi; /* peerspi CSA rekey */
500
  struct ibuf     *sa_simult; /* simultaneous rekey */
501
502
  struct iked_ipcomp     sa_ipcompi;  /* IPcomp initator */
503
  struct iked_ipcomp     sa_ipcompr;  /* IPcomp responder */
504
505
  int        sa_mobike; /* MOBIKE */
506
  int        sa_frag; /* fragmentation */
507
508
  int        sa_use_transport_mode; /* peer requested */
509
  int        sa_used_transport_mode; /* we enabled */
510
511
  struct iked_timer    sa_timer;  /* SA timeouts */
512
#define IKED_IKE_SA_EXCHANGE_TIMEOUT   300    /* 5 minutes */
513
#define IKED_IKE_SA_REKEY_TIMEOUT  120    /* 2 minutes */
514
#define IKED_IKE_SA_DELETE_TIMEOUT   120    /* 2 minutes */
515
#define IKED_IKE_SA_ALIVE_TIMEOUT  60   /* 1 minute */
516
517
  struct iked_timer    sa_keepalive;  /* keepalive timer */
518
#define IKED_IKE_SA_KEEPALIVE_TIMEOUT  20
519
520
  struct iked_timer    sa_rekey;  /* rekey timeout */
521
  int        sa_tmpfail;
522
523
  struct iked_msgqueue     sa_requests; /* request queue */
524
#define IKED_RETRANSMIT_TIMEOUT    2    /* 2 seconds */
525
526
  struct iked_msgqueue     sa_responses;  /* response queue */
527
#define IKED_RESPONSE_TIMEOUT    120    /* 2 minutes */
528
529
  TAILQ_ENTRY(iked_sa)     sa_peer_entry;
530
  RB_ENTRY(iked_sa)    sa_entry;  /* all SAs */
531
532
  RB_ENTRY(iked_sa)    sa_dstid_entry;  /* SAs by DSTID */
533
  int        sa_dstid_entry_valid;    /* sa_dstid_entry valid */
534
535
  struct iked_addr    *sa_addrpool; /* address from pool */
536
  RB_ENTRY(iked_sa)    sa_addrpool_entry; /* pool entries */
537
538
  struct iked_addr    *sa_addrpool6;  /* address from pool */
539
  RB_ENTRY(iked_sa)    sa_addrpool6_entry;  /* pool entries */
540
  time_t         sa_last_recvd;
541
#define IKED_IKE_SA_LAST_RECVD_TIMEOUT   300    /* 5 minutes */
542
};
543
RB_HEAD(iked_sas, iked_sa);
544
RB_HEAD(iked_dstid_sas, iked_sa);
545
RB_HEAD(iked_addrpool, iked_sa);
546
RB_HEAD(iked_addrpool6, iked_sa);
547
548
/* stats */
549
550
struct iked_stats {
551
  uint64_t  ikes_sa_created;
552
  uint64_t  ikes_sa_established_total;
553
  uint64_t  ikes_sa_established_current;  /* gauge */
554
  uint64_t  ikes_sa_established_failures;
555
  uint64_t  ikes_sa_proposals_negotiate_failures;
556
  uint64_t  ikes_sa_rekeyed;
557
  uint64_t  ikes_sa_removed;
558
  uint64_t  ikes_csa_created;
559
  uint64_t  ikes_csa_removed;
560
  uint64_t  ikes_msg_sent;
561
  uint64_t  ikes_msg_send_failures;
562
  uint64_t  ikes_msg_rcvd;
563
  uint64_t  ikes_msg_rcvd_busy;
564
  uint64_t  ikes_msg_rcvd_dropped;
565
  uint64_t  ikes_retransmit_request;
566
  uint64_t  ikes_retransmit_response;
567
  uint64_t  ikes_retransmit_limit;
568
  uint64_t  ikes_frag_sent;
569
  uint64_t  ikes_frag_send_failures;
570
  uint64_t  ikes_frag_rcvd;
571
  uint64_t  ikes_frag_rcvd_drop;
572
  uint64_t  ikes_frag_reass_ok;
573
  uint64_t  ikes_frag_reass_drop;
574
  uint64_t  ikes_update_addresses_sent;
575
  uint64_t  ikes_dpd_sent;
576
  uint64_t  ikes_keepalive_sent;
577
};
578
579
0
#define ikestat_add(env, c, n)  do { env->sc_stats.c += (n); } while(0)
580
0
#define ikestat_inc(env, c) ikestat_add(env, c, 1)
581
#define ikestat_dec(env, c) ikestat_add(env, c, -1)
582
583
struct iked_certreq {
584
  struct ibuf     *cr_data;
585
  uint8_t        cr_type;
586
  SIMPLEQ_ENTRY(iked_certreq)  cr_entry;
587
};
588
SIMPLEQ_HEAD(iked_certreqs, iked_certreq);
589
590
#define EAP_STATE_IDENTITY    (1)
591
#define EAP_STATE_MSCHAPV2_CHALLENGE  (2)
592
#define EAP_STATE_MSCHAPV2_SUCCESS  (3)
593
#define EAP_STATE_SUCCESS   (4)
594
595
struct eap_msg {
596
  char    *eam_identity;
597
  char    *eam_user;
598
  int    eam_type;
599
  uint8_t    eam_id;
600
  uint8_t    eam_msrid;
601
  int    eam_success;
602
  int    eam_found;
603
  int    eam_response;
604
  uint8_t    eam_challenge[16];
605
  uint8_t    eam_ntresponse[24];
606
  uint32_t   eam_state;
607
};
608
609
struct iked_message {
610
  struct ibuf   *msg_data;
611
  size_t       msg_offset;
612
613
  struct sockaddr_storage  msg_local;
614
  socklen_t    msg_locallen;
615
616
  struct sockaddr_storage  msg_peer;
617
  socklen_t    msg_peerlen;
618
619
  struct iked_socket  *msg_sock;
620
621
  int      msg_fd;
622
  int      msg_response;
623
  int      msg_responded;
624
  int      msg_valid;
625
  int      msg_natt;
626
  int      msg_natt_rcvd;
627
  int      msg_nat_detected;
628
  int      msg_error;
629
  int      msg_e;
630
  struct iked_message *msg_parent;
631
632
  /* Associated policy and SA */
633
  struct iked_policy  *msg_policy;
634
  struct iked_sa    *msg_sa;
635
636
  uint32_t     msg_msgid;
637
  uint8_t      msg_exchange;
638
639
  /* Parsed information */
640
  struct iked_proposals  msg_proposals;
641
  struct iked_certreqs   msg_certreqs;
642
  struct iked_spi    msg_rekey;
643
  struct ibuf   *msg_nonce; /* dh NONCE */
644
  uint16_t     msg_dhgroup; /* dh group */
645
  struct ibuf   *msg_ke;  /* dh key exchange */
646
  struct iked_id     msg_auth;  /* AUTH payload */
647
  struct iked_id     msg_peerid;
648
  struct iked_id     msg_localid;
649
  struct iked_id     msg_cert;
650
  struct iked_id     msg_scert[IKED_SCERT_MAX]; /* supplemental certs */
651
  struct ibuf   *msg_cookie;
652
  uint16_t     msg_group;
653
  uint16_t     msg_cpi;
654
  uint8_t      msg_transform;
655
  uint16_t     msg_flags;
656
  struct eap_msg     msg_eap;
657
  size_t       msg_del_spisize;
658
  size_t       msg_del_cnt;
659
  struct ibuf   *msg_del_buf;
660
  int      msg_del_protoid;
661
  int      msg_cp;
662
  struct iked_addr  *msg_cp_addr; /* requested address */
663
  struct iked_addr  *msg_cp_addr6;  /* requested address */
664
  struct iked_addr  *msg_cp_dns;  /* requested dns */
665
666
  /* MOBIKE */
667
  int      msg_update_sa_addresses;
668
  struct ibuf   *msg_cookie2;
669
670
  /* Parse stack */
671
  struct iked_proposal  *msg_prop;
672
  uint16_t     msg_attrlength;
673
674
  /* Retransmit queue */
675
  TAILQ_ENTRY(iked_message)
676
         msg_entry;
677
};
678
679
struct iked_msg_retransmit {
680
  struct iked_msg_fragqueue       mrt_frags;
681
  TAILQ_ENTRY(iked_msg_retransmit)      mrt_entry;
682
  struct iked_timer         mrt_timer;
683
  int             mrt_tries;
684
#define IKED_RETRANSMIT_TRIES  5    /* try 5 times */
685
};
686
687
3.04k
#define IKED_MSG_NAT_SRC_IP       0x01
688
19.5k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
136
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
73
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
241
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
131
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
128
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
239
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
348
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
36
#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN   0x0400
701
702
703
struct iked_user {
704
  char       usr_name[LOGIN_NAME_MAX];
705
  char       usr_pass[IKED_PASSWORD_SIZE];
706
  RB_ENTRY(iked_user)  usr_entry;
707
};
708
RB_HEAD(iked_users, iked_user);
709
710
struct privsep_pipes {
711
  int       *pp_pipes[PROC_MAX];
712
};
713
714
struct privsep {
715
  struct privsep_pipes    *ps_pipes[PROC_MAX];
716
  struct privsep_pipes    *ps_pp;
717
718
  struct imsgev     *ps_ievs[PROC_MAX];
719
  const char      *ps_title[PROC_MAX];
720
  pid_t        ps_pid[PROC_MAX];
721
  struct passwd     *ps_pw;
722
  int        ps_noaction;
723
724
  struct control_sock    ps_csock;
725
  struct control_socks     ps_rcsocks;
726
727
  unsigned int       ps_instances[PROC_MAX];
728
  unsigned int       ps_ninstances;
729
  unsigned int       ps_instance;
730
731
  /* Event and signal handlers */
732
  struct event       ps_evsigint;
733
  struct event       ps_evsigterm;
734
  struct event       ps_evsigchld;
735
  struct event       ps_evsighup;
736
  struct event       ps_evsigpipe;
737
  struct event       ps_evsigusr1;
738
739
  struct iked     *ps_env;
740
};
741
742
struct privsep_proc {
743
  const char    *p_title;
744
  enum privsep_procid  p_id;
745
  int     (*p_cb)(int, struct privsep_proc *,
746
            struct imsg *);
747
  void      (*p_init)(struct privsep *,
748
            struct privsep_proc *);
749
  const char    *p_chroot;
750
  struct passwd   *p_pw;
751
  struct privsep    *p_ps;
752
  void      (*p_shutdown)(void);
753
};
754
755
struct privsep_fd {
756
  enum privsep_procid    pf_procid;
757
  unsigned int       pf_instance;
758
};
759
760
#define PROC_PARENT_SOCK_FILENO 3
761
#define PROC_MAX_INSTANCES      32
762
763
struct iked_ocsp_entry {
764
  TAILQ_ENTRY(iked_ocsp_entry) ioe_entry; /* next request */
765
  void      *ioe_ocsp;  /* private ocsp request data */
766
};
767
TAILQ_HEAD(iked_ocsp_requests, iked_ocsp_entry);
768
769
/*
770
 * Daemon configuration
771
 */
772
773
enum natt_mode {
774
  NATT_DEFAULT, /* send/recv with both :500 and NAT-T port */
775
  NATT_DISABLE, /* send/recv with only :500 */
776
  NATT_FORCE, /* send/recv with only NAT-T port */
777
};
778
779
struct iked_static {
780
  uint64_t     st_alive_timeout;
781
  int      st_enforcesingleikesa;
782
  uint8_t      st_frag; /* fragmentation */
783
  uint8_t      st_mobike; /* MOBIKE */
784
  in_port_t    st_nattport;
785
  int      st_stickyaddress; /* addr per DSTID  */
786
  int      st_vendorid;
787
};
788
789
struct iked {
790
  char         sc_conffile[PATH_MAX];
791
792
  uint32_t       sc_opts;
793
  enum natt_mode       sc_nattmode;
794
  uint8_t        sc_passive;
795
  uint8_t        sc_decoupled;
796
797
  struct iked_static     sc_static;
798
799
#define sc_alive_timeout  sc_static.st_alive_timeout
800
#define sc_enforcesingleikesa sc_static.st_enforcesingleikesa
801
#define sc_frag     sc_static.st_frag
802
#define sc_mobike   sc_static.st_mobike
803
#define sc_nattport   sc_static.st_nattport
804
#define sc_stickyaddress  sc_static.st_stickyaddress
805
#define sc_vendorid   sc_static.st_vendorid
806
807
  struct iked_policies     sc_policies;
808
  struct iked_policy    *sc_defaultcon;
809
810
  struct iked_sas      sc_sas;
811
  struct iked_dstid_sas    sc_dstid_sas;
812
  struct iked_activesas    sc_activesas;
813
  struct iked_flows    sc_activeflows;
814
  struct iked_users    sc_users;
815
816
  struct iked_stats    sc_stats;
817
818
  void        *sc_priv; /* per-process */
819
820
  int        sc_pfkey;  /* ike process */
821
  struct event       sc_pfkeyev;
822
  struct event       sc_routeev;
823
  uint8_t        sc_certreqtype;
824
  struct ibuf     *sc_certreq;
825
  void        *sc_vroute;
826
827
  struct iked_socket    *sc_sock4[2];
828
  struct iked_socket    *sc_sock6[2];
829
830
  struct iked_timer    sc_inittmr;
831
#define IKED_INITIATOR_INITIAL     2
832
#define IKED_INITIATOR_INTERVAL    60
833
834
  struct privsep       sc_ps;
835
836
  struct iked_ocsp_requests  sc_ocsp;
837
  char        *sc_ocsp_url;
838
  long         sc_ocsp_tolerate;
839
  long         sc_ocsp_maxage;
840
841
  struct iked_addrpool     sc_addrpool;
842
  struct iked_addrpool6    sc_addrpool6;
843
844
  int        sc_cert_partial_chain;
845
#ifdef WITH_APPARMOR
846
  int        sc_apparmor;
847
#endif
848
};
849
850
struct iked_socket {
851
  int      sock_fd;
852
  struct event     sock_ev;
853
  struct iked   *sock_env;
854
  struct sockaddr_storage  sock_addr;
855
};
856
857
struct ipsec_xf {
858
  const char  *name;
859
  unsigned int   id;
860
  unsigned int   length;
861
  unsigned int   keylength;
862
  unsigned int   nonce;
863
  unsigned int   noauth;
864
};
865
866
struct ipsec_transforms {
867
  const struct ipsec_xf **authxf;
868
  unsigned int      nauthxf;
869
  const struct ipsec_xf **prfxf;
870
  unsigned int      nprfxf;
871
  const struct ipsec_xf **encxf;
872
  unsigned int      nencxf;
873
  const struct ipsec_xf **groupxf;
874
  unsigned int      ngroupxf;
875
  const struct ipsec_xf **esnxf;
876
  unsigned int      nesnxf;
877
};
878
879
struct ipsec_mode {
880
  struct ipsec_transforms **xfs;
881
  unsigned int      nxfs;
882
};
883
884
/* iked.c */
885
void   parent_reload(struct iked *, int, const char *);
886
887
extern struct iked  *iked_env;
888
889
/* control.c */
890
void   control(struct privsep *, struct privsep_proc *);
891
int  control_init(struct privsep *, struct control_sock *);
892
int  control_listen(struct control_sock *);
893
894
/* config.c */
895
struct iked_policy *
896
   config_new_policy(struct iked *);
897
void   config_free_kex(struct iked_kex *);
898
void   config_free_fragments(struct iked_frag *);
899
void   config_free_sa(struct iked *, struct iked_sa *);
900
struct iked_sa *
901
   config_new_sa(struct iked *, int);
902
struct iked_user *
903
   config_new_user(struct iked *, struct iked_user *);
904
uint64_t
905
   config_getspi(void);
906
struct iked_transform *
907
   config_findtransform(struct iked_proposals *, uint8_t, unsigned int);
908
struct iked_transform *
909
   config_findtransform_ext(struct iked_proposals *, uint8_t,int, unsigned int);
910
void   config_free_policy(struct iked *, struct iked_policy *);
911
struct iked_proposal *
912
   config_add_proposal(struct iked_proposals *, unsigned int,
913
      unsigned int);
914
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
915
void   config_free_proposals(struct iked_proposals *, unsigned int);
916
void   config_free_flows(struct iked *, struct iked_flows *);
917
void   config_free_childsas(struct iked *, struct iked_childsas *,
918
      struct iked_spi *, struct iked_spi *);
919
int  config_add_transform(struct iked_proposal *,
920
      unsigned int, unsigned int, unsigned int, unsigned int);
921
int  config_setcoupled(struct iked *, unsigned int);
922
int  config_getcoupled(struct iked *, unsigned int);
923
int  config_setmode(struct iked *, unsigned int);
924
int  config_getmode(struct iked *, unsigned int);
925
int  config_setreset(struct iked *, unsigned int, enum privsep_procid);
926
int  config_getreset(struct iked *, struct imsg *);
927
int  config_doreset(struct iked *, unsigned int);
928
int  config_setpolicy(struct iked *, struct iked_policy *,
929
      enum privsep_procid);
930
int  config_getpolicy(struct iked *, struct imsg *);
931
int  config_setflow(struct iked *, struct iked_policy *,
932
      enum privsep_procid);
933
int  config_getflow(struct iked *, struct imsg *);
934
int  config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t,
935
      enum privsep_procid, int);
936
int  config_getsocket(struct iked *env, struct imsg *,
937
      void (*cb)(int, short, void *));
938
int  config_setpfkey(struct iked *);
939
int  config_getpfkey(struct iked *, struct imsg *);
940
int  config_setuser(struct iked *, struct iked_user *, enum privsep_procid);
941
int  config_getuser(struct iked *, struct imsg *);
942
int  config_setcompile(struct iked *, enum privsep_procid);
943
int  config_getcompile(struct iked *);
944
int  config_setocsp(struct iked *);
945
int  config_getocsp(struct iked *, struct imsg *);
946
int  config_setkeys(struct iked *);
947
int  config_getkey(struct iked *, struct imsg *);
948
int  config_setstatic(struct iked *);
949
int  config_getstatic(struct iked *, struct imsg *);
950
int  config_setcertpartialchain(struct iked *);
951
int  config_getcertpartialchain(struct iked *, struct imsg *);
952
953
/* policy.c */
954
void   policy_init(struct iked *);
955
int  policy_lookup(struct iked *, struct iked_message *,
956
      struct iked_proposals *, struct iked_flows *, int);
957
int  policy_lookup_sa(struct iked *, struct iked_sa *);
958
struct iked_policy *
959
   policy_test(struct iked *, struct iked_policy *);
960
int  policy_generate_ts(struct iked_policy *);
961
void   policy_calc_skip_steps(struct iked_policies *);
962
void   policy_ref(struct iked *, struct iked_policy *);
963
void   policy_unref(struct iked *, struct iked_policy *);
964
void   sa_state(struct iked *, struct iked_sa *, int);
965
void   sa_stateflags(struct iked_sa *, unsigned int);
966
int  sa_stateok(const struct iked_sa *, int);
967
struct iked_sa *
968
   sa_new(struct iked *, uint64_t, uint64_t, unsigned int,
969
      struct iked_policy *);
970
void   sa_free(struct iked *, struct iked_sa *);
971
void   sa_free_flows(struct iked *, struct iked_saflows *);
972
int  sa_configure_iface(struct iked *, struct iked_sa *, int);
973
int  sa_address(struct iked_sa *, struct iked_addr *, struct sockaddr *);
974
void   childsa_free(struct iked_childsa *);
975
struct iked_childsa *
976
   childsa_lookup(struct iked_sa *, uint64_t, uint8_t);
977
void   flow_free(struct iked_flow *);
978
int  flow_equal(struct iked_flow *, struct iked_flow *);
979
struct iked_sa *
980
   sa_lookup(struct iked *, uint64_t, uint64_t, unsigned int);
981
struct iked_user *
982
   user_lookup(struct iked *, const char *);
983
struct iked_sa *
984
   sa_dstid_lookup(struct iked *, struct iked_sa *);
985
struct iked_sa *
986
   sa_dstid_insert(struct iked *, struct iked_sa *);
987
void   sa_dstid_remove(struct iked *, struct iked_sa *);
988
int  proposals_negotiate(struct iked_proposals *, struct iked_proposals *,
989
      struct iked_proposals *, int, int);
990
RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
991
RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
992
RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
993
RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
994
RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
995
RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
996
RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
997
998
/* crypto.c */
999
struct iked_hash *
1000
   hash_new(uint8_t, uint16_t);
1001
struct ibuf *
1002
   hash_setkey(struct iked_hash *, void *, size_t);
1003
void   hash_free(struct iked_hash *);
1004
void   hash_init(struct iked_hash *);
1005
void   hash_update(struct iked_hash *, void *, size_t);
1006
void   hash_final(struct iked_hash *, void *, size_t *);
1007
size_t   hash_keylength(struct iked_hash *);
1008
size_t   hash_length(struct iked_hash *);
1009
1010
struct iked_cipher *
1011
   cipher_new(uint8_t, uint16_t, uint16_t);
1012
struct ibuf *
1013
   cipher_setkey(struct iked_cipher *, const void *, size_t);
1014
struct ibuf *
1015
   cipher_setiv(struct iked_cipher *, const void *, size_t);
1016
int  cipher_settag(struct iked_cipher *, uint8_t *, size_t);
1017
int  cipher_gettag(struct iked_cipher *, uint8_t *, size_t);
1018
void   cipher_free(struct iked_cipher *);
1019
int  cipher_init(struct iked_cipher *, int);
1020
int  cipher_init_encrypt(struct iked_cipher *);
1021
int  cipher_init_decrypt(struct iked_cipher *);
1022
void   cipher_aad(struct iked_cipher *, const void *, size_t, size_t *);
1023
int  cipher_update(struct iked_cipher *, const void *, size_t, void *, size_t *);
1024
int  cipher_final(struct iked_cipher *);
1025
size_t   cipher_length(struct iked_cipher *);
1026
size_t   cipher_keylength(struct iked_cipher *);
1027
size_t   cipher_ivlength(struct iked_cipher *);
1028
size_t   cipher_outlength(struct iked_cipher *, size_t);
1029
1030
struct iked_dsa *
1031
   dsa_new(uint8_t, struct iked_hash *, int);
1032
struct iked_dsa *
1033
   dsa_sign_new(uint8_t, struct iked_hash *);
1034
struct iked_dsa *
1035
   dsa_verify_new(uint8_t, struct iked_hash *);
1036
struct ibuf *
1037
   dsa_setkey(struct iked_dsa *, void *, size_t, uint8_t);
1038
void   dsa_free(struct iked_dsa *);
1039
int  dsa_init(struct iked_dsa *, const void *, size_t);
1040
size_t   dsa_prefix(struct iked_dsa *);
1041
size_t   dsa_length(struct iked_dsa *);
1042
int  dsa_update(struct iked_dsa *, const void *, size_t);
1043
ssize_t  dsa_sign_final(struct iked_dsa *, void *, size_t);
1044
ssize_t  dsa_verify_final(struct iked_dsa *, void *, size_t);
1045
1046
/* vroute.c */
1047
void vroute_init(struct iked *);
1048
int vroute_setaddr(struct iked *, int, struct sockaddr *, int, unsigned int);
1049
void vroute_cleanup(struct iked *);
1050
int vroute_getaddr(struct iked *, struct imsg *);
1051
int vroute_setdns(struct iked *, int, struct sockaddr *, unsigned int);
1052
int vroute_getdns(struct iked *, struct imsg *);
1053
int vroute_setaddroute(struct iked *, uint8_t, struct sockaddr *,
1054
    uint8_t, struct sockaddr *);
1055
int vroute_setcloneroute(struct iked *, uint8_t, struct sockaddr *,
1056
    uint8_t, struct sockaddr *);
1057
int vroute_setdelroute(struct iked *, uint8_t, struct sockaddr *,
1058
    uint8_t, struct sockaddr *);
1059
int vroute_getroute(struct iked *, struct imsg *);
1060
int vroute_getcloneroute(struct iked *, struct imsg *);
1061
1062
/* ikev2.c */
1063
void   ikev2(struct privsep *, struct privsep_proc *);
1064
void   ikev2_recv(struct iked *, struct iked_message *);
1065
void   ikev2_init_ike_sa(struct iked *, void *);
1066
int  ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
1067
int  ikev2_childsa_enable(struct iked *, struct iked_sa *);
1068
int  ikev2_childsa_delete(struct iked *, struct iked_sa *,
1069
      uint8_t, uint64_t, uint64_t *, int);
1070
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
1071
void   ikev2_ike_sa_timeout(struct iked *env, void *);
1072
void   ikev2_ike_sa_setreason(struct iked_sa *, char *);
1073
void   ikev2_reset_alive_timer(struct iked *);
1074
int  ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
1075
1076
struct ibuf *
1077
   ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
1078
      size_t);
1079
ssize_t  ikev2_psk(struct iked_sa *, uint8_t *, size_t, uint8_t **);
1080
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
1081
      void *, size_t, unsigned int, int);
1082
void   ikev2_enable_natt(struct iked *, struct iked_sa *,
1083
      struct iked_message *, int);
1084
int  ikev2_send_informational(struct iked *, struct iked_message *);
1085
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
1086
      uint8_t, uint8_t, int);
1087
struct ike_header *
1088
   ikev2_add_header(struct ibuf *, struct iked_sa *,
1089
      uint32_t, uint8_t, uint8_t, uint8_t);
1090
int  ikev2_set_header(struct ike_header *, size_t);
1091
struct ikev2_payload *
1092
   ikev2_add_payload(struct ibuf *);
1093
int  ikev2_next_payload(struct ikev2_payload *, size_t,
1094
      uint8_t);
1095
int  ikev2_child_sa_acquire(struct iked *, struct iked_flow *);
1096
int  ikev2_child_sa_drop(struct iked *, struct iked_spi *);
1097
int  ikev2_child_sa_rekey(struct iked *, struct iked_spi *);
1098
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
1099
int  ikev2_print_id(struct iked_id *, char *, size_t);
1100
int  ikev2_print_static_id(struct iked_static_id *, char *, size_t);
1101
1102
const char  *ikev2_ikesa_info(uint64_t, const char *msg);
1103
#define SPI_IH(hdr)      ikev2_ikesa_info(betoh64((hdr)->ike_ispi), NULL)
1104
7.69k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.69k
#define SPI_SA(sa, f)    SPI_SH(&(sa)->sa_hdr, (f))
1106
1107
/* ikev2_msg.c */
1108
void   ikev2_msg_cb(int, short, void *);
1109
struct ibuf *
1110
   ikev2_msg_init(struct iked *, struct iked_message *,
1111
      struct sockaddr_storage *, socklen_t,
1112
      struct sockaddr_storage *, socklen_t, int);
1113
struct iked_message *
1114
   ikev2_msg_copy(struct iked *, struct iked_message *);
1115
void   ikev2_msg_cleanup(struct iked *, struct iked_message *);
1116
uint32_t
1117
   ikev2_msg_id(struct iked *, struct iked_sa *);
1118
struct ibuf
1119
  *ikev2_msg_auth(struct iked *, struct iked_sa *, int);
1120
int  ikev2_msg_authsign(struct iked *, struct iked_sa *,
1121
      struct iked_auth *, struct ibuf *);
1122
int  ikev2_msg_authverify(struct iked *, struct iked_sa *,
1123
      struct iked_auth *, uint8_t *, size_t, struct ibuf *);
1124
int  ikev2_msg_valid_ike_sa(struct iked *, struct ike_header *,
1125
      struct iked_message *);
1126
int  ikev2_msg_send(struct iked *, struct iked_message *);
1127
int  ikev2_msg_send_encrypt(struct iked *, struct iked_sa *,
1128
      struct ibuf **, uint8_t, uint8_t, int);
1129
struct ibuf
1130
  *ikev2_msg_encrypt(struct iked *, struct iked_sa *, struct ibuf *,
1131
      struct ibuf *);
1132
struct ibuf *
1133
   ikev2_msg_decrypt(struct iked *, struct iked_sa *,
1134
      struct ibuf *, struct ibuf *);
1135
int  ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
1136
int  ikev2_msg_frompeer(struct iked_message *);
1137
struct iked_socket *
1138
   ikev2_msg_getsocket(struct iked *, int, int);
1139
int  ikev2_msg_enqueue(struct iked *, struct iked_msgqueue *,
1140
      struct iked_message *, int);
1141
int  ikev2_msg_retransmit_response(struct iked *, struct iked_sa *,
1142
      struct iked_message *, uint8_t);
1143
void   ikev2_msg_prevail(struct iked *, struct iked_msgqueue *,
1144
      struct iked_message *);
1145
void   ikev2_msg_dispose(struct iked *, struct iked_msgqueue *,
1146
      struct iked_msg_retransmit *);
1147
void   ikev2_msg_flushqueue(struct iked *, struct iked_msgqueue *);
1148
struct iked_msg_retransmit *
1149
   ikev2_msg_lookup(struct iked *, struct iked_msgqueue *,
1150
      struct iked_message *, uint8_t);
1151
1152
/* ikev2_pld.c */
1153
int  ikev2_pld_parse(struct iked *, struct ike_header *,
1154
      struct iked_message *, size_t);
1155
1156
/* eap.c */
1157
int  eap_parse(struct iked *, const struct iked_sa *, struct iked_message*,
1158
      void *, int);
1159
int  eap_success(struct iked *, struct iked_sa *, int);
1160
int  eap_identity_request(struct iked *, struct iked_sa *);
1161
int  eap_mschap_challenge(struct iked *, struct iked_sa *, int, int,
1162
      uint8_t *, size_t);
1163
int  eap_mschap_success(struct iked *, struct iked_sa *, int);
1164
int  eap_challenge_request(struct iked *, struct iked_sa *, int);
1165
1166
/* pfkey.c */
1167
int  pfkey_couple(struct iked *, struct iked_sas *, int);
1168
int  pfkey_flow_add(struct iked *, struct iked_flow *);
1169
int  pfkey_flow_delete(struct iked *, struct iked_flow *);
1170
int  pfkey_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1171
int  pfkey_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1172
int  pfkey_sa_update_addresses(struct iked *, struct iked_childsa *);
1173
int  pfkey_sa_delete(struct iked *, struct iked_childsa *);
1174
int  pfkey_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1175
int  pfkey_flush(struct iked *);
1176
int  pfkey_socket(struct iked *);
1177
void   pfkey_init(struct iked *, int fd);
1178
1179
/* ipsec.c */
1180
int  ipsec_couple(struct iked *, struct iked_sas *, int);
1181
int  ipsec_flow_add(struct iked *, struct iked_flow *);
1182
int  ipsec_flow_delete(struct iked *, struct iked_flow *);
1183
int  ipsec_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1184
int  ipsec_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1185
int  ipsec_sa_update_addresses(struct iked *, struct iked_childsa *);
1186
int  ipsec_sa_delete(struct iked *, struct iked_childsa *);
1187
int  ipsec_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1188
int  ipsec_sa_rpl(struct iked *, struct iked_childsa *, uint32_t *);
1189
int  ipsec_sa_lifetimes(struct iked *, struct iked_childsa *, struct iked_lifetime *,
1190
       struct iked_lifetime *, struct iked_lifetime *);
1191
int  ipsec_flush(struct iked *);
1192
int  ipsec_socket(struct iked *);
1193
void   ipsec_init(struct iked *, int fd);
1194
1195
/* ca.c */
1196
void   caproc(struct privsep *, struct privsep_proc *);
1197
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
1198
      uint8_t, uint8_t, uint8_t *, size_t, enum privsep_procid);
1199
int  ca_setcert(struct iked *, struct iked_sahdr *, struct iked_id *,
1200
      uint8_t, uint8_t *, size_t, enum privsep_procid);
1201
int  ca_setauth(struct iked *, struct iked_sa *,
1202
      struct ibuf *, enum privsep_procid);
1203
void   ca_getkey(struct privsep *, struct iked_id *, enum imsg_type);
1204
int  ca_certbundle_add(struct ibuf *, struct iked_id *);
1205
int  ca_privkey_serialize(EVP_PKEY *, struct iked_id *);
1206
int  ca_pubkey_serialize(EVP_PKEY *, struct iked_id *);
1207
void   ca_sslinit(void);
1208
void   ca_sslerror(const char *);
1209
char  *ca_asn1_name(uint8_t *, size_t);
1210
void  *ca_x509_name_parse(char *);
1211
void   ca_cert_info(const char *, X509 *);
1212
1213
/* timer.c */
1214
void   timer_set(struct iked *, struct iked_timer *,
1215
      void (*)(struct iked *, void *), void *);
1216
void   timer_add(struct iked *, struct iked_timer *, int);
1217
void   timer_del(struct iked *, struct iked_timer *);
1218
1219
/* proc.c */
1220
void   proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
1221
      int, char **, enum privsep_procid);
1222
void   proc_kill(struct privsep *);
1223
void   proc_connect(struct privsep *);
1224
void   proc_dispatch(int, short event, void *);
1225
void   proc_run(struct privsep *, struct privsep_proc *,
1226
      struct privsep_proc *, unsigned int,
1227
      void (*)(struct privsep *, struct privsep_proc *, void *), void *);
1228
void   imsg_event_add(struct imsgev *);
1229
int  imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
1230
      pid_t, int, void *, uint16_t);
1231
int  imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
1232
      pid_t, int, const struct iovec *, int);
1233
int  proc_compose_imsg(struct privsep *, enum privsep_procid, int,
1234
      uint16_t, uint32_t, int, void *, uint16_t);
1235
int  proc_compose(struct privsep *, enum privsep_procid,
1236
      uint16_t, void *, uint16_t);
1237
int  proc_composev_imsg(struct privsep *, enum privsep_procid, int,
1238
      uint16_t, uint32_t, int, const struct iovec *, int);
1239
int  proc_composev(struct privsep *, enum privsep_procid,
1240
      uint16_t, const struct iovec *, int);
1241
int  proc_forward_imsg(struct privsep *, struct imsg *,
1242
      enum privsep_procid, int);
1243
struct imsgbuf *
1244
   proc_ibuf(struct privsep *, enum privsep_procid, int);
1245
struct imsgev *
1246
   proc_iev(struct privsep *, enum privsep_procid, int);
1247
enum privsep_procid
1248
   proc_getid(struct privsep_proc *, unsigned int, const char *);
1249
int  proc_flush_imsg(struct privsep *, enum privsep_procid, int);
1250
1251
/* util.c */
1252
int  socket_af(struct sockaddr *, in_port_t);
1253
in_port_t
1254
   socket_getport(struct sockaddr *);
1255
int  socket_setport(struct sockaddr *, in_port_t);
1256
int  socket_getaddr(int, struct sockaddr_storage *);
1257
int  socket_bypass(int, struct sockaddr *);
1258
int  udp_bind(struct sockaddr *, in_port_t);
1259
ssize_t  sendtofrom(int, void *, size_t, int, struct sockaddr *,
1260
      socklen_t, struct sockaddr *, socklen_t);
1261
ssize_t  recvfromto(int, void *, size_t, int, struct sockaddr *,
1262
      socklen_t *, struct sockaddr *, socklen_t *);
1263
const char *
1264
   print_spi(uint64_t, int);
1265
const char *
1266
   print_map(unsigned int, struct iked_constmap *);
1267
void   lc_idtype(char *);
1268
void   print_hex(const uint8_t *, off_t, size_t);
1269
void   print_hexval(const uint8_t *, off_t, size_t);
1270
void   print_hexbuf(struct ibuf *);
1271
const char *
1272
   print_bits(unsigned short, unsigned char *);
1273
int  sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
1274
uint8_t mask2prefixlen(struct sockaddr *);
1275
uint8_t mask2prefixlen6(struct sockaddr *);
1276
struct in6_addr *
1277
   prefixlen2mask6(uint8_t, uint32_t *);
1278
uint32_t
1279
   prefixlen2mask(uint8_t);
1280
const char *
1281
   print_addr(void *);
1282
char  *get_string(uint8_t *, size_t);
1283
const char *
1284
   print_proto(uint8_t);
1285
int  expand_string(char *, size_t, const char *, const char *);
1286
uint8_t *string2unicode(const char *, size_t *);
1287
void   print_debug(const char *, ...)
1288
      __attribute__((format(printf, 1, 2)));
1289
void   print_verbose(const char *, ...)
1290
      __attribute__((format(printf, 1, 2)));
1291
1292
/* imsg_util.c */
1293
struct ibuf *
1294
   ibuf_new(const void *, size_t);
1295
struct ibuf *
1296
   ibuf_static(void);
1297
size_t   ibuf_length(struct ibuf *);
1298
int  ibuf_setsize(struct ibuf *, size_t);
1299
struct ibuf *
1300
   ibuf_getdata(struct ibuf *, size_t);
1301
struct ibuf *
1302
   ibuf_dup(struct ibuf *);
1303
struct ibuf *
1304
   ibuf_random(size_t);
1305
1306
/* log.c */
1307
void  log_init(int, int);
1308
void  log_procinit(const char *);
1309
void  log_setverbose(int);
1310
int log_getverbose(void);
1311
void  log_warn(const char *, ...)
1312
      __attribute__((__format__ (printf, 1, 2)));
1313
void  log_warnx(const char *, ...)
1314
      __attribute__((__format__ (printf, 1, 2)));
1315
void  log_info(const char *, ...)
1316
      __attribute__((__format__ (printf, 1, 2)));
1317
void  log_debug(const char *, ...)
1318
      __attribute__((__format__ (printf, 1, 2)));
1319
void  logit(int, const char *, ...)
1320
      __attribute__((__format__ (printf, 2, 3)));
1321
void  vlog(int, const char *, va_list)
1322
      __attribute__((__format__ (printf, 2, 0)));
1323
__dead void fatal(const char *, ...)
1324
      __attribute__((__format__ (printf, 1, 2)));
1325
__dead void fatalx(const char *, ...)
1326
      __attribute__((__format__ (printf, 1, 2)));
1327
1328
/* ocsp.c */
1329
int  ocsp_connect(struct iked *, struct imsg *);
1330
int  ocsp_receive_fd(struct iked *, struct imsg *);
1331
int  ocsp_validate_cert(struct iked *, void *, size_t, struct iked_sahdr,
1332
    uint8_t, X509 *);
1333
1334
/* parse.y */
1335
int  parse_config(const char *, struct iked *);
1336
int  cmdline_symset(char *);
1337
extern const struct ipsec_xf authxfs[];
1338
extern const struct ipsec_xf prfxfs[];
1339
extern const struct ipsec_xf *encxfs;
1340
extern const struct ipsec_xf ikeencxfs[];
1341
extern const struct ipsec_xf ipsecencxfs[];
1342
extern const struct ipsec_xf groupxfs[];
1343
extern const struct ipsec_xf esnxfs[];
1344
extern const struct ipsec_xf methodxfs[];
1345
extern const struct ipsec_xf saxfs[];
1346
extern const struct ipsec_xf cpxfs[];
1347
size_t   keylength_xf(unsigned int, unsigned int, unsigned int);
1348
size_t   noncelength_xf(unsigned int, unsigned int);
1349
int  encxf_noauth(unsigned int);
1350
1351
/* print.c */
1352
void   print_user(struct iked_user *);
1353
void   print_policy(struct iked_policy *);
1354
const char *print_xf(unsigned int, unsigned int, const struct ipsec_xf *);
1355
1356
#endif /* IKED_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/iked.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: iked.h,v 1.224 2023/08/11 11:24:55 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019-2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/tree.h>
22
#include <sys/queue.h>
23
#include <arpa/inet.h>
24
#include <limits.h>
25
#include <imsg.h>
26
27
#include <openssl/evp.h>
28
29
#include "openbsd-compat.h"
30
31
#include "types.h"
32
#include "dh.h"
33
34
#define MAXIMUM(a,b) (((a)>(b))?(a):(b))
35
#define MINIMUM(a,b) (((a)<(b))?(a):(b))
36
#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
37
38
#ifndef IKED_H
39
#define IKED_H
40
41
/*
42
 * Common IKEv1/IKEv2 header
43
 */
44
45
struct ike_header {
46
  uint64_t   ike_ispi;    /* Initiator cookie */
47
  uint64_t   ike_rspi;    /* Responder cookie */
48
  uint8_t    ike_nextpayload; /* Next payload type */
49
  uint8_t    ike_version;   /* Major/Minor version number */
50
  uint8_t    ike_exchange;    /* Exchange type */
51
  uint8_t    ike_flags;   /* Message options */
52
  uint32_t   ike_msgid;   /* Message identifier */
53
  uint32_t   ike_length;    /* Total message length */
54
} __packed;
55
56
/*
57
 * Common daemon infrastructure, local imsg etc.
58
 */
59
60
struct imsgev {
61
  struct imsgbuf     ibuf;
62
  void      (*handler)(int, short, void *);
63
  struct event     ev;
64
  struct privsep_proc *proc;
65
  void      *data;
66
  short      events;
67
  const char    *name;
68
};
69
70
#define IMSG_SIZE_CHECK(imsg, p) do {       \
71
  if (IMSG_DATA_SIZE(imsg) < sizeof(*p))      \
72
    fatalx("bad length imsg received");   \
73
} while (0)
74
#define IMSG_DATA_SIZE(imsg)  ((imsg)->hdr.len - IMSG_HEADER_SIZE)
75
76
#define IKED_ADDR_EQ(_a, _b)            \
77
  ((_a)->addr_mask == (_b)->addr_mask &&        \
78
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
79
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) == 0)
80
81
#define IKED_ADDR_NEQ(_a, _b)           \
82
  ((_a)->addr_mask != (_b)->addr_mask ||        \
83
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
84
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) != 0)
85
86
/* initially control.h */
87
struct control_sock {
88
  const char  *cs_name;
89
  struct event   cs_ev;
90
  struct event   cs_evt;
91
  int    cs_fd;
92
  int    cs_restricted;
93
  void    *cs_env;
94
95
  TAILQ_ENTRY(control_sock) cs_entry;
96
};
97
TAILQ_HEAD(control_socks, control_sock);
98
99
struct ctl_conn {
100
  TAILQ_ENTRY(ctl_conn)  entry;
101
  uint8_t      flags;
102
#define CTL_CONN_NOTIFY    0x01
103
  struct imsgev    iev;
104
};
105
TAILQ_HEAD(ctl_connlist, ctl_conn);
106
107
extern enum privsep_procid privsep_process;
108
109
/*
110
 * Runtime structures
111
 */
112
113
struct iked_timer {
114
  struct event   tmr_ev;
115
  struct iked *tmr_env;
116
  void    (*tmr_cb)(struct iked *, void *);
117
  void    *tmr_cbarg;
118
};
119
120
struct iked_spi {
121
  uint64_t   spi;
122
  uint8_t    spi_size;
123
  uint8_t    spi_protoid;
124
};
125
126
struct iked_proposal {
127
  uint8_t        prop_id;
128
  uint8_t        prop_protoid;
129
130
  struct iked_spi      prop_localspi;
131
  struct iked_spi      prop_peerspi;
132
133
  struct iked_transform   *prop_xforms;
134
  unsigned int       prop_nxforms;
135
136
  TAILQ_ENTRY(iked_proposal)   prop_entry;
137
};
138
TAILQ_HEAD(iked_proposals, iked_proposal);
139
140
struct iked_addr {
141
  int        addr_af;
142
  struct sockaddr_storage    addr;
143
  uint8_t        addr_mask;
144
  int        addr_net;
145
  in_port_t      addr_port;
146
};
147
148
struct iked_ts {
149
  struct iked_addr     ts_addr;
150
  uint8_t        ts_ipproto;
151
  TAILQ_ENTRY(iked_ts)     ts_entry;
152
};
153
TAILQ_HEAD(iked_tss, iked_ts);
154
155
struct iked_flow {
156
  struct iked_addr     flow_src;
157
  struct iked_addr     flow_dst;
158
  unsigned int       flow_dir;  /* in/out */
159
  int        flow_rdomain;
160
  struct iked_addr     flow_prenat;
161
  int        flow_fixed;
162
163
  unsigned int       flow_loaded; /* pfkey done */
164
165
  uint8_t        flow_saproto;
166
  uint8_t        flow_ipproto;
167
168
  struct iked_addr    *flow_local;  /* outer source */
169
  struct iked_addr    *flow_peer; /* outer dest */
170
  struct iked_sa      *flow_ikesa;  /* parent SA */
171
172
  int        flow_transport;
173
174
  RB_ENTRY(iked_flow)    flow_node;
175
  TAILQ_ENTRY(iked_flow)     flow_entry;
176
};
177
RB_HEAD(iked_flows, iked_flow);
178
TAILQ_HEAD(iked_saflows, iked_flow);
179
180
struct iked_childsa {
181
  uint8_t        csa_saproto; /* IPsec protocol */
182
  unsigned int       csa_dir; /* in/out */
183
184
  uint64_t       csa_peerspi; /* peer relation */
185
  uint8_t        csa_loaded;  /* pfkey done */
186
  uint8_t        csa_rekey; /* will be deleted */
187
  uint8_t        csa_allocated; /* from the kernel */
188
  uint8_t        csa_persistent;/* do not rekey */
189
  uint8_t        csa_esn; /* use ESN */
190
  uint8_t        csa_transport; /* transport mode */
191
192
  struct iked_spi      csa_spi;
193
194
  struct ibuf     *csa_encrkey; /* encryption key */
195
  uint16_t       csa_encrid;  /* encryption xform id */
196
197
  struct ibuf     *csa_integrkey; /* auth key */
198
  uint16_t       csa_integrid;  /* auth xform id */
199
200
  struct iked_addr    *csa_local; /* outer source */
201
  struct iked_addr    *csa_peer;  /* outer dest */
202
  struct iked_sa      *csa_ikesa; /* parent SA */
203
204
  struct iked_childsa   *csa_peersa;  /* peer */
205
206
  struct iked_childsa   *csa_bundled; /* IPCOMP */
207
208
  uint16_t       csa_pfsgrpid;  /* pfs group id */
209
210
  RB_ENTRY(iked_childsa)     csa_node;
211
  TAILQ_ENTRY(iked_childsa)  csa_entry;
212
};
213
RB_HEAD(iked_activesas, iked_childsa);
214
TAILQ_HEAD(iked_childsas, iked_childsa);
215
216
217
struct iked_static_id {
218
  uint8_t   id_type;
219
  uint8_t   id_length;
220
  uint8_t   id_offset;
221
  uint8_t   id_data[IKED_ID_SIZE];
222
};
223
224
struct iked_auth {
225
  uint8_t   auth_method;
226
  uint8_t   auth_eap;     /* optional EAP */
227
  uint8_t   auth_length;      /* zero if EAP */
228
  uint8_t   auth_data[IKED_PSK_SIZE];
229
};
230
231
struct iked_cfg {
232
  uint8_t        cfg_action;
233
  uint16_t       cfg_type;
234
  union {
235
    struct iked_addr   address;
236
  } cfg;
237
};
238
239
TAILQ_HEAD(iked_sapeers, iked_sa);
240
241
struct iked_lifetime {
242
  uint64_t       lt_bytes;
243
  uint64_t       lt_seconds;
244
};
245
246
struct iked_policy {
247
  unsigned int       pol_id;
248
  char         pol_name[IKED_ID_SIZE];
249
  unsigned int       pol_iface;
250
251
#define IKED_SKIP_FLAGS      0
252
#define IKED_SKIP_AF       1
253
#define IKED_SKIP_SRC_ADDR     2
254
#define IKED_SKIP_DST_ADDR     3
255
#define IKED_SKIP_COUNT      4
256
  struct iked_policy    *pol_skip[IKED_SKIP_COUNT];
257
258
  uint8_t        pol_flags;
259
#define IKED_POLICY_PASSIVE    0x00
260
#define IKED_POLICY_DEFAULT    0x01
261
#define IKED_POLICY_ACTIVE     0x02
262
#define IKED_POLICY_REFCNT     0x04
263
#define IKED_POLICY_QUICK    0x08
264
#define IKED_POLICY_SKIP     0x10
265
#define IKED_POLICY_IPCOMP     0x20
266
0
#define IKED_POLICY_TRANSPORT    0x40
267
#define IKED_POLICY_ROUTING    0x80
268
269
  int        pol_refcnt;
270
271
  uint8_t        pol_certreqtype;
272
273
  int        pol_af;
274
  int        pol_rdomain;
275
  uint8_t        pol_saproto;
276
  unsigned int       pol_ipproto[IKED_IPPROTO_MAX];
277
  unsigned int       pol_nipproto;
278
279
  struct iked_addr     pol_peer;
280
  struct iked_static_id    pol_peerid;
281
  uint32_t       pol_peerdh;
282
283
  struct iked_addr     pol_local;
284
  struct iked_static_id    pol_localid;
285
286
  struct iked_auth     pol_auth;
287
288
  char         pol_tag[IKED_TAG_SIZE];
289
  unsigned int       pol_tap;
290
291
  struct iked_proposals    pol_proposals;
292
  size_t         pol_nproposals;
293
294
  struct iked_flows    pol_flows;
295
  size_t         pol_nflows;
296
  struct iked_tss      pol_tssrc; /* Traffic Selectors Initiator*/
297
  size_t         pol_tssrc_count;
298
  struct iked_tss      pol_tsdst; /* Traffic Selectors Responder*/
299
  size_t         pol_tsdst_count;
300
301
  struct iked_cfg      pol_cfg[IKED_CFG_MAX];
302
  unsigned int       pol_ncfg;
303
304
  uint32_t       pol_rekey; /* ike SA lifetime */
305
  struct iked_lifetime     pol_lifetime;  /* child SA lifetime */
306
307
  struct iked_sapeers    pol_sapeers;
308
309
  TAILQ_ENTRY(iked_policy)   pol_entry;
310
};
311
TAILQ_HEAD(iked_policies, iked_policy);
312
313
struct iked_hash {
314
  uint8_t    hash_type; /* PRF or INTEGR */
315
  uint16_t   hash_id; /* IKE PRF/INTEGR hash id */
316
  const void  *hash_priv; /* Identifying the hash alg */
317
  void    *hash_ctx;  /* Context of the current invocation */
318
  int    hash_fixedkey; /* Requires fixed key length */
319
  struct ibuf *hash_key;  /* MAC key derived from key seed */
320
  size_t     hash_length; /* Output length */
321
  size_t     hash_trunc;  /* Truncate the output length */
322
  struct iked_hash *hash_prf; /* PRF pointer */
323
  int    hash_isaead;
324
};
325
326
struct iked_cipher {
327
  uint8_t    encr_type; /* ENCR */
328
  uint16_t   encr_id; /* IKE ENCR hash id */
329
  const void  *encr_priv; /* Identifying the hash alg */
330
  void    *encr_ctx;  /* Context of the current invocation */
331
  int    encr_fixedkey; /* Requires fixed key length */
332
  struct ibuf *encr_key;  /* MAC key derived from key seed */
333
  struct ibuf *encr_iv; /* Initialization Vector */
334
  uint64_t   encr_civ;  /* Counter IV for GCM */
335
  size_t     encr_ivlength; /* IV length */
336
  size_t     encr_length; /* Block length */
337
  size_t     encr_saltlength; /* IV salt length */
338
  uint16_t   encr_authid; /* ID of associated authentication */
339
};
340
341
struct iked_dsa {
342
  uint8_t    dsa_method;  /* AUTH method */
343
  const void  *dsa_priv;  /* PRF or signature hash function */
344
  void    *dsa_ctx; /* PRF or signature hash ctx */
345
  struct ibuf *dsa_keydata; /* public, private or shared key */
346
  void    *dsa_key; /* parsed public or private key */
347
  int    dsa_hmac;  /* HMAC or public/private key */
348
  int    dsa_sign;  /* Sign or verify operation */
349
  uint32_t   dsa_flags; /* State flags */
350
};
351
352
struct iked_id {
353
  uint8_t    id_type;
354
  uint8_t    id_offset;
355
  struct ibuf *id_buf;
356
};
357
358
#define IKED_REQ_CERT   0x0001  /* get local certificate (if required) */
359
#define IKED_REQ_CERTVALID  0x0002  /* validated the peer cert */
360
#define IKED_REQ_CERTREQ  0x0004  /* CERTREQ has been received */
361
#define IKED_REQ_AUTH   0x0008  /* AUTH payload */
362
#define IKED_REQ_AUTHVALID  0x0010  /* AUTH payload has been verified */
363
#define IKED_REQ_SA   0x0020  /* SA available */
364
#define IKED_REQ_EAPVALID 0x0040  /* EAP payload has been verified */
365
#define IKED_REQ_CHILDSA  0x0080  /* Child SA initiated */
366
#define IKED_REQ_INF    0x0100  /* Informational exchange initiated */
367
368
#define IKED_REQ_BITS \
369
    "\20\01CERT\02CERTVALID\03CERTREQ\04AUTH\05AUTHVALID\06SA\07EAPVALID" \
370
    "\10CHILDSA\11INF"
371
372
TAILQ_HEAD(iked_msgqueue, iked_msg_retransmit);
373
TAILQ_HEAD(iked_msg_fragqueue, iked_message);
374
375
struct iked_sahdr {
376
  uint64_t       sh_ispi; /* Initiator SPI */
377
  uint64_t       sh_rspi; /* Responder SPI */
378
  unsigned int       sh_initiator;  /* Is initiator? */
379
} __packed;
380
381
struct iked_kex {
382
  struct ibuf     *kex_inonce;  /* Ni */
383
  struct ibuf     *kex_rnonce;  /* Nr */
384
385
  struct dh_group     *kex_dhgroup; /* DH group */
386
  struct ibuf     *kex_dhiexchange;
387
  struct ibuf     *kex_dhrexchange;
388
  struct ibuf     *kex_dhpeer;  /* pointer to i or r */
389
};
390
391
struct iked_frag_entry {
392
  uint8_t *frag_data;
393
  size_t   frag_size;
394
};
395
396
struct iked_frag {
397
  struct iked_frag_entry  **frag_arr; /* list of fragment buffers */
398
  size_t        frag_count; /* number of fragments received */
399
0
#define IKED_FRAG_TOTAL_MAX   111    /* upper limit (64kB / 576B) */
400
  size_t        frag_total; /* total numbe of fragments */
401
  size_t        frag_total_size;
402
  uint8_t       frag_nextpayload;
403
404
};
405
406
struct iked_ipcomp {
407
  uint16_t       ic_cpi_out;  /* outgoing CPI */
408
  uint16_t       ic_cpi_in; /* incoming CPI */
409
  uint8_t        ic_transform;  /* transform */
410
};
411
412
struct iked_sa {
413
  struct iked_sahdr    sa_hdr;
414
  uint32_t       sa_msgid;  /* Last request rcvd */
415
  int        sa_msgid_set;  /* msgid initialized */
416
  uint32_t       sa_msgid_current;  /* Current requested rcvd */
417
  uint32_t       sa_reqid;  /* Next request sent */
418
419
  int        sa_type;
420
#define IKED_SATYPE_LOOKUP     0    /* Used for lookup */
421
#define IKED_SATYPE_LOCAL    1    /* Local SA */
422
423
  struct iked_addr     sa_peer;
424
  struct iked_addr     sa_peer_loaded;/* MOBIKE */
425
  struct iked_addr     sa_local;
426
  int        sa_fd;
427
428
  struct iked_frag     sa_fragments;
429
430
  int        sa_natt; /* for IKE messages */
431
  int        sa_udpencap; /* for pfkey */
432
  int        sa_usekeepalive;/* NAT-T keepalive */
433
434
  int        sa_state;
435
  unsigned int       sa_stateflags;
436
  unsigned int       sa_stateinit;  /* SA_INIT */
437
  unsigned int       sa_statevalid; /* IKE_AUTH */
438
439
  int        sa_cp;   /* XXX */
440
  struct iked_addr    *sa_cp_addr;  /* requested address */
441
  struct iked_addr    *sa_cp_addr6; /* requested address */
442
  struct iked_addr    *sa_cp_dns; /* requested dns */
443
444
  struct iked_policy    *sa_policy;
445
  struct timeval       sa_timecreated;
446
  struct timeval       sa_timeused;
447
448
  char        *sa_tag;
449
  const char      *sa_reason; /* reason for close */
450
451
  struct iked_kex      sa_kex;
452
/* XXX compat defines until everything is converted */
453
#define sa_inonce   sa_kex.kex_inonce
454
#define sa_rnonce   sa_kex.kex_rnonce
455
#define sa_dhgroup    sa_kex.kex_dhgroup
456
#define sa_dhiexchange    sa_kex.kex_dhiexchange
457
#define sa_dhrexchange    sa_kex.kex_dhrexchange
458
#define sa_dhpeer   sa_kex.kex_dhpeer
459
460
  struct iked_hash    *sa_prf;  /* PRF alg */
461
  struct iked_hash    *sa_integr; /* integrity alg */
462
  struct iked_cipher    *sa_encr; /* encryption alg */
463
464
  struct ibuf     *sa_key_d;  /* SK_d */
465
  struct ibuf     *sa_key_iauth;  /* SK_ai */
466
  struct ibuf     *sa_key_rauth;  /* SK_ar */
467
  struct ibuf     *sa_key_iencr;  /* SK_ei */
468
  struct ibuf     *sa_key_rencr;  /* SK_er */
469
  struct ibuf     *sa_key_iprf; /* SK_pi */
470
  struct ibuf     *sa_key_rprf; /* SK_pr */
471
472
  struct ibuf     *sa_1stmsg; /* for initiator AUTH */
473
  struct ibuf     *sa_2ndmsg; /* for responder AUTH */
474
  struct iked_id       sa_localauth;  /* local AUTH message */
475
  struct iked_id       sa_peerauth; /* peer AUTH message */
476
  int        sa_sigsha2;  /* use SHA2 for signatures */
477
109k
#define IKED_SCERT_MAX  3 /* max # of supplemental cert payloads */
478
479
  struct iked_id       sa_iid;  /* initiator id */
480
  struct iked_id       sa_rid;  /* responder id */
481
  struct iked_id       sa_icert;  /* initiator cert */
482
  struct iked_id       sa_rcert;  /* responder cert */
483
  struct iked_id       sa_scert[IKED_SCERT_MAX]; /* supplemental certs */
484
#define IKESA_SRCID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_iid : &(x)->sa_rid)
485
#define IKESA_DSTID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_rid : &(x)->sa_iid)
486
487
  char        *sa_eapid;  /* EAP identity */
488
  struct iked_id       sa_eap;  /* EAP challenge */
489
  struct ibuf     *sa_eapmsk; /* EAK session key */
490
491
  struct iked_proposals    sa_proposals;  /* SA proposals */
492
  struct iked_childsas     sa_childsas; /* IPsec Child SAs */
493
  struct iked_saflows    sa_flows;  /* IPsec flows */
494
495
  struct iked_sa      *sa_nexti;  /* initiated IKE SA */
496
  struct iked_sa      *sa_previ;  /* matching back pointer */
497
  struct iked_sa      *sa_nextr;  /* simultaneous rekey */
498
  struct iked_sa      *sa_prevr;  /* matching back pointer */
499
  uint64_t       sa_rekeyspi; /* peerspi CSA rekey */
500
  struct ibuf     *sa_simult; /* simultaneous rekey */
501
502
  struct iked_ipcomp     sa_ipcompi;  /* IPcomp initator */
503
  struct iked_ipcomp     sa_ipcompr;  /* IPcomp responder */
504
505
  int        sa_mobike; /* MOBIKE */
506
  int        sa_frag; /* fragmentation */
507
508
  int        sa_use_transport_mode; /* peer requested */
509
  int        sa_used_transport_mode; /* we enabled */
510
511
  struct iked_timer    sa_timer;  /* SA timeouts */
512
#define IKED_IKE_SA_EXCHANGE_TIMEOUT   300    /* 5 minutes */
513
#define IKED_IKE_SA_REKEY_TIMEOUT  120    /* 2 minutes */
514
#define IKED_IKE_SA_DELETE_TIMEOUT   120    /* 2 minutes */
515
#define IKED_IKE_SA_ALIVE_TIMEOUT  60   /* 1 minute */
516
517
  struct iked_timer    sa_keepalive;  /* keepalive timer */
518
#define IKED_IKE_SA_KEEPALIVE_TIMEOUT  20
519
520
  struct iked_timer    sa_rekey;  /* rekey timeout */
521
  int        sa_tmpfail;
522
523
  struct iked_msgqueue     sa_requests; /* request queue */
524
#define IKED_RETRANSMIT_TIMEOUT    2    /* 2 seconds */
525
526
  struct iked_msgqueue     sa_responses;  /* response queue */
527
#define IKED_RESPONSE_TIMEOUT    120    /* 2 minutes */
528
529
  TAILQ_ENTRY(iked_sa)     sa_peer_entry;
530
  RB_ENTRY(iked_sa)    sa_entry;  /* all SAs */
531
532
  RB_ENTRY(iked_sa)    sa_dstid_entry;  /* SAs by DSTID */
533
  int        sa_dstid_entry_valid;    /* sa_dstid_entry valid */
534
535
  struct iked_addr    *sa_addrpool; /* address from pool */
536
  RB_ENTRY(iked_sa)    sa_addrpool_entry; /* pool entries */
537
538
  struct iked_addr    *sa_addrpool6;  /* address from pool */
539
  RB_ENTRY(iked_sa)    sa_addrpool6_entry;  /* pool entries */
540
  time_t         sa_last_recvd;
541
#define IKED_IKE_SA_LAST_RECVD_TIMEOUT   300    /* 5 minutes */
542
};
543
RB_HEAD(iked_sas, iked_sa);
544
RB_HEAD(iked_dstid_sas, iked_sa);
545
RB_HEAD(iked_addrpool, iked_sa);
546
RB_HEAD(iked_addrpool6, iked_sa);
547
548
/* stats */
549
550
struct iked_stats {
551
  uint64_t  ikes_sa_created;
552
  uint64_t  ikes_sa_established_total;
553
  uint64_t  ikes_sa_established_current;  /* gauge */
554
  uint64_t  ikes_sa_established_failures;
555
  uint64_t  ikes_sa_proposals_negotiate_failures;
556
  uint64_t  ikes_sa_rekeyed;
557
  uint64_t  ikes_sa_removed;
558
  uint64_t  ikes_csa_created;
559
  uint64_t  ikes_csa_removed;
560
  uint64_t  ikes_msg_sent;
561
  uint64_t  ikes_msg_send_failures;
562
  uint64_t  ikes_msg_rcvd;
563
  uint64_t  ikes_msg_rcvd_busy;
564
  uint64_t  ikes_msg_rcvd_dropped;
565
  uint64_t  ikes_retransmit_request;
566
  uint64_t  ikes_retransmit_response;
567
  uint64_t  ikes_retransmit_limit;
568
  uint64_t  ikes_frag_sent;
569
  uint64_t  ikes_frag_send_failures;
570
  uint64_t  ikes_frag_rcvd;
571
  uint64_t  ikes_frag_rcvd_drop;
572
  uint64_t  ikes_frag_reass_ok;
573
  uint64_t  ikes_frag_reass_drop;
574
  uint64_t  ikes_update_addresses_sent;
575
  uint64_t  ikes_dpd_sent;
576
  uint64_t  ikes_keepalive_sent;
577
};
578
579
0
#define ikestat_add(env, c, n)  do { env->sc_stats.c += (n); } while(0)
580
0
#define ikestat_inc(env, c) ikestat_add(env, c, 1)
581
#define ikestat_dec(env, c) ikestat_add(env, c, -1)
582
583
struct iked_certreq {
584
  struct ibuf     *cr_data;
585
  uint8_t        cr_type;
586
  SIMPLEQ_ENTRY(iked_certreq)  cr_entry;
587
};
588
SIMPLEQ_HEAD(iked_certreqs, iked_certreq);
589
590
#define EAP_STATE_IDENTITY    (1)
591
#define EAP_STATE_MSCHAPV2_CHALLENGE  (2)
592
#define EAP_STATE_MSCHAPV2_SUCCESS  (3)
593
#define EAP_STATE_SUCCESS   (4)
594
595
struct eap_msg {
596
  char    *eam_identity;
597
  char    *eam_user;
598
  int    eam_type;
599
  uint8_t    eam_id;
600
  uint8_t    eam_msrid;
601
  int    eam_success;
602
  int    eam_found;
603
  int    eam_response;
604
  uint8_t    eam_challenge[16];
605
  uint8_t    eam_ntresponse[24];
606
  uint32_t   eam_state;
607
};
608
609
struct iked_message {
610
  struct ibuf   *msg_data;
611
  size_t       msg_offset;
612
613
  struct sockaddr_storage  msg_local;
614
  socklen_t    msg_locallen;
615
616
  struct sockaddr_storage  msg_peer;
617
  socklen_t    msg_peerlen;
618
619
  struct iked_socket  *msg_sock;
620
621
  int      msg_fd;
622
  int      msg_response;
623
  int      msg_responded;
624
  int      msg_valid;
625
  int      msg_natt;
626
  int      msg_natt_rcvd;
627
  int      msg_nat_detected;
628
  int      msg_error;
629
  int      msg_e;
630
  struct iked_message *msg_parent;
631
632
  /* Associated policy and SA */
633
  struct iked_policy  *msg_policy;
634
  struct iked_sa    *msg_sa;
635
636
  uint32_t     msg_msgid;
637
  uint8_t      msg_exchange;
638
639
  /* Parsed information */
640
  struct iked_proposals  msg_proposals;
641
  struct iked_certreqs   msg_certreqs;
642
  struct iked_spi    msg_rekey;
643
  struct ibuf   *msg_nonce; /* dh NONCE */
644
  uint16_t     msg_dhgroup; /* dh group */
645
  struct ibuf   *msg_ke;  /* dh key exchange */
646
  struct iked_id     msg_auth;  /* AUTH payload */
647
  struct iked_id     msg_peerid;
648
  struct iked_id     msg_localid;
649
  struct iked_id     msg_cert;
650
  struct iked_id     msg_scert[IKED_SCERT_MAX]; /* supplemental certs */
651
  struct ibuf   *msg_cookie;
652
  uint16_t     msg_group;
653
  uint16_t     msg_cpi;
654
  uint8_t      msg_transform;
655
  uint16_t     msg_flags;
656
  struct eap_msg     msg_eap;
657
  size_t       msg_del_spisize;
658
  size_t       msg_del_cnt;
659
  struct ibuf   *msg_del_buf;
660
  int      msg_del_protoid;
661
  int      msg_cp;
662
  struct iked_addr  *msg_cp_addr; /* requested address */
663
  struct iked_addr  *msg_cp_addr6;  /* requested address */
664
  struct iked_addr  *msg_cp_dns;  /* requested dns */
665
666
  /* MOBIKE */
667
  int      msg_update_sa_addresses;
668
  struct ibuf   *msg_cookie2;
669
670
  /* Parse stack */
671
  struct iked_proposal  *msg_prop;
672
  uint16_t     msg_attrlength;
673
674
  /* Retransmit queue */
675
  TAILQ_ENTRY(iked_message)
676
         msg_entry;
677
};
678
679
struct iked_msg_retransmit {
680
  struct iked_msg_fragqueue       mrt_frags;
681
  TAILQ_ENTRY(iked_msg_retransmit)      mrt_entry;
682
  struct iked_timer         mrt_timer;
683
  int             mrt_tries;
684
#define IKED_RETRANSMIT_TRIES  5    /* try 5 times */
685
};
686
687
3.05k
#define IKED_MSG_NAT_SRC_IP       0x01
688
19.9k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
136
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
73
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
241
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
131
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
128
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
239
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
348
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
36
#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN   0x0400
701
702
703
struct iked_user {
704
  char       usr_name[LOGIN_NAME_MAX];
705
  char       usr_pass[IKED_PASSWORD_SIZE];
706
  RB_ENTRY(iked_user)  usr_entry;
707
};
708
RB_HEAD(iked_users, iked_user);
709
710
struct privsep_pipes {
711
  int       *pp_pipes[PROC_MAX];
712
};
713
714
struct privsep {
715
  struct privsep_pipes    *ps_pipes[PROC_MAX];
716
  struct privsep_pipes    *ps_pp;
717
718
  struct imsgev     *ps_ievs[PROC_MAX];
719
  const char      *ps_title[PROC_MAX];
720
  pid_t        ps_pid[PROC_MAX];
721
  struct passwd     *ps_pw;
722
  int        ps_noaction;
723
724
  struct control_sock    ps_csock;
725
  struct control_socks     ps_rcsocks;
726
727
  unsigned int       ps_instances[PROC_MAX];
728
  unsigned int       ps_ninstances;
729
  unsigned int       ps_instance;
730
731
  /* Event and signal handlers */
732
  struct event       ps_evsigint;
733
  struct event       ps_evsigterm;
734
  struct event       ps_evsigchld;
735
  struct event       ps_evsighup;
736
  struct event       ps_evsigpipe;
737
  struct event       ps_evsigusr1;
738
739
  struct iked     *ps_env;
740
};
741
742
struct privsep_proc {
743
  const char    *p_title;
744
  enum privsep_procid  p_id;
745
  int     (*p_cb)(int, struct privsep_proc *,
746
            struct imsg *);
747
  void      (*p_init)(struct privsep *,
748
            struct privsep_proc *);
749
  const char    *p_chroot;
750
  struct passwd   *p_pw;
751
  struct privsep    *p_ps;
752
  void      (*p_shutdown)(void);
753
};
754
755
struct privsep_fd {
756
  enum privsep_procid    pf_procid;
757
  unsigned int       pf_instance;
758
};
759
760
#define PROC_PARENT_SOCK_FILENO 3
761
#define PROC_MAX_INSTANCES      32
762
763
struct iked_ocsp_entry {
764
  TAILQ_ENTRY(iked_ocsp_entry) ioe_entry; /* next request */
765
  void      *ioe_ocsp;  /* private ocsp request data */
766
};
767
TAILQ_HEAD(iked_ocsp_requests, iked_ocsp_entry);
768
769
/*
770
 * Daemon configuration
771
 */
772
773
enum natt_mode {
774
  NATT_DEFAULT, /* send/recv with both :500 and NAT-T port */
775
  NATT_DISABLE, /* send/recv with only :500 */
776
  NATT_FORCE, /* send/recv with only NAT-T port */
777
};
778
779
struct iked_static {
780
  uint64_t     st_alive_timeout;
781
  int      st_enforcesingleikesa;
782
  uint8_t      st_frag; /* fragmentation */
783
  uint8_t      st_mobike; /* MOBIKE */
784
  in_port_t    st_nattport;
785
  int      st_stickyaddress; /* addr per DSTID  */
786
  int      st_vendorid;
787
};
788
789
struct iked {
790
  char         sc_conffile[PATH_MAX];
791
792
  uint32_t       sc_opts;
793
  enum natt_mode       sc_nattmode;
794
  uint8_t        sc_passive;
795
  uint8_t        sc_decoupled;
796
797
  struct iked_static     sc_static;
798
799
#define sc_alive_timeout  sc_static.st_alive_timeout
800
#define sc_enforcesingleikesa sc_static.st_enforcesingleikesa
801
#define sc_frag     sc_static.st_frag
802
#define sc_mobike   sc_static.st_mobike
803
#define sc_nattport   sc_static.st_nattport
804
#define sc_stickyaddress  sc_static.st_stickyaddress
805
#define sc_vendorid   sc_static.st_vendorid
806
807
  struct iked_policies     sc_policies;
808
  struct iked_policy    *sc_defaultcon;
809
810
  struct iked_sas      sc_sas;
811
  struct iked_dstid_sas    sc_dstid_sas;
812
  struct iked_activesas    sc_activesas;
813
  struct iked_flows    sc_activeflows;
814
  struct iked_users    sc_users;
815
816
  struct iked_stats    sc_stats;
817
818
  void        *sc_priv; /* per-process */
819
820
  int        sc_pfkey;  /* ike process */
821
  struct event       sc_pfkeyev;
822
  struct event       sc_routeev;
823
  uint8_t        sc_certreqtype;
824
  struct ibuf     *sc_certreq;
825
  void        *sc_vroute;
826
827
  struct iked_socket    *sc_sock4[2];
828
  struct iked_socket    *sc_sock6[2];
829
830
  struct iked_timer    sc_inittmr;
831
#define IKED_INITIATOR_INITIAL     2
832
#define IKED_INITIATOR_INTERVAL    60
833
834
  struct privsep       sc_ps;
835
836
  struct iked_ocsp_requests  sc_ocsp;
837
  char        *sc_ocsp_url;
838
  long         sc_ocsp_tolerate;
839
  long         sc_ocsp_maxage;
840
841
  struct iked_addrpool     sc_addrpool;
842
  struct iked_addrpool6    sc_addrpool6;
843
844
  int        sc_cert_partial_chain;
845
#ifdef WITH_APPARMOR
846
  int        sc_apparmor;
847
#endif
848
};
849
850
struct iked_socket {
851
  int      sock_fd;
852
  struct event     sock_ev;
853
  struct iked   *sock_env;
854
  struct sockaddr_storage  sock_addr;
855
};
856
857
struct ipsec_xf {
858
  const char  *name;
859
  unsigned int   id;
860
  unsigned int   length;
861
  unsigned int   keylength;
862
  unsigned int   nonce;
863
  unsigned int   noauth;
864
};
865
866
struct ipsec_transforms {
867
  const struct ipsec_xf **authxf;
868
  unsigned int      nauthxf;
869
  const struct ipsec_xf **prfxf;
870
  unsigned int      nprfxf;
871
  const struct ipsec_xf **encxf;
872
  unsigned int      nencxf;
873
  const struct ipsec_xf **groupxf;
874
  unsigned int      ngroupxf;
875
  const struct ipsec_xf **esnxf;
876
  unsigned int      nesnxf;
877
};
878
879
struct ipsec_mode {
880
  struct ipsec_transforms **xfs;
881
  unsigned int      nxfs;
882
};
883
884
/* iked.c */
885
void   parent_reload(struct iked *, int, const char *);
886
887
extern struct iked  *iked_env;
888
889
/* control.c */
890
void   control(struct privsep *, struct privsep_proc *);
891
int  control_init(struct privsep *, struct control_sock *);
892
int  control_listen(struct control_sock *);
893
894
/* config.c */
895
struct iked_policy *
896
   config_new_policy(struct iked *);
897
void   config_free_kex(struct iked_kex *);
898
void   config_free_fragments(struct iked_frag *);
899
void   config_free_sa(struct iked *, struct iked_sa *);
900
struct iked_sa *
901
   config_new_sa(struct iked *, int);
902
struct iked_user *
903
   config_new_user(struct iked *, struct iked_user *);
904
uint64_t
905
   config_getspi(void);
906
struct iked_transform *
907
   config_findtransform(struct iked_proposals *, uint8_t, unsigned int);
908
struct iked_transform *
909
   config_findtransform_ext(struct iked_proposals *, uint8_t,int, unsigned int);
910
void   config_free_policy(struct iked *, struct iked_policy *);
911
struct iked_proposal *
912
   config_add_proposal(struct iked_proposals *, unsigned int,
913
      unsigned int);
914
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
915
void   config_free_proposals(struct iked_proposals *, unsigned int);
916
void   config_free_flows(struct iked *, struct iked_flows *);
917
void   config_free_childsas(struct iked *, struct iked_childsas *,
918
      struct iked_spi *, struct iked_spi *);
919
int  config_add_transform(struct iked_proposal *,
920
      unsigned int, unsigned int, unsigned int, unsigned int);
921
int  config_setcoupled(struct iked *, unsigned int);
922
int  config_getcoupled(struct iked *, unsigned int);
923
int  config_setmode(struct iked *, unsigned int);
924
int  config_getmode(struct iked *, unsigned int);
925
int  config_setreset(struct iked *, unsigned int, enum privsep_procid);
926
int  config_getreset(struct iked *, struct imsg *);
927
int  config_doreset(struct iked *, unsigned int);
928
int  config_setpolicy(struct iked *, struct iked_policy *,
929
      enum privsep_procid);
930
int  config_getpolicy(struct iked *, struct imsg *);
931
int  config_setflow(struct iked *, struct iked_policy *,
932
      enum privsep_procid);
933
int  config_getflow(struct iked *, struct imsg *);
934
int  config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t,
935
      enum privsep_procid, int);
936
int  config_getsocket(struct iked *env, struct imsg *,
937
      void (*cb)(int, short, void *));
938
int  config_setpfkey(struct iked *);
939
int  config_getpfkey(struct iked *, struct imsg *);
940
int  config_setuser(struct iked *, struct iked_user *, enum privsep_procid);
941
int  config_getuser(struct iked *, struct imsg *);
942
int  config_setcompile(struct iked *, enum privsep_procid);
943
int  config_getcompile(struct iked *);
944
int  config_setocsp(struct iked *);
945
int  config_getocsp(struct iked *, struct imsg *);
946
int  config_setkeys(struct iked *);
947
int  config_getkey(struct iked *, struct imsg *);
948
int  config_setstatic(struct iked *);
949
int  config_getstatic(struct iked *, struct imsg *);
950
int  config_setcertpartialchain(struct iked *);
951
int  config_getcertpartialchain(struct iked *, struct imsg *);
952
953
/* policy.c */
954
void   policy_init(struct iked *);
955
int  policy_lookup(struct iked *, struct iked_message *,
956
      struct iked_proposals *, struct iked_flows *, int);
957
int  policy_lookup_sa(struct iked *, struct iked_sa *);
958
struct iked_policy *
959
   policy_test(struct iked *, struct iked_policy *);
960
int  policy_generate_ts(struct iked_policy *);
961
void   policy_calc_skip_steps(struct iked_policies *);
962
void   policy_ref(struct iked *, struct iked_policy *);
963
void   policy_unref(struct iked *, struct iked_policy *);
964
void   sa_state(struct iked *, struct iked_sa *, int);
965
void   sa_stateflags(struct iked_sa *, unsigned int);
966
int  sa_stateok(const struct iked_sa *, int);
967
struct iked_sa *
968
   sa_new(struct iked *, uint64_t, uint64_t, unsigned int,
969
      struct iked_policy *);
970
void   sa_free(struct iked *, struct iked_sa *);
971
void   sa_free_flows(struct iked *, struct iked_saflows *);
972
int  sa_configure_iface(struct iked *, struct iked_sa *, int);
973
int  sa_address(struct iked_sa *, struct iked_addr *, struct sockaddr *);
974
void   childsa_free(struct iked_childsa *);
975
struct iked_childsa *
976
   childsa_lookup(struct iked_sa *, uint64_t, uint8_t);
977
void   flow_free(struct iked_flow *);
978
int  flow_equal(struct iked_flow *, struct iked_flow *);
979
struct iked_sa *
980
   sa_lookup(struct iked *, uint64_t, uint64_t, unsigned int);
981
struct iked_user *
982
   user_lookup(struct iked *, const char *);
983
struct iked_sa *
984
   sa_dstid_lookup(struct iked *, struct iked_sa *);
985
struct iked_sa *
986
   sa_dstid_insert(struct iked *, struct iked_sa *);
987
void   sa_dstid_remove(struct iked *, struct iked_sa *);
988
int  proposals_negotiate(struct iked_proposals *, struct iked_proposals *,
989
      struct iked_proposals *, int, int);
990
RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
991
RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
992
RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
993
RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
994
RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
995
RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
996
RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
997
998
/* crypto.c */
999
struct iked_hash *
1000
   hash_new(uint8_t, uint16_t);
1001
struct ibuf *
1002
   hash_setkey(struct iked_hash *, void *, size_t);
1003
void   hash_free(struct iked_hash *);
1004
void   hash_init(struct iked_hash *);
1005
void   hash_update(struct iked_hash *, void *, size_t);
1006
void   hash_final(struct iked_hash *, void *, size_t *);
1007
size_t   hash_keylength(struct iked_hash *);
1008
size_t   hash_length(struct iked_hash *);
1009
1010
struct iked_cipher *
1011
   cipher_new(uint8_t, uint16_t, uint16_t);
1012
struct ibuf *
1013
   cipher_setkey(struct iked_cipher *, const void *, size_t);
1014
struct ibuf *
1015
   cipher_setiv(struct iked_cipher *, const void *, size_t);
1016
int  cipher_settag(struct iked_cipher *, uint8_t *, size_t);
1017
int  cipher_gettag(struct iked_cipher *, uint8_t *, size_t);
1018
void   cipher_free(struct iked_cipher *);
1019
int  cipher_init(struct iked_cipher *, int);
1020
int  cipher_init_encrypt(struct iked_cipher *);
1021
int  cipher_init_decrypt(struct iked_cipher *);
1022
void   cipher_aad(struct iked_cipher *, const void *, size_t, size_t *);
1023
int  cipher_update(struct iked_cipher *, const void *, size_t, void *, size_t *);
1024
int  cipher_final(struct iked_cipher *);
1025
size_t   cipher_length(struct iked_cipher *);
1026
size_t   cipher_keylength(struct iked_cipher *);
1027
size_t   cipher_ivlength(struct iked_cipher *);
1028
size_t   cipher_outlength(struct iked_cipher *, size_t);
1029
1030
struct iked_dsa *
1031
   dsa_new(uint8_t, struct iked_hash *, int);
1032
struct iked_dsa *
1033
   dsa_sign_new(uint8_t, struct iked_hash *);
1034
struct iked_dsa *
1035
   dsa_verify_new(uint8_t, struct iked_hash *);
1036
struct ibuf *
1037
   dsa_setkey(struct iked_dsa *, void *, size_t, uint8_t);
1038
void   dsa_free(struct iked_dsa *);
1039
int  dsa_init(struct iked_dsa *, const void *, size_t);
1040
size_t   dsa_prefix(struct iked_dsa *);
1041
size_t   dsa_length(struct iked_dsa *);
1042
int  dsa_update(struct iked_dsa *, const void *, size_t);
1043
ssize_t  dsa_sign_final(struct iked_dsa *, void *, size_t);
1044
ssize_t  dsa_verify_final(struct iked_dsa *, void *, size_t);
1045
1046
/* vroute.c */
1047
void vroute_init(struct iked *);
1048
int vroute_setaddr(struct iked *, int, struct sockaddr *, int, unsigned int);
1049
void vroute_cleanup(struct iked *);
1050
int vroute_getaddr(struct iked *, struct imsg *);
1051
int vroute_setdns(struct iked *, int, struct sockaddr *, unsigned int);
1052
int vroute_getdns(struct iked *, struct imsg *);
1053
int vroute_setaddroute(struct iked *, uint8_t, struct sockaddr *,
1054
    uint8_t, struct sockaddr *);
1055
int vroute_setcloneroute(struct iked *, uint8_t, struct sockaddr *,
1056
    uint8_t, struct sockaddr *);
1057
int vroute_setdelroute(struct iked *, uint8_t, struct sockaddr *,
1058
    uint8_t, struct sockaddr *);
1059
int vroute_getroute(struct iked *, struct imsg *);
1060
int vroute_getcloneroute(struct iked *, struct imsg *);
1061
1062
/* ikev2.c */
1063
void   ikev2(struct privsep *, struct privsep_proc *);
1064
void   ikev2_recv(struct iked *, struct iked_message *);
1065
void   ikev2_init_ike_sa(struct iked *, void *);
1066
int  ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
1067
int  ikev2_childsa_enable(struct iked *, struct iked_sa *);
1068
int  ikev2_childsa_delete(struct iked *, struct iked_sa *,
1069
      uint8_t, uint64_t, uint64_t *, int);
1070
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
1071
void   ikev2_ike_sa_timeout(struct iked *env, void *);
1072
void   ikev2_ike_sa_setreason(struct iked_sa *, char *);
1073
void   ikev2_reset_alive_timer(struct iked *);
1074
int  ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
1075
1076
struct ibuf *
1077
   ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
1078
      size_t);
1079
ssize_t  ikev2_psk(struct iked_sa *, uint8_t *, size_t, uint8_t **);
1080
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
1081
      void *, size_t, unsigned int, int);
1082
void   ikev2_enable_natt(struct iked *, struct iked_sa *,
1083
      struct iked_message *, int);
1084
int  ikev2_send_informational(struct iked *, struct iked_message *);
1085
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
1086
      uint8_t, uint8_t, int);
1087
struct ike_header *
1088
   ikev2_add_header(struct ibuf *, struct iked_sa *,
1089
      uint32_t, uint8_t, uint8_t, uint8_t);
1090
int  ikev2_set_header(struct ike_header *, size_t);
1091
struct ikev2_payload *
1092
   ikev2_add_payload(struct ibuf *);
1093
int  ikev2_next_payload(struct ikev2_payload *, size_t,
1094
      uint8_t);
1095
int  ikev2_child_sa_acquire(struct iked *, struct iked_flow *);
1096
int  ikev2_child_sa_drop(struct iked *, struct iked_spi *);
1097
int  ikev2_child_sa_rekey(struct iked *, struct iked_spi *);
1098
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
1099
int  ikev2_print_id(struct iked_id *, char *, size_t);
1100
int  ikev2_print_static_id(struct iked_static_id *, char *, size_t);
1101
1102
const char  *ikev2_ikesa_info(uint64_t, const char *msg);
1103
#define SPI_IH(hdr)      ikev2_ikesa_info(betoh64((hdr)->ike_ispi), NULL)
1104
7.69k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.69k
#define SPI_SA(sa, f)    SPI_SH(&(sa)->sa_hdr, (f))
1106
1107
/* ikev2_msg.c */
1108
void   ikev2_msg_cb(int, short, void *);
1109
struct ibuf *
1110
   ikev2_msg_init(struct iked *, struct iked_message *,
1111
      struct sockaddr_storage *, socklen_t,
1112
      struct sockaddr_storage *, socklen_t, int);
1113
struct iked_message *
1114
   ikev2_msg_copy(struct iked *, struct iked_message *);
1115
void   ikev2_msg_cleanup(struct iked *, struct iked_message *);
1116
uint32_t
1117
   ikev2_msg_id(struct iked *, struct iked_sa *);
1118
struct ibuf
1119
  *ikev2_msg_auth(struct iked *, struct iked_sa *, int);
1120
int  ikev2_msg_authsign(struct iked *, struct iked_sa *,
1121
      struct iked_auth *, struct ibuf *);
1122
int  ikev2_msg_authverify(struct iked *, struct iked_sa *,
1123
      struct iked_auth *, uint8_t *, size_t, struct ibuf *);
1124
int  ikev2_msg_valid_ike_sa(struct iked *, struct ike_header *,
1125
      struct iked_message *);
1126
int  ikev2_msg_send(struct iked *, struct iked_message *);
1127
int  ikev2_msg_send_encrypt(struct iked *, struct iked_sa *,
1128
      struct ibuf **, uint8_t, uint8_t, int);
1129
struct ibuf
1130
  *ikev2_msg_encrypt(struct iked *, struct iked_sa *, struct ibuf *,
1131
      struct ibuf *);
1132
struct ibuf *
1133
   ikev2_msg_decrypt(struct iked *, struct iked_sa *,
1134
      struct ibuf *, struct ibuf *);
1135
int  ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
1136
int  ikev2_msg_frompeer(struct iked_message *);
1137
struct iked_socket *
1138
   ikev2_msg_getsocket(struct iked *, int, int);
1139
int  ikev2_msg_enqueue(struct iked *, struct iked_msgqueue *,
1140
      struct iked_message *, int);
1141
int  ikev2_msg_retransmit_response(struct iked *, struct iked_sa *,
1142
      struct iked_message *, uint8_t);
1143
void   ikev2_msg_prevail(struct iked *, struct iked_msgqueue *,
1144
      struct iked_message *);
1145
void   ikev2_msg_dispose(struct iked *, struct iked_msgqueue *,
1146
      struct iked_msg_retransmit *);
1147
void   ikev2_msg_flushqueue(struct iked *, struct iked_msgqueue *);
1148
struct iked_msg_retransmit *
1149
   ikev2_msg_lookup(struct iked *, struct iked_msgqueue *,
1150
      struct iked_message *, uint8_t);
1151
1152
/* ikev2_pld.c */
1153
int  ikev2_pld_parse(struct iked *, struct ike_header *,
1154
      struct iked_message *, size_t);
1155
1156
/* eap.c */
1157
int  eap_parse(struct iked *, const struct iked_sa *, struct iked_message*,
1158
      void *, int);
1159
int  eap_success(struct iked *, struct iked_sa *, int);
1160
int  eap_identity_request(struct iked *, struct iked_sa *);
1161
int  eap_mschap_challenge(struct iked *, struct iked_sa *, int, int,
1162
      uint8_t *, size_t);
1163
int  eap_mschap_success(struct iked *, struct iked_sa *, int);
1164
int  eap_challenge_request(struct iked *, struct iked_sa *, int);
1165
1166
/* pfkey.c */
1167
int  pfkey_couple(struct iked *, struct iked_sas *, int);
1168
int  pfkey_flow_add(struct iked *, struct iked_flow *);
1169
int  pfkey_flow_delete(struct iked *, struct iked_flow *);
1170
int  pfkey_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1171
int  pfkey_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1172
int  pfkey_sa_update_addresses(struct iked *, struct iked_childsa *);
1173
int  pfkey_sa_delete(struct iked *, struct iked_childsa *);
1174
int  pfkey_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1175
int  pfkey_flush(struct iked *);
1176
int  pfkey_socket(struct iked *);
1177
void   pfkey_init(struct iked *, int fd);
1178
1179
/* ipsec.c */
1180
int  ipsec_couple(struct iked *, struct iked_sas *, int);
1181
int  ipsec_flow_add(struct iked *, struct iked_flow *);
1182
int  ipsec_flow_delete(struct iked *, struct iked_flow *);
1183
int  ipsec_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1184
int  ipsec_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1185
int  ipsec_sa_update_addresses(struct iked *, struct iked_childsa *);
1186
int  ipsec_sa_delete(struct iked *, struct iked_childsa *);
1187
int  ipsec_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1188
int  ipsec_sa_rpl(struct iked *, struct iked_childsa *, uint32_t *);
1189
int  ipsec_sa_lifetimes(struct iked *, struct iked_childsa *, struct iked_lifetime *,
1190
       struct iked_lifetime *, struct iked_lifetime *);
1191
int  ipsec_flush(struct iked *);
1192
int  ipsec_socket(struct iked *);
1193
void   ipsec_init(struct iked *, int fd);
1194
1195
/* ca.c */
1196
void   caproc(struct privsep *, struct privsep_proc *);
1197
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
1198
      uint8_t, uint8_t, uint8_t *, size_t, enum privsep_procid);
1199
int  ca_setcert(struct iked *, struct iked_sahdr *, struct iked_id *,
1200
      uint8_t, uint8_t *, size_t, enum privsep_procid);
1201
int  ca_setauth(struct iked *, struct iked_sa *,
1202
      struct ibuf *, enum privsep_procid);
1203
void   ca_getkey(struct privsep *, struct iked_id *, enum imsg_type);
1204
int  ca_certbundle_add(struct ibuf *, struct iked_id *);
1205
int  ca_privkey_serialize(EVP_PKEY *, struct iked_id *);
1206
int  ca_pubkey_serialize(EVP_PKEY *, struct iked_id *);
1207
void   ca_sslinit(void);
1208
void   ca_sslerror(const char *);
1209
char  *ca_asn1_name(uint8_t *, size_t);
1210
void  *ca_x509_name_parse(char *);
1211
void   ca_cert_info(const char *, X509 *);
1212
1213
/* timer.c */
1214
void   timer_set(struct iked *, struct iked_timer *,
1215
      void (*)(struct iked *, void *), void *);
1216
void   timer_add(struct iked *, struct iked_timer *, int);
1217
void   timer_del(struct iked *, struct iked_timer *);
1218
1219
/* proc.c */
1220
void   proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
1221
      int, char **, enum privsep_procid);
1222
void   proc_kill(struct privsep *);
1223
void   proc_connect(struct privsep *);
1224
void   proc_dispatch(int, short event, void *);
1225
void   proc_run(struct privsep *, struct privsep_proc *,
1226
      struct privsep_proc *, unsigned int,
1227
      void (*)(struct privsep *, struct privsep_proc *, void *), void *);
1228
void   imsg_event_add(struct imsgev *);
1229
int  imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
1230
      pid_t, int, void *, uint16_t);
1231
int  imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
1232
      pid_t, int, const struct iovec *, int);
1233
int  proc_compose_imsg(struct privsep *, enum privsep_procid, int,
1234
      uint16_t, uint32_t, int, void *, uint16_t);
1235
int  proc_compose(struct privsep *, enum privsep_procid,
1236
      uint16_t, void *, uint16_t);
1237
int  proc_composev_imsg(struct privsep *, enum privsep_procid, int,
1238
      uint16_t, uint32_t, int, const struct iovec *, int);
1239
int  proc_composev(struct privsep *, enum privsep_procid,
1240
      uint16_t, const struct iovec *, int);
1241
int  proc_forward_imsg(struct privsep *, struct imsg *,
1242
      enum privsep_procid, int);
1243
struct imsgbuf *
1244
   proc_ibuf(struct privsep *, enum privsep_procid, int);
1245
struct imsgev *
1246
   proc_iev(struct privsep *, enum privsep_procid, int);
1247
enum privsep_procid
1248
   proc_getid(struct privsep_proc *, unsigned int, const char *);
1249
int  proc_flush_imsg(struct privsep *, enum privsep_procid, int);
1250
1251
/* util.c */
1252
int  socket_af(struct sockaddr *, in_port_t);
1253
in_port_t
1254
   socket_getport(struct sockaddr *);
1255
int  socket_setport(struct sockaddr *, in_port_t);
1256
int  socket_getaddr(int, struct sockaddr_storage *);
1257
int  socket_bypass(int, struct sockaddr *);
1258
int  udp_bind(struct sockaddr *, in_port_t);
1259
ssize_t  sendtofrom(int, void *, size_t, int, struct sockaddr *,
1260
      socklen_t, struct sockaddr *, socklen_t);
1261
ssize_t  recvfromto(int, void *, size_t, int, struct sockaddr *,
1262
      socklen_t *, struct sockaddr *, socklen_t *);
1263
const char *
1264
   print_spi(uint64_t, int);
1265
const char *
1266
   print_map(unsigned int, struct iked_constmap *);
1267
void   lc_idtype(char *);
1268
void   print_hex(const uint8_t *, off_t, size_t);
1269
void   print_hexval(const uint8_t *, off_t, size_t);
1270
void   print_hexbuf(struct ibuf *);
1271
const char *
1272
   print_bits(unsigned short, unsigned char *);
1273
int  sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
1274
uint8_t mask2prefixlen(struct sockaddr *);
1275
uint8_t mask2prefixlen6(struct sockaddr *);
1276
struct in6_addr *
1277
   prefixlen2mask6(uint8_t, uint32_t *);
1278
uint32_t
1279
   prefixlen2mask(uint8_t);
1280
const char *
1281
   print_addr(void *);
1282
char  *get_string(uint8_t *, size_t);
1283
const char *
1284
   print_proto(uint8_t);
1285
int  expand_string(char *, size_t, const char *, const char *);
1286
uint8_t *string2unicode(const char *, size_t *);
1287
void   print_debug(const char *, ...)
1288
      __attribute__((format(printf, 1, 2)));
1289
void   print_verbose(const char *, ...)
1290
      __attribute__((format(printf, 1, 2)));
1291
1292
/* imsg_util.c */
1293
struct ibuf *
1294
   ibuf_new(const void *, size_t);
1295
struct ibuf *
1296
   ibuf_static(void);
1297
size_t   ibuf_length(struct ibuf *);
1298
int  ibuf_setsize(struct ibuf *, size_t);
1299
struct ibuf *
1300
   ibuf_getdata(struct ibuf *, size_t);
1301
struct ibuf *
1302
   ibuf_dup(struct ibuf *);
1303
struct ibuf *
1304
   ibuf_random(size_t);
1305
1306
/* log.c */
1307
void  log_init(int, int);
1308
void  log_procinit(const char *);
1309
void  log_setverbose(int);
1310
int log_getverbose(void);
1311
void  log_warn(const char *, ...)
1312
      __attribute__((__format__ (printf, 1, 2)));
1313
void  log_warnx(const char *, ...)
1314
      __attribute__((__format__ (printf, 1, 2)));
1315
void  log_info(const char *, ...)
1316
      __attribute__((__format__ (printf, 1, 2)));
1317
void  log_debug(const char *, ...)
1318
      __attribute__((__format__ (printf, 1, 2)));
1319
void  logit(int, const char *, ...)
1320
      __attribute__((__format__ (printf, 2, 3)));
1321
void  vlog(int, const char *, va_list)
1322
      __attribute__((__format__ (printf, 2, 0)));
1323
__dead void fatal(const char *, ...)
1324
      __attribute__((__format__ (printf, 1, 2)));
1325
__dead void fatalx(const char *, ...)
1326
      __attribute__((__format__ (printf, 1, 2)));
1327
1328
/* ocsp.c */
1329
int  ocsp_connect(struct iked *, struct imsg *);
1330
int  ocsp_receive_fd(struct iked *, struct imsg *);
1331
int  ocsp_validate_cert(struct iked *, void *, size_t, struct iked_sahdr,
1332
    uint8_t, X509 *);
1333
1334
/* parse.y */
1335
int  parse_config(const char *, struct iked *);
1336
int  cmdline_symset(char *);
1337
extern const struct ipsec_xf authxfs[];
1338
extern const struct ipsec_xf prfxfs[];
1339
extern const struct ipsec_xf *encxfs;
1340
extern const struct ipsec_xf ikeencxfs[];
1341
extern const struct ipsec_xf ipsecencxfs[];
1342
extern const struct ipsec_xf groupxfs[];
1343
extern const struct ipsec_xf esnxfs[];
1344
extern const struct ipsec_xf methodxfs[];
1345
extern const struct ipsec_xf saxfs[];
1346
extern const struct ipsec_xf cpxfs[];
1347
size_t   keylength_xf(unsigned int, unsigned int, unsigned int);
1348
size_t   noncelength_xf(unsigned int, unsigned int);
1349
int  encxf_noauth(unsigned int);
1350
1351
/* print.c */
1352
void   print_user(struct iked_user *);
1353
void   print_policy(struct iked_policy *);
1354
const char *print_xf(unsigned int, unsigned int, const struct ipsec_xf *);
1355
1356
#endif /* IKED_H */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/ikev2.h.html b/coverage/latest/report/linux/src/openiked-portable/iked/ikev2.h.html index 293bf0209..0dc40f7c0 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/ikev2.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/ikev2.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/ikev2.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2.h,v 1.35 2023/06/28 14:10:24 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_IKEV2_H
21
#define IKED_IKEV2_H
22
23
#include "openbsd-compat.h"
24
25
#define IKEV2_VERSION   0x20  /* IKE version 2.0 */
26
#define IKEV1_VERSION   0x10  /* IKE version 1.0 */
27
28
#define IKEV2_KEYPAD    "Key Pad for IKEv2" /* don't change! */
29
30
/*
31
 * IKEv2 pseudo states
32
 */
33
34
#define IKEV2_STATE_INIT    0 /* new IKE SA */
35
#define IKEV2_STATE_COOKIE    1 /* cookie requested */
36
#define IKEV2_STATE_SA_INIT   2 /* init IKE SA */
37
#define IKEV2_STATE_EAP     3 /* EAP requested */
38
#define IKEV2_STATE_EAP_SUCCESS   4 /* EAP succeeded */
39
#define IKEV2_STATE_AUTH_REQUEST  5 /* auth received */
40
#define IKEV2_STATE_AUTH_SUCCESS  6 /* authenticated */
41
141
#define IKEV2_STATE_VALID   7  /* authenticated AND validated certs */
42
#define IKEV2_STATE_EAP_VALID   8 /* EAP validated */
43
#define IKEV2_STATE_ESTABLISHED   9 /* active IKE SA */
44
#define IKEV2_STATE_CLOSING   10  /* expect delete for this SA */
45
#define IKEV2_STATE_CLOSED    11  /* delete this SA */
46
47
extern struct iked_constmap ikev2_state_map[];
48
49
/*
50
 * "IKEv2 Parameters" based on the official RFC-based assignments by IANA
51
 * (http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.txt)
52
 */
53
54
/*
55
 * IKEv2 definitions of the IKE header
56
 */
57
58
/* IKEv2 exchange types */
59
#define IKEV2_EXCHANGE_IKE_SA_INIT    34  /* Initial Exchange */
60
#define IKEV2_EXCHANGE_IKE_AUTH     35  /* Authentication */
61
#define IKEV2_EXCHANGE_CREATE_CHILD_SA    36  /* Create Child SA */
62
#define IKEV2_EXCHANGE_INFORMATIONAL    37  /* Informational */
63
#define IKEV2_EXCHANGE_IKE_SESSION_RESUME 38  /* RFC5723 */
64
65
extern struct iked_constmap ikev2_exchange_map[];
66
67
/* IKEv2 message flags */
68
#define IKEV2_FLAG_INITIATOR    0x08  /* Sent by the initiator */
69
#define IKEV2_FLAG_OLDVERSION   0x10  /* Supports a higher IKE version */
70
#define IKEV2_FLAG_RESPONSE   0x20  /* Message is a response */
71
72
extern struct iked_constmap ikev2_flag_map[];
73
74
/*
75
 * IKEv2 payloads
76
 */
77
78
struct ikev2_payload {
79
  uint8_t    pld_nextpayload; /* Next payload type */
80
  uint8_t    pld_reserved;    /* Contains the critical bit */
81
  uint16_t   pld_length;    /* Payload length with header */
82
} __packed;
83
84
struct ikev2_frag_payload {
85
  uint16_t   frag_num;    /* current fragment message number */
86
  uint16_t   frag_total;    /* total number of fragment messages */
87
} __packed;
88
89
224k
#define IKEV2_CRITICAL_PAYLOAD  0x01  /* First bit in the reserved field */
90
91
/* IKEv2 payload types */
92
#define IKEV2_PAYLOAD_NONE  0 /* No payload */
93
28.1k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
8.28k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
12.9k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
19.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.80k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
12.1k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
8.17k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
242
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
32.0k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
7.11k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.64k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
18.0k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
224k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
9.77k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
17.0k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
224k
#define IKEV2_PAYLOAD_SKF 53  /* RFC7383 Encrypted Fragment Payload */
111
112
extern struct iked_constmap ikev2_payload_map[];
113
114
/*
115
 * SA payload
116
 */
117
118
struct ikev2_sa_proposal {
119
  uint8_t    sap_more;    /* Last proposal or more */
120
  uint8_t    sap_reserved;    /* Must be set to zero */
121
  uint16_t   sap_length;    /* Proposal length */
122
  uint8_t    sap_proposalnr;  /* Proposal number */
123
  uint8_t    sap_protoid;   /* Protocol Id */
124
  uint8_t    sap_spisize;   /* SPI size */
125
  uint8_t    sap_transforms;  /* Number of transforms */
126
  /* Followed by variable-length SPI */
127
  /* Followed by variable-length transforms */
128
} __packed;
129
130
#define IKEV2_SAP_LAST  0
131
#define IKEV2_SAP_MORE  2
132
133
#define IKEV2_SAPROTO_NONE    0 /* None */
134
#define IKEV2_SAPROTO_IKE   1 /* IKEv2 */
135
#define IKEV2_SAPROTO_AH    2 /* AH */
136
#define IKEV2_SAPROTO_ESP   3 /* ESP */
137
#define IKEV2_SAPROTO_FC_ESP_HEADER 4 /* RFC4595 */
138
#define IKEV2_SAPROTO_FC_CT_AUTH  5 /* RFC4595 */
139
#define IKEV2_SAPROTO_IPCOMP    204 /* private, should be 4 */
140
141
extern struct iked_constmap ikev2_saproto_map[];
142
143
struct ikev2_transform {
144
  uint8_t   xfrm_more;    /* Last transform or more */
145
  uint8_t   xfrm_reserved;    /* Must be set to zero */
146
  uint16_t  xfrm_length;    /* Transform length */
147
  uint8_t   xfrm_type;    /* Transform type */
148
  uint8_t   xfrm_reserved1;   /* Must be set to zero */
149
  uint16_t  xfrm_id;    /* Transform Id */
150
  /* Followed by variable-length transform attributes */
151
} __packed;
152
153
#define IKEV2_XFORM_LAST    0
154
3.09k
#define IKEV2_XFORM_MORE    3
155
156
1.07k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
777
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
567
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
1.00k
#define IKEV2_XFORMTYPE_ESN   5  /* Extended Sequence Numbers */
161
#define IKEV2_XFORMTYPE_MAX   6
162
163
extern struct iked_constmap ikev2_xformtype_map[];
164
165
#define IKEV2_XFORMENCR_NONE    0 /* None */
166
#define IKEV2_XFORMENCR_DES_IV64  1 /* RFC1827 */
167
#define IKEV2_XFORMENCR_DES   2 /* RFC2405 */
168
#define IKEV2_XFORMENCR_3DES    3 /* RFC2451 */
169
#define IKEV2_XFORMENCR_RC5   4 /* RFC2451 */
170
#define IKEV2_XFORMENCR_IDEA    5 /* RFC2451 */
171
#define IKEV2_XFORMENCR_CAST    6 /* RFC2451 */
172
#define IKEV2_XFORMENCR_BLOWFISH  7 /* RFC2451 */
173
#define IKEV2_XFORMENCR_3IDEA   8 /* RFC2451 */
174
#define IKEV2_XFORMENCR_DES_IV32  9 /* DESIV32 */
175
#define IKEV2_XFORMENCR_RC4   10  /* RFC2451 */
176
#define IKEV2_XFORMENCR_NULL    11  /* RFC2410 */
177
#define IKEV2_XFORMENCR_AES_CBC   12  /* RFC3602 */
178
#define IKEV2_XFORMENCR_AES_CTR   13  /* RFC3664 */
179
#define IKEV2_XFORMENCR_AES_CCM_8 14  /* RFC5282 */
180
#define IKEV2_XFORMENCR_AES_CCM_12  15  /* RFC5282 */
181
#define IKEV2_XFORMENCR_AES_CCM_16  16  /* RFC5282 */
182
#define IKEV2_XFORMENCR_AES_GCM_8 18  /* RFC5282 */
183
#define IKEV2_XFORMENCR_AES_GCM_12  19  /* RFC5282 */
184
#define IKEV2_XFORMENCR_AES_GCM_16  20  /* RFC5282 */
185
#define IKEV2_XFORMENCR_NULL_AES_GMAC 21  /* RFC4543 */
186
#define IKEV2_XFORMENCR_XTS_AES   22  /* IEEE P1619 */
187
#define IKEV2_XFORMENCR_CAMELLIA_CBC  23  /* RFC5529 */
188
#define IKEV2_XFORMENCR_CAMELLIA_CTR  24  /* RFC5529 */
189
#define IKEV2_XFORMENCR_CAMELLIA_CCM_8  25  /* RFC5529 */
190
#define IKEV2_XFORMENCR_CAMELLIA_CCM_12 26  /* RFC5529 */
191
#define IKEV2_XFORMENCR_CAMELLIA_CCM_16 27  /* RFC5529 */
192
#define IKEV2_XFORMENCR_CHACHA20_POLY1305 28  /* RFC7634 */
193
194
extern struct iked_constmap ikev2_xformencr_map[];
195
196
#define IKEV2_IPCOMP_OUI    1 /* UNSPECIFIED */
197
#define IKEV2_IPCOMP_DEFLATE    2 /* RFC2394 */
198
#define IKEV2_IPCOMP_LZS    3 /* RFC2395 */
199
#define IKEV2_IPCOMP_LZJH   4 /* RFC3051 */
200
201
extern struct iked_constmap ikev2_ipcomp_map[];
202
203
#define IKEV2_XFORMPRF_HMAC_MD5   1 /* RFC2104 */
204
#define IKEV2_XFORMPRF_HMAC_SHA1  2 /* RFC2104 */
205
#define IKEV2_XFORMPRF_HMAC_TIGER 3 /* RFC2104 */
206
#define IKEV2_XFORMPRF_AES128_XCBC  4 /* RFC3664 */
207
#define IKEV2_XFORMPRF_HMAC_SHA2_256  5 /* RFC4868 */
208
#define IKEV2_XFORMPRF_HMAC_SHA2_384  6 /* RFC4868 */
209
#define IKEV2_XFORMPRF_HMAC_SHA2_512  7 /* RFC4868 */
210
#define IKEV2_XFORMPRF_AES128_CMAC  8 /* RFC4615 */
211
212
extern struct iked_constmap ikev2_xformprf_map[];
213
214
#define IKEV2_XFORMAUTH_NONE    0 /* No Authentication */
215
#define IKEV2_XFORMAUTH_HMAC_MD5_96 1 /* RFC2403 */
216
#define IKEV2_XFORMAUTH_HMAC_SHA1_96  2 /* RFC2404 */
217
#define IKEV2_XFORMAUTH_DES_MAC   3 /* DES-MAC */
218
#define IKEV2_XFORMAUTH_KPDK_MD5  4 /* RFC1826 */
219
#define IKEV2_XFORMAUTH_AES_XCBC_96 5 /* RFC3566 */
220
#define IKEV2_XFORMAUTH_HMAC_MD5_128  6 /* RFC4595 */
221
#define IKEV2_XFORMAUTH_HMAC_SHA1_160 7 /* RFC4595 */
222
#define IKEV2_XFORMAUTH_AES_CMAC_96 8 /* RFC4494 */
223
#define IKEV2_XFORMAUTH_AES_128_GMAC  9 /* RFC4543 */
224
#define IKEV2_XFORMAUTH_AES_192_GMAC  10  /* RFC4543 */
225
#define IKEV2_XFORMAUTH_AES_256_GMAC  11  /* RFC4543 */
226
#define IKEV2_XFORMAUTH_HMAC_SHA2_256_128 12  /* RFC4868 */
227
#define IKEV2_XFORMAUTH_HMAC_SHA2_384_192 13  /* RFC4868 */
228
#define IKEV2_XFORMAUTH_HMAC_SHA2_512_256 14  /* RFC4868 */
229
230
/* Placeholders for AEAD ciphers (only used internally) */
231
#define IKEV2_XFORMAUTH_AES_GCM_8 2018  /* internal */
232
#define IKEV2_XFORMAUTH_AES_GCM_12  2019  /* internal */
233
#define IKEV2_XFORMAUTH_AES_GCM_16  2020  /* internal */
234
235
extern struct iked_constmap ikev2_xformauth_map[];
236
237
#define IKEV2_XFORMDH_NONE    0 /* No DH */
238
#define IKEV2_XFORMDH_MODP_768    1 /* DH Group 1 */
239
#define IKEV2_XFORMDH_MODP_1024   2 /* DH Group 2 */
240
#define IKEV2_XFORMDH_MODP_1536   5 /* DH Group 5 */
241
#define IKEV2_XFORMDH_MODP_2048   14  /* DH Group 14 */
242
#define IKEV2_XFORMDH_MODP_3072   15  /* DH Group 15 */
243
#define IKEV2_XFORMDH_MODP_4096   16  /* DH Group 16 */
244
#define IKEV2_XFORMDH_MODP_6144   17  /* DH Group 17 */
245
#define IKEV2_XFORMDH_MODP_8192   18  /* DH Group 18 */
246
#define IKEV2_XFORMDH_ECP_256   19  /* RFC5114 */
247
#define IKEV2_XFORMDH_ECP_384   20  /* RFC5114 */
248
#define IKEV2_XFORMDH_ECP_521   21  /* RFC5114 */
249
#define IKEV2_XFORMDH_ECP_192   25  /* RFC5114 */
250
#define IKEV2_XFORMDH_ECP_224   26  /* RFC5114 */
251
#define IKEV2_XFORMDH_BRAINPOOL_P224R1  27  /* RFC6954 */
252
#define IKEV2_XFORMDH_BRAINPOOL_P256R1  28  /* RFC6954 */
253
#define IKEV2_XFORMDH_BRAINPOOL_P384R1  29  /* RFC6954 */
254
#define IKEV2_XFORMDH_BRAINPOOL_P512R1  30  /* RFC6954 */
255
#define IKEV2_XFORMDH_CURVE25519  31  /* RFC8031 */
256
#define IKEV2_XFORMDH_X_SNTRUP761X25519 1035  /* private */
257
258
extern struct iked_constmap ikev2_xformdh_map[];
259
260
#define IKEV2_IPV4_OVERHEAD   (20 + 8 + 28) /* IPv4 + UDP + IKE_HDR*/
261
#define IKEV2_MAXLEN_IPV4_FRAG    (576 - IKEV2_IPV4_OVERHEAD)
262
#define IKEV2_IPV6_OVERHEAD   (40 + 8 + 28) /* IPv6 + UDP + IKE_HDR*/
263
#define IKEV2_MAXLEN_IPV6_FRAG    (1280 - IKEV2_IPV6_OVERHEAD)
264
265
#define IKEV2_MAXNUM_TSS    255 /* 8 bit Number of TSs field */
266
267
#define IKEV2_XFORMESN_NONE   0 /* No ESN */
268
#define IKEV2_XFORMESN_ESN    1 /* ESN */
269
270
extern struct iked_constmap ikev2_xformesn_map[];
271
272
struct ikev2_attribute {
273
  uint16_t  attr_type;  /* Attribute type */
274
  uint16_t  attr_length;  /* Attribute length or value */
275
  /* Followed by variable length (TLV) */
276
} __packed;
277
278
#define IKEV2_ATTRAF_TLV    0x0000  /* Type-Length-Value format */
279
57.2k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
22.1k
#define IKEV2_ATTRTYPE_KEY_LENGTH 14  /* Key length */
282
283
extern struct iked_constmap ikev2_attrtype_map[];
284
285
/*
286
 * KE Payload
287
 */
288
289
struct ikev2_keyexchange {
290
  uint16_t   kex_dhgroup;   /* DH Group # */
291
  uint16_t   kex_reserved;    /* Reserved */
292
} __packed;
293
294
/*
295
 * N payload
296
 */
297
298
struct ikev2_notify {
299
  uint8_t    n_protoid;   /* Protocol Id */
300
  uint8_t    n_spisize;   /* SPI size */
301
  uint16_t   n_type;    /* Notify message type */
302
  /* Followed by variable length SPI */
303
  /* Followed by variable length notification data */
304
} __packed;
305
306
#define IKEV2_N_UNSUPPORTED_CRITICAL_PAYLOAD  1 /* RFC7296 */
307
#define IKEV2_N_INVALID_IKE_SPI     4 /* RFC7296 */
308
#define IKEV2_N_INVALID_MAJOR_VERSION   5 /* RFC7296 */
309
#define IKEV2_N_INVALID_SYNTAX      7 /* RFC7296 */
310
#define IKEV2_N_INVALID_MESSAGE_ID    9 /* RFC7296 */
311
#define IKEV2_N_INVALID_SPI     11  /* RFC7296 */
312
36
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
135
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
6
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
241
#define IKEV2_N_NO_ADDITIONAL_SAS   35  /* RFC7296 */
317
#define IKEV2_N_INTERNAL_ADDRESS_FAILURE  36  /* RFC7296 */
318
#define IKEV2_N_FAILED_CP_REQUIRED    37  /* RFC7296 */
319
#define IKEV2_N_TS_UNACCEPTABLE     38  /* RFC7296 */
320
#define IKEV2_N_INVALID_SELECTORS   39  /* RFC7296 */
321
#define IKEV2_N_UNACCEPTABLE_ADDRESSES    40  /* RFC4555 */
322
#define IKEV2_N_UNEXPECTED_NAT_DETECTED   41  /* RFC4555 */
323
#define IKEV2_N_USE_ASSIGNED_HoA    42  /* RFC5026 */
324
348
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
73
#define IKEV2_N_CHILD_SA_NOT_FOUND    44  /* RFC7296 */
326
#define IKEV2_N_INITIAL_CONTACT     16384 /* RFC7296 */
327
#define IKEV2_N_SET_WINDOW_SIZE     16385 /* RFC7296 */
328
#define IKEV2_N_ADDITIONAL_TS_POSSIBLE    16386 /* RFC7296 */
329
255
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
25.6k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
22.6k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
316
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
75
#define IKEV2_N_REKEY_SA      16393  /* RFC7296 */
336
#define IKEV2_N_ESP_TFC_PADDING_NOT_SUPPORTED 16394 /* RFC7296 */
337
#define IKEV2_N_NON_FIRST_FRAGMENTS_ALSO  16395 /* RFC7296 */
338
267
#define IKEV2_N_MOBIKE_SUPPORTED    16396  /* RFC4555 */
339
#define IKEV2_N_ADDITIONAL_IP4_ADDRESS    16397 /* RFC4555 */
340
#define IKEV2_N_ADDITIONAL_IP6_ADDRESS    16398 /* RFC4555 */
341
#define IKEV2_N_NO_ADDITIONAL_ADDRESSES   16399 /* RFC4555 */
342
388
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
202
#define IKEV2_N_COOKIE2       16401  /* RFC4555 */
344
#define IKEV2_N_NO_NATS_ALLOWED     16402 /* RFC4555 */
345
#define IKEV2_N_AUTH_LIFETIME     16403 /* RFC4478 */
346
#define IKEV2_N_MULTIPLE_AUTH_SUPPORTED   16404 /* RFC4739 */
347
#define IKEV2_N_ANOTHER_AUTH_FOLLOWS    16405 /* RFC4739 */
348
#define IKEV2_N_REDIRECT_SUPPORTED    16406 /* RFC5685 */
349
#define IKEV2_N_REDIRECT      16407 /* RFC5685 */
350
#define IKEV2_N_REDIRECTED_FROM     16408 /* RFC5685 */
351
#define IKEV2_N_TICKET_LT_OPAQUE    16409 /* RFC5723 */
352
#define IKEV2_N_TICKET_REQUEST      16410 /* RFC5723 */
353
#define IKEV2_N_TICKET_ACK      16411 /* RFC5723 */
354
#define IKEV2_N_TICKET_NACK     16412 /* RFC5723 */
355
#define IKEV2_N_TICKET_OPAQUE     16413 /* RFC5723 */
356
#define IKEV2_N_LINK_ID       16414 /* RFC5739 */
357
#define IKEV2_N_USE_WESP_MODE     16415 /* RFC5415 */
358
#define IKEV2_N_ROHC_SUPPORTED      16416 /* RFC5857 */
359
#define IKEV2_N_EAP_ONLY_AUTHENTICATION   16417 /* RFC5998 */
360
#define IKEV2_N_CHILDLESS_IKEV2_SUPPORTED 16418 /* RFC6023 */
361
#define IKEV2_N_QUICK_CRASH_DETECTION   16419 /* RFC6290 */
362
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC_SUPPORTED 16420 /* RFC6311 */
363
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC_SUPPORTED 16421 /* RFC6311 */
364
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC   16422 /* RFC6311 */
365
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC   16423 /* RFC6311 */
366
#define IKEV2_N_SECURE_PASSWORD_METHODS   16424 /* RFC6467 */
367
#define IKEV2_N_PSK_PERSIST     16425 /* RFC6631 */
368
#define IKEV2_N_PSK_CONFIRM     16426 /* RFC6631 */
369
#define IKEV2_N_ERX_SUPPORTED     16427 /* RFC6867 */
370
#define IKEV2_N_IFOM_CAPABILITY     16428 /* OA3GPP */
371
14
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
7
#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431  /* RFC7427 */
373
374
extern struct iked_constmap ikev2_n_map[];
375
376
/*
377
 * DELETE payload
378
 */
379
380
struct ikev2_delete {
381
  uint8_t    del_protoid;   /* Protocol Id */
382
  uint8_t    del_spisize;   /* SPI size */
383
  uint16_t   del_nspi;    /* Number of SPIs */
384
  /* Followed by variable length SPIs */
385
} __packed;
386
387
/*
388
 * ID payload
389
 */
390
391
struct ikev2_id {
392
  uint8_t    id_type;   /* Id type */
393
  uint8_t    id_reserved[3];  /* Reserved */
394
  /* Followed by the identification data */
395
} __packed;
396
397
11.8k
#define IKEV2_ID_NONE   0  /* No ID */
398
#define IKEV2_ID_IPV4   1 /* RFC7296 (ID_IPV4_ADDR) */
399
#define IKEV2_ID_FQDN   2 /* RFC7296 */
400
#define IKEV2_ID_UFQDN    3 /* RFC7296 (ID_RFC822_ADDR) */
401
#define IKEV2_ID_IPV6   5 /* RFC7296 (ID_IPV6_ADDR) */
402
#define IKEV2_ID_ASN1_DN  9 /* RFC7296 */
403
#define IKEV2_ID_ASN1_GN  10  /* RFC7296 */
404
#define IKEV2_ID_KEY_ID   11  /* RFC7296 */
405
#define IKEV2_ID_FC_NAME  12  /* RFC4595 */
406
407
extern struct iked_constmap ikev2_id_map[];
408
409
/*
410
 * CERT/CERTREQ payloads
411
 */
412
413
struct ikev2_cert {
414
  uint8_t   cert_type;  /* Encoding */
415
  /* Followed by the certificate data */
416
} __packed;
417
418
4.34k
#define IKEV2_CERT_NONE     0  /* None */
419
#define IKEV2_CERT_X509_PKCS7   1 /* UNSPECIFIED */
420
#define IKEV2_CERT_PGP      2 /* UNSPECIFIED */
421
#define IKEV2_CERT_DNS_SIGNED_KEY 3 /* UNSPECIFIED */
422
1.18k
#define IKEV2_CERT_X509_CERT    4  /* RFC7296 */
423
#define IKEV2_CERT_KERBEROS_TOKEN 6 /* UNSPECIFIED */
424
#define IKEV2_CERT_CRL      7 /* RFC7296 */
425
#define IKEV2_CERT_ARL      8 /* UNSPECIFIED */
426
#define IKEV2_CERT_SPKI     9 /* UNSPECIFIED */
427
#define IKEV2_CERT_X509_ATTR    10  /* UNSPECIFIED */
428
#define IKEV2_CERT_RSA_KEY    11  /* RFC7296 */
429
#define IKEV2_CERT_HASHURL_X509   12  /* RFC7296 */
430
#define IKEV2_CERT_HASHURL_X509_BUNDLE  13  /* RFC7296 */
431
#define IKEV2_CERT_OCSP     14  /* RFC4806 */
432
/*
433
 * As of November 2014, work was still in progress to add a more generic
434
 * format for raw public keys (RFC7296), so we use a number in IANA's private
435
 * use range (201-255, same RFC) for ECDSA.
436
 */
437
#define IKEV2_CERT_ECDSA    201 /* Private */
438
1.94k
#define IKEV2_CERT_BUNDLE   254  /* Private */
439
440
extern struct iked_constmap ikev2_cert_map[];
441
442
/*
443
 * TSi/TSr payloads
444
 */
445
446
struct ikev2_tsp {
447
  uint8_t   tsp_count;    /* Number of TSs */
448
  uint8_t   tsp_reserved[3];  /* Reserved */
449
  /* Followed by the traffic selectors */
450
} __packed;
451
452
struct ikev2_ts {
453
  uint8_t   ts_type;    /* TS type */
454
  uint8_t   ts_protoid;   /* Protocol Id */
455
  uint16_t  ts_length;    /* Length */
456
  uint16_t  ts_startport;   /* Start port */
457
  uint16_t  ts_endport;   /* End port */
458
} __packed;
459
460
6.12k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.35k
#define IKEV2_TS_IPV6_ADDR_RANGE  8  /* RFC7296 */
462
#define IKEV2_TS_FC_ADDR_RANGE    9 /* RFC4595 */
463
464
extern struct iked_constmap ikev2_ts_map[];
465
466
/*
467
 * AUTH payload
468
 */
469
470
struct ikev2_auth {
471
  uint8_t   auth_method;    /* Signature type */
472
  uint8_t   auth_reserved[3]; /* Reserved */
473
  /* Followed by the signature */
474
} __packed;
475
476
#define IKEV2_AUTH_NONE     0 /* None */
477
#define IKEV2_AUTH_RSA_SIG    1 /* RFC7296 */
478
#define IKEV2_AUTH_SHARED_KEY_MIC 2 /* RFC7296 */
479
#define IKEV2_AUTH_DSS_SIG    3 /* RFC7296 */
480
#define IKEV2_AUTH_ECDSA_256    9 /* RFC4754 */
481
#define IKEV2_AUTH_ECDSA_384    10  /* RFC4754 */
482
#define IKEV2_AUTH_ECDSA_521    11  /* RFC4754 */
483
#define IKEV2_AUTH_GSPM     12  /* RFC6467 */
484
#define IKEV2_AUTH_NULL     13  /* RFC7619 */
485
#define IKEV2_AUTH_SIG      14  /* RFC7427 */
486
#define IKEV2_AUTH_SIG_ANY    255 /* Internal (any signature) */
487
/*
488
 * AUTH_SIG also serves as an indication that a given policy has
489
 * been configured to accept RSA or ECDSA payloads, as long as it
490
 * successfully authenticates against a configured CA.
491
 */
492
493
extern struct iked_constmap ikev2_auth_map[];
494
495
/* Notifications used together with IKEV2_AUTH_SIG */
496
497
#define IKEV2_SIGHASH_RESERVED    0 /* RFC7427 */
498
#define IKEV2_SIGHASH_SHA1    1 /* RFC7427 */
499
0
#define IKEV2_SIGHASH_SHA2_256    2  /* RFC7427 */
500
#define IKEV2_SIGHASH_SHA2_384    3 /* RFC7427 */
501
#define IKEV2_SIGHASH_SHA2_512    4 /* RFC7427 */
502
503
extern struct iked_constmap ikev2_sighash_map[];
504
505
/*
506
 * CP payload
507
 */
508
509
struct ikev2_cp {
510
  uint8_t   cp_type;
511
  uint8_t   cp_reserved[3];
512
  /* Followed by the attributes */
513
} __packed;
514
515
#define IKEV2_CP_REQUEST  1 /* CFG-Request */
516
#define IKEV2_CP_REPLY    2 /* CFG-Reply */
517
#define IKEV2_CP_SET    3 /* CFG-SET */
518
#define IKEV2_CP_ACK    4 /* CFG-ACK */
519
520
extern struct iked_constmap ikev2_cp_map[];
521
522
struct ikev2_cfg {
523
  uint16_t  cfg_type; /* first bit must be set to zero */
524
  uint16_t  cfg_length;
525
  /* Followed by variable-length data */
526
} __packed;
527
528
1.31k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.65k
#define IKEV2_CFG_INTERNAL_IP4_DNS    3  /* RFC7296 */
531
#define IKEV2_CFG_INTERNAL_IP4_NBNS   4 /* RFC7296 */
532
#define IKEV2_CFG_INTERNAL_ADDRESS_EXPIRY 5 /* RFC4306 */
533
#define IKEV2_CFG_INTERNAL_IP4_DHCP   6 /* RFC7296 */
534
#define IKEV2_CFG_APPLICATION_VERSION   7 /* RFC7296 */
535
2.37k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
3.10k
#define IKEV2_CFG_INTERNAL_IP6_DNS    10  /* RFC7296 */
537
#define IKEV2_CFG_INTERNAL_IP6_NBNS   11  /* RFC4306 */
538
#define IKEV2_CFG_INTERNAL_IP6_DHCP   12  /* RFC7296 */
539
#define IKEV2_CFG_INTERNAL_IP4_SUBNET   13  /* RFC7296 */
540
#define IKEV2_CFG_SUPPORTED_ATTRIBUTES    14  /* RFC7296 */
541
#define IKEV2_CFG_INTERNAL_IP6_SUBNET   15  /* RFC7296 */
542
#define IKEV2_CFG_MIP6_HOME_PREFIX    16  /* RFC5026 */
543
#define IKEV2_CFG_INTERNAL_IP6_LINK   17  /* RFC5739 */
544
#define IKEV2_CFG_INTERNAL_IP6_PREFIX   18  /* RFC5739 */
545
#define IKEV2_CFG_HOME_AGENT_ADDRESS    19  /* http://www.3gpp.org/ftp/Specs/html-info/24302.htm */
546
#define IKEV2_CFG_INTERNAL_IP4_SERVER   23456 /* MS-IKEE */
547
#define IKEV2_CFG_INTERNAL_IP6_SERVER   23457 /* MS-IKEE */
548
549
extern struct iked_constmap ikev2_cfg_map[];
550
551
/* IKEv1 payload types */
552
#define IKEV1_PAYLOAD_NONE  0 /* No payload */
553
#define IKEV1_PAYLOAD_PROPOSAL  2 /* Proposal */
554
555
#endif /* IKED_IKEV2_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/ikev2.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2.h,v 1.35 2023/06/28 14:10:24 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_IKEV2_H
21
#define IKED_IKEV2_H
22
23
#include "openbsd-compat.h"
24
25
#define IKEV2_VERSION   0x20  /* IKE version 2.0 */
26
#define IKEV1_VERSION   0x10  /* IKE version 1.0 */
27
28
#define IKEV2_KEYPAD    "Key Pad for IKEv2" /* don't change! */
29
30
/*
31
 * IKEv2 pseudo states
32
 */
33
34
#define IKEV2_STATE_INIT    0 /* new IKE SA */
35
#define IKEV2_STATE_COOKIE    1 /* cookie requested */
36
#define IKEV2_STATE_SA_INIT   2 /* init IKE SA */
37
#define IKEV2_STATE_EAP     3 /* EAP requested */
38
#define IKEV2_STATE_EAP_SUCCESS   4 /* EAP succeeded */
39
#define IKEV2_STATE_AUTH_REQUEST  5 /* auth received */
40
#define IKEV2_STATE_AUTH_SUCCESS  6 /* authenticated */
41
141
#define IKEV2_STATE_VALID   7  /* authenticated AND validated certs */
42
#define IKEV2_STATE_EAP_VALID   8 /* EAP validated */
43
#define IKEV2_STATE_ESTABLISHED   9 /* active IKE SA */
44
#define IKEV2_STATE_CLOSING   10  /* expect delete for this SA */
45
#define IKEV2_STATE_CLOSED    11  /* delete this SA */
46
47
extern struct iked_constmap ikev2_state_map[];
48
49
/*
50
 * "IKEv2 Parameters" based on the official RFC-based assignments by IANA
51
 * (http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.txt)
52
 */
53
54
/*
55
 * IKEv2 definitions of the IKE header
56
 */
57
58
/* IKEv2 exchange types */
59
#define IKEV2_EXCHANGE_IKE_SA_INIT    34  /* Initial Exchange */
60
#define IKEV2_EXCHANGE_IKE_AUTH     35  /* Authentication */
61
#define IKEV2_EXCHANGE_CREATE_CHILD_SA    36  /* Create Child SA */
62
#define IKEV2_EXCHANGE_INFORMATIONAL    37  /* Informational */
63
#define IKEV2_EXCHANGE_IKE_SESSION_RESUME 38  /* RFC5723 */
64
65
extern struct iked_constmap ikev2_exchange_map[];
66
67
/* IKEv2 message flags */
68
#define IKEV2_FLAG_INITIATOR    0x08  /* Sent by the initiator */
69
#define IKEV2_FLAG_OLDVERSION   0x10  /* Supports a higher IKE version */
70
#define IKEV2_FLAG_RESPONSE   0x20  /* Message is a response */
71
72
extern struct iked_constmap ikev2_flag_map[];
73
74
/*
75
 * IKEv2 payloads
76
 */
77
78
struct ikev2_payload {
79
  uint8_t    pld_nextpayload; /* Next payload type */
80
  uint8_t    pld_reserved;    /* Contains the critical bit */
81
  uint16_t   pld_length;    /* Payload length with header */
82
} __packed;
83
84
struct ikev2_frag_payload {
85
  uint16_t   frag_num;    /* current fragment message number */
86
  uint16_t   frag_total;    /* total number of fragment messages */
87
} __packed;
88
89
225k
#define IKEV2_CRITICAL_PAYLOAD  0x01  /* First bit in the reserved field */
90
91
/* IKEv2 payload types */
92
#define IKEV2_PAYLOAD_NONE  0 /* No payload */
93
28.2k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
8.28k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
13.0k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
19.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.80k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
12.1k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
8.17k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
242
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
32.4k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
7.11k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.65k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
18.1k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
224k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
9.77k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
17.1k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
224k
#define IKEV2_PAYLOAD_SKF 53  /* RFC7383 Encrypted Fragment Payload */
111
112
extern struct iked_constmap ikev2_payload_map[];
113
114
/*
115
 * SA payload
116
 */
117
118
struct ikev2_sa_proposal {
119
  uint8_t    sap_more;    /* Last proposal or more */
120
  uint8_t    sap_reserved;    /* Must be set to zero */
121
  uint16_t   sap_length;    /* Proposal length */
122
  uint8_t    sap_proposalnr;  /* Proposal number */
123
  uint8_t    sap_protoid;   /* Protocol Id */
124
  uint8_t    sap_spisize;   /* SPI size */
125
  uint8_t    sap_transforms;  /* Number of transforms */
126
  /* Followed by variable-length SPI */
127
  /* Followed by variable-length transforms */
128
} __packed;
129
130
#define IKEV2_SAP_LAST  0
131
#define IKEV2_SAP_MORE  2
132
133
#define IKEV2_SAPROTO_NONE    0 /* None */
134
#define IKEV2_SAPROTO_IKE   1 /* IKEv2 */
135
#define IKEV2_SAPROTO_AH    2 /* AH */
136
#define IKEV2_SAPROTO_ESP   3 /* ESP */
137
#define IKEV2_SAPROTO_FC_ESP_HEADER 4 /* RFC4595 */
138
#define IKEV2_SAPROTO_FC_CT_AUTH  5 /* RFC4595 */
139
#define IKEV2_SAPROTO_IPCOMP    204 /* private, should be 4 */
140
141
extern struct iked_constmap ikev2_saproto_map[];
142
143
struct ikev2_transform {
144
  uint8_t   xfrm_more;    /* Last transform or more */
145
  uint8_t   xfrm_reserved;    /* Must be set to zero */
146
  uint16_t  xfrm_length;    /* Transform length */
147
  uint8_t   xfrm_type;    /* Transform type */
148
  uint8_t   xfrm_reserved1;   /* Must be set to zero */
149
  uint16_t  xfrm_id;    /* Transform Id */
150
  /* Followed by variable-length transform attributes */
151
} __packed;
152
153
#define IKEV2_XFORM_LAST    0
154
3.10k
#define IKEV2_XFORM_MORE    3
155
156
1.07k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
777
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
567
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
1.00k
#define IKEV2_XFORMTYPE_ESN   5  /* Extended Sequence Numbers */
161
#define IKEV2_XFORMTYPE_MAX   6
162
163
extern struct iked_constmap ikev2_xformtype_map[];
164
165
#define IKEV2_XFORMENCR_NONE    0 /* None */
166
#define IKEV2_XFORMENCR_DES_IV64  1 /* RFC1827 */
167
#define IKEV2_XFORMENCR_DES   2 /* RFC2405 */
168
#define IKEV2_XFORMENCR_3DES    3 /* RFC2451 */
169
#define IKEV2_XFORMENCR_RC5   4 /* RFC2451 */
170
#define IKEV2_XFORMENCR_IDEA    5 /* RFC2451 */
171
#define IKEV2_XFORMENCR_CAST    6 /* RFC2451 */
172
#define IKEV2_XFORMENCR_BLOWFISH  7 /* RFC2451 */
173
#define IKEV2_XFORMENCR_3IDEA   8 /* RFC2451 */
174
#define IKEV2_XFORMENCR_DES_IV32  9 /* DESIV32 */
175
#define IKEV2_XFORMENCR_RC4   10  /* RFC2451 */
176
#define IKEV2_XFORMENCR_NULL    11  /* RFC2410 */
177
#define IKEV2_XFORMENCR_AES_CBC   12  /* RFC3602 */
178
#define IKEV2_XFORMENCR_AES_CTR   13  /* RFC3664 */
179
#define IKEV2_XFORMENCR_AES_CCM_8 14  /* RFC5282 */
180
#define IKEV2_XFORMENCR_AES_CCM_12  15  /* RFC5282 */
181
#define IKEV2_XFORMENCR_AES_CCM_16  16  /* RFC5282 */
182
#define IKEV2_XFORMENCR_AES_GCM_8 18  /* RFC5282 */
183
#define IKEV2_XFORMENCR_AES_GCM_12  19  /* RFC5282 */
184
#define IKEV2_XFORMENCR_AES_GCM_16  20  /* RFC5282 */
185
#define IKEV2_XFORMENCR_NULL_AES_GMAC 21  /* RFC4543 */
186
#define IKEV2_XFORMENCR_XTS_AES   22  /* IEEE P1619 */
187
#define IKEV2_XFORMENCR_CAMELLIA_CBC  23  /* RFC5529 */
188
#define IKEV2_XFORMENCR_CAMELLIA_CTR  24  /* RFC5529 */
189
#define IKEV2_XFORMENCR_CAMELLIA_CCM_8  25  /* RFC5529 */
190
#define IKEV2_XFORMENCR_CAMELLIA_CCM_12 26  /* RFC5529 */
191
#define IKEV2_XFORMENCR_CAMELLIA_CCM_16 27  /* RFC5529 */
192
#define IKEV2_XFORMENCR_CHACHA20_POLY1305 28  /* RFC7634 */
193
194
extern struct iked_constmap ikev2_xformencr_map[];
195
196
#define IKEV2_IPCOMP_OUI    1 /* UNSPECIFIED */
197
#define IKEV2_IPCOMP_DEFLATE    2 /* RFC2394 */
198
#define IKEV2_IPCOMP_LZS    3 /* RFC2395 */
199
#define IKEV2_IPCOMP_LZJH   4 /* RFC3051 */
200
201
extern struct iked_constmap ikev2_ipcomp_map[];
202
203
#define IKEV2_XFORMPRF_HMAC_MD5   1 /* RFC2104 */
204
#define IKEV2_XFORMPRF_HMAC_SHA1  2 /* RFC2104 */
205
#define IKEV2_XFORMPRF_HMAC_TIGER 3 /* RFC2104 */
206
#define IKEV2_XFORMPRF_AES128_XCBC  4 /* RFC3664 */
207
#define IKEV2_XFORMPRF_HMAC_SHA2_256  5 /* RFC4868 */
208
#define IKEV2_XFORMPRF_HMAC_SHA2_384  6 /* RFC4868 */
209
#define IKEV2_XFORMPRF_HMAC_SHA2_512  7 /* RFC4868 */
210
#define IKEV2_XFORMPRF_AES128_CMAC  8 /* RFC4615 */
211
212
extern struct iked_constmap ikev2_xformprf_map[];
213
214
#define IKEV2_XFORMAUTH_NONE    0 /* No Authentication */
215
#define IKEV2_XFORMAUTH_HMAC_MD5_96 1 /* RFC2403 */
216
#define IKEV2_XFORMAUTH_HMAC_SHA1_96  2 /* RFC2404 */
217
#define IKEV2_XFORMAUTH_DES_MAC   3 /* DES-MAC */
218
#define IKEV2_XFORMAUTH_KPDK_MD5  4 /* RFC1826 */
219
#define IKEV2_XFORMAUTH_AES_XCBC_96 5 /* RFC3566 */
220
#define IKEV2_XFORMAUTH_HMAC_MD5_128  6 /* RFC4595 */
221
#define IKEV2_XFORMAUTH_HMAC_SHA1_160 7 /* RFC4595 */
222
#define IKEV2_XFORMAUTH_AES_CMAC_96 8 /* RFC4494 */
223
#define IKEV2_XFORMAUTH_AES_128_GMAC  9 /* RFC4543 */
224
#define IKEV2_XFORMAUTH_AES_192_GMAC  10  /* RFC4543 */
225
#define IKEV2_XFORMAUTH_AES_256_GMAC  11  /* RFC4543 */
226
#define IKEV2_XFORMAUTH_HMAC_SHA2_256_128 12  /* RFC4868 */
227
#define IKEV2_XFORMAUTH_HMAC_SHA2_384_192 13  /* RFC4868 */
228
#define IKEV2_XFORMAUTH_HMAC_SHA2_512_256 14  /* RFC4868 */
229
230
/* Placeholders for AEAD ciphers (only used internally) */
231
#define IKEV2_XFORMAUTH_AES_GCM_8 2018  /* internal */
232
#define IKEV2_XFORMAUTH_AES_GCM_12  2019  /* internal */
233
#define IKEV2_XFORMAUTH_AES_GCM_16  2020  /* internal */
234
235
extern struct iked_constmap ikev2_xformauth_map[];
236
237
#define IKEV2_XFORMDH_NONE    0 /* No DH */
238
#define IKEV2_XFORMDH_MODP_768    1 /* DH Group 1 */
239
#define IKEV2_XFORMDH_MODP_1024   2 /* DH Group 2 */
240
#define IKEV2_XFORMDH_MODP_1536   5 /* DH Group 5 */
241
#define IKEV2_XFORMDH_MODP_2048   14  /* DH Group 14 */
242
#define IKEV2_XFORMDH_MODP_3072   15  /* DH Group 15 */
243
#define IKEV2_XFORMDH_MODP_4096   16  /* DH Group 16 */
244
#define IKEV2_XFORMDH_MODP_6144   17  /* DH Group 17 */
245
#define IKEV2_XFORMDH_MODP_8192   18  /* DH Group 18 */
246
#define IKEV2_XFORMDH_ECP_256   19  /* RFC5114 */
247
#define IKEV2_XFORMDH_ECP_384   20  /* RFC5114 */
248
#define IKEV2_XFORMDH_ECP_521   21  /* RFC5114 */
249
#define IKEV2_XFORMDH_ECP_192   25  /* RFC5114 */
250
#define IKEV2_XFORMDH_ECP_224   26  /* RFC5114 */
251
#define IKEV2_XFORMDH_BRAINPOOL_P224R1  27  /* RFC6954 */
252
#define IKEV2_XFORMDH_BRAINPOOL_P256R1  28  /* RFC6954 */
253
#define IKEV2_XFORMDH_BRAINPOOL_P384R1  29  /* RFC6954 */
254
#define IKEV2_XFORMDH_BRAINPOOL_P512R1  30  /* RFC6954 */
255
#define IKEV2_XFORMDH_CURVE25519  31  /* RFC8031 */
256
#define IKEV2_XFORMDH_X_SNTRUP761X25519 1035  /* private */
257
258
extern struct iked_constmap ikev2_xformdh_map[];
259
260
#define IKEV2_IPV4_OVERHEAD   (20 + 8 + 28) /* IPv4 + UDP + IKE_HDR*/
261
#define IKEV2_MAXLEN_IPV4_FRAG    (576 - IKEV2_IPV4_OVERHEAD)
262
#define IKEV2_IPV6_OVERHEAD   (40 + 8 + 28) /* IPv6 + UDP + IKE_HDR*/
263
#define IKEV2_MAXLEN_IPV6_FRAG    (1280 - IKEV2_IPV6_OVERHEAD)
264
265
#define IKEV2_MAXNUM_TSS    255 /* 8 bit Number of TSs field */
266
267
#define IKEV2_XFORMESN_NONE   0 /* No ESN */
268
#define IKEV2_XFORMESN_ESN    1 /* ESN */
269
270
extern struct iked_constmap ikev2_xformesn_map[];
271
272
struct ikev2_attribute {
273
  uint16_t  attr_type;  /* Attribute type */
274
  uint16_t  attr_length;  /* Attribute length or value */
275
  /* Followed by variable length (TLV) */
276
} __packed;
277
278
#define IKEV2_ATTRAF_TLV    0x0000  /* Type-Length-Value format */
279
57.2k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
22.1k
#define IKEV2_ATTRTYPE_KEY_LENGTH 14  /* Key length */
282
283
extern struct iked_constmap ikev2_attrtype_map[];
284
285
/*
286
 * KE Payload
287
 */
288
289
struct ikev2_keyexchange {
290
  uint16_t   kex_dhgroup;   /* DH Group # */
291
  uint16_t   kex_reserved;    /* Reserved */
292
} __packed;
293
294
/*
295
 * N payload
296
 */
297
298
struct ikev2_notify {
299
  uint8_t    n_protoid;   /* Protocol Id */
300
  uint8_t    n_spisize;   /* SPI size */
301
  uint16_t   n_type;    /* Notify message type */
302
  /* Followed by variable length SPI */
303
  /* Followed by variable length notification data */
304
} __packed;
305
306
#define IKEV2_N_UNSUPPORTED_CRITICAL_PAYLOAD  1 /* RFC7296 */
307
#define IKEV2_N_INVALID_IKE_SPI     4 /* RFC7296 */
308
#define IKEV2_N_INVALID_MAJOR_VERSION   5 /* RFC7296 */
309
#define IKEV2_N_INVALID_SYNTAX      7 /* RFC7296 */
310
#define IKEV2_N_INVALID_MESSAGE_ID    9 /* RFC7296 */
311
#define IKEV2_N_INVALID_SPI     11  /* RFC7296 */
312
36
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
135
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
6
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
241
#define IKEV2_N_NO_ADDITIONAL_SAS   35  /* RFC7296 */
317
#define IKEV2_N_INTERNAL_ADDRESS_FAILURE  36  /* RFC7296 */
318
#define IKEV2_N_FAILED_CP_REQUIRED    37  /* RFC7296 */
319
#define IKEV2_N_TS_UNACCEPTABLE     38  /* RFC7296 */
320
#define IKEV2_N_INVALID_SELECTORS   39  /* RFC7296 */
321
#define IKEV2_N_UNACCEPTABLE_ADDRESSES    40  /* RFC4555 */
322
#define IKEV2_N_UNEXPECTED_NAT_DETECTED   41  /* RFC4555 */
323
#define IKEV2_N_USE_ASSIGNED_HoA    42  /* RFC5026 */
324
348
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
73
#define IKEV2_N_CHILD_SA_NOT_FOUND    44  /* RFC7296 */
326
#define IKEV2_N_INITIAL_CONTACT     16384 /* RFC7296 */
327
#define IKEV2_N_SET_WINDOW_SIZE     16385 /* RFC7296 */
328
#define IKEV2_N_ADDITIONAL_TS_POSSIBLE    16386 /* RFC7296 */
329
255
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
26.0k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
23.0k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
316
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
75
#define IKEV2_N_REKEY_SA      16393  /* RFC7296 */
336
#define IKEV2_N_ESP_TFC_PADDING_NOT_SUPPORTED 16394 /* RFC7296 */
337
#define IKEV2_N_NON_FIRST_FRAGMENTS_ALSO  16395 /* RFC7296 */
338
267
#define IKEV2_N_MOBIKE_SUPPORTED    16396  /* RFC4555 */
339
#define IKEV2_N_ADDITIONAL_IP4_ADDRESS    16397 /* RFC4555 */
340
#define IKEV2_N_ADDITIONAL_IP6_ADDRESS    16398 /* RFC4555 */
341
#define IKEV2_N_NO_ADDITIONAL_ADDRESSES   16399 /* RFC4555 */
342
388
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
202
#define IKEV2_N_COOKIE2       16401  /* RFC4555 */
344
#define IKEV2_N_NO_NATS_ALLOWED     16402 /* RFC4555 */
345
#define IKEV2_N_AUTH_LIFETIME     16403 /* RFC4478 */
346
#define IKEV2_N_MULTIPLE_AUTH_SUPPORTED   16404 /* RFC4739 */
347
#define IKEV2_N_ANOTHER_AUTH_FOLLOWS    16405 /* RFC4739 */
348
#define IKEV2_N_REDIRECT_SUPPORTED    16406 /* RFC5685 */
349
#define IKEV2_N_REDIRECT      16407 /* RFC5685 */
350
#define IKEV2_N_REDIRECTED_FROM     16408 /* RFC5685 */
351
#define IKEV2_N_TICKET_LT_OPAQUE    16409 /* RFC5723 */
352
#define IKEV2_N_TICKET_REQUEST      16410 /* RFC5723 */
353
#define IKEV2_N_TICKET_ACK      16411 /* RFC5723 */
354
#define IKEV2_N_TICKET_NACK     16412 /* RFC5723 */
355
#define IKEV2_N_TICKET_OPAQUE     16413 /* RFC5723 */
356
#define IKEV2_N_LINK_ID       16414 /* RFC5739 */
357
#define IKEV2_N_USE_WESP_MODE     16415 /* RFC5415 */
358
#define IKEV2_N_ROHC_SUPPORTED      16416 /* RFC5857 */
359
#define IKEV2_N_EAP_ONLY_AUTHENTICATION   16417 /* RFC5998 */
360
#define IKEV2_N_CHILDLESS_IKEV2_SUPPORTED 16418 /* RFC6023 */
361
#define IKEV2_N_QUICK_CRASH_DETECTION   16419 /* RFC6290 */
362
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC_SUPPORTED 16420 /* RFC6311 */
363
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC_SUPPORTED 16421 /* RFC6311 */
364
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC   16422 /* RFC6311 */
365
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC   16423 /* RFC6311 */
366
#define IKEV2_N_SECURE_PASSWORD_METHODS   16424 /* RFC6467 */
367
#define IKEV2_N_PSK_PERSIST     16425 /* RFC6631 */
368
#define IKEV2_N_PSK_CONFIRM     16426 /* RFC6631 */
369
#define IKEV2_N_ERX_SUPPORTED     16427 /* RFC6867 */
370
#define IKEV2_N_IFOM_CAPABILITY     16428 /* OA3GPP */
371
14
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
7
#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431  /* RFC7427 */
373
374
extern struct iked_constmap ikev2_n_map[];
375
376
/*
377
 * DELETE payload
378
 */
379
380
struct ikev2_delete {
381
  uint8_t    del_protoid;   /* Protocol Id */
382
  uint8_t    del_spisize;   /* SPI size */
383
  uint16_t   del_nspi;    /* Number of SPIs */
384
  /* Followed by variable length SPIs */
385
} __packed;
386
387
/*
388
 * ID payload
389
 */
390
391
struct ikev2_id {
392
  uint8_t    id_type;   /* Id type */
393
  uint8_t    id_reserved[3];  /* Reserved */
394
  /* Followed by the identification data */
395
} __packed;
396
397
11.8k
#define IKEV2_ID_NONE   0  /* No ID */
398
#define IKEV2_ID_IPV4   1 /* RFC7296 (ID_IPV4_ADDR) */
399
#define IKEV2_ID_FQDN   2 /* RFC7296 */
400
#define IKEV2_ID_UFQDN    3 /* RFC7296 (ID_RFC822_ADDR) */
401
#define IKEV2_ID_IPV6   5 /* RFC7296 (ID_IPV6_ADDR) */
402
#define IKEV2_ID_ASN1_DN  9 /* RFC7296 */
403
#define IKEV2_ID_ASN1_GN  10  /* RFC7296 */
404
#define IKEV2_ID_KEY_ID   11  /* RFC7296 */
405
#define IKEV2_ID_FC_NAME  12  /* RFC4595 */
406
407
extern struct iked_constmap ikev2_id_map[];
408
409
/*
410
 * CERT/CERTREQ payloads
411
 */
412
413
struct ikev2_cert {
414
  uint8_t   cert_type;  /* Encoding */
415
  /* Followed by the certificate data */
416
} __packed;
417
418
4.34k
#define IKEV2_CERT_NONE     0  /* None */
419
#define IKEV2_CERT_X509_PKCS7   1 /* UNSPECIFIED */
420
#define IKEV2_CERT_PGP      2 /* UNSPECIFIED */
421
#define IKEV2_CERT_DNS_SIGNED_KEY 3 /* UNSPECIFIED */
422
1.18k
#define IKEV2_CERT_X509_CERT    4  /* RFC7296 */
423
#define IKEV2_CERT_KERBEROS_TOKEN 6 /* UNSPECIFIED */
424
#define IKEV2_CERT_CRL      7 /* RFC7296 */
425
#define IKEV2_CERT_ARL      8 /* UNSPECIFIED */
426
#define IKEV2_CERT_SPKI     9 /* UNSPECIFIED */
427
#define IKEV2_CERT_X509_ATTR    10  /* UNSPECIFIED */
428
#define IKEV2_CERT_RSA_KEY    11  /* RFC7296 */
429
#define IKEV2_CERT_HASHURL_X509   12  /* RFC7296 */
430
#define IKEV2_CERT_HASHURL_X509_BUNDLE  13  /* RFC7296 */
431
#define IKEV2_CERT_OCSP     14  /* RFC4806 */
432
/*
433
 * As of November 2014, work was still in progress to add a more generic
434
 * format for raw public keys (RFC7296), so we use a number in IANA's private
435
 * use range (201-255, same RFC) for ECDSA.
436
 */
437
#define IKEV2_CERT_ECDSA    201 /* Private */
438
1.94k
#define IKEV2_CERT_BUNDLE   254  /* Private */
439
440
extern struct iked_constmap ikev2_cert_map[];
441
442
/*
443
 * TSi/TSr payloads
444
 */
445
446
struct ikev2_tsp {
447
  uint8_t   tsp_count;    /* Number of TSs */
448
  uint8_t   tsp_reserved[3];  /* Reserved */
449
  /* Followed by the traffic selectors */
450
} __packed;
451
452
struct ikev2_ts {
453
  uint8_t   ts_type;    /* TS type */
454
  uint8_t   ts_protoid;   /* Protocol Id */
455
  uint16_t  ts_length;    /* Length */
456
  uint16_t  ts_startport;   /* Start port */
457
  uint16_t  ts_endport;   /* End port */
458
} __packed;
459
460
6.22k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.36k
#define IKEV2_TS_IPV6_ADDR_RANGE  8  /* RFC7296 */
462
#define IKEV2_TS_FC_ADDR_RANGE    9 /* RFC4595 */
463
464
extern struct iked_constmap ikev2_ts_map[];
465
466
/*
467
 * AUTH payload
468
 */
469
470
struct ikev2_auth {
471
  uint8_t   auth_method;    /* Signature type */
472
  uint8_t   auth_reserved[3]; /* Reserved */
473
  /* Followed by the signature */
474
} __packed;
475
476
#define IKEV2_AUTH_NONE     0 /* None */
477
#define IKEV2_AUTH_RSA_SIG    1 /* RFC7296 */
478
#define IKEV2_AUTH_SHARED_KEY_MIC 2 /* RFC7296 */
479
#define IKEV2_AUTH_DSS_SIG    3 /* RFC7296 */
480
#define IKEV2_AUTH_ECDSA_256    9 /* RFC4754 */
481
#define IKEV2_AUTH_ECDSA_384    10  /* RFC4754 */
482
#define IKEV2_AUTH_ECDSA_521    11  /* RFC4754 */
483
#define IKEV2_AUTH_GSPM     12  /* RFC6467 */
484
#define IKEV2_AUTH_NULL     13  /* RFC7619 */
485
#define IKEV2_AUTH_SIG      14  /* RFC7427 */
486
#define IKEV2_AUTH_SIG_ANY    255 /* Internal (any signature) */
487
/*
488
 * AUTH_SIG also serves as an indication that a given policy has
489
 * been configured to accept RSA or ECDSA payloads, as long as it
490
 * successfully authenticates against a configured CA.
491
 */
492
493
extern struct iked_constmap ikev2_auth_map[];
494
495
/* Notifications used together with IKEV2_AUTH_SIG */
496
497
#define IKEV2_SIGHASH_RESERVED    0 /* RFC7427 */
498
#define IKEV2_SIGHASH_SHA1    1 /* RFC7427 */
499
0
#define IKEV2_SIGHASH_SHA2_256    2  /* RFC7427 */
500
#define IKEV2_SIGHASH_SHA2_384    3 /* RFC7427 */
501
#define IKEV2_SIGHASH_SHA2_512    4 /* RFC7427 */
502
503
extern struct iked_constmap ikev2_sighash_map[];
504
505
/*
506
 * CP payload
507
 */
508
509
struct ikev2_cp {
510
  uint8_t   cp_type;
511
  uint8_t   cp_reserved[3];
512
  /* Followed by the attributes */
513
} __packed;
514
515
#define IKEV2_CP_REQUEST  1 /* CFG-Request */
516
#define IKEV2_CP_REPLY    2 /* CFG-Reply */
517
#define IKEV2_CP_SET    3 /* CFG-SET */
518
#define IKEV2_CP_ACK    4 /* CFG-ACK */
519
520
extern struct iked_constmap ikev2_cp_map[];
521
522
struct ikev2_cfg {
523
  uint16_t  cfg_type; /* first bit must be set to zero */
524
  uint16_t  cfg_length;
525
  /* Followed by variable-length data */
526
} __packed;
527
528
1.31k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.65k
#define IKEV2_CFG_INTERNAL_IP4_DNS    3  /* RFC7296 */
531
#define IKEV2_CFG_INTERNAL_IP4_NBNS   4 /* RFC7296 */
532
#define IKEV2_CFG_INTERNAL_ADDRESS_EXPIRY 5 /* RFC4306 */
533
#define IKEV2_CFG_INTERNAL_IP4_DHCP   6 /* RFC7296 */
534
#define IKEV2_CFG_APPLICATION_VERSION   7 /* RFC7296 */
535
2.37k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
3.10k
#define IKEV2_CFG_INTERNAL_IP6_DNS    10  /* RFC7296 */
537
#define IKEV2_CFG_INTERNAL_IP6_NBNS   11  /* RFC4306 */
538
#define IKEV2_CFG_INTERNAL_IP6_DHCP   12  /* RFC7296 */
539
#define IKEV2_CFG_INTERNAL_IP4_SUBNET   13  /* RFC7296 */
540
#define IKEV2_CFG_SUPPORTED_ATTRIBUTES    14  /* RFC7296 */
541
#define IKEV2_CFG_INTERNAL_IP6_SUBNET   15  /* RFC7296 */
542
#define IKEV2_CFG_MIP6_HOME_PREFIX    16  /* RFC5026 */
543
#define IKEV2_CFG_INTERNAL_IP6_LINK   17  /* RFC5739 */
544
#define IKEV2_CFG_INTERNAL_IP6_PREFIX   18  /* RFC5739 */
545
#define IKEV2_CFG_HOME_AGENT_ADDRESS    19  /* http://www.3gpp.org/ftp/Specs/html-info/24302.htm */
546
#define IKEV2_CFG_INTERNAL_IP4_SERVER   23456 /* MS-IKEE */
547
#define IKEV2_CFG_INTERNAL_IP6_SERVER   23457 /* MS-IKEE */
548
549
extern struct iked_constmap ikev2_cfg_map[];
550
551
/* IKEv1 payload types */
552
#define IKEV1_PAYLOAD_NONE  0 /* No payload */
553
#define IKEV1_PAYLOAD_PROPOSAL  2 /* Proposal */
554
555
#endif /* IKED_IKEV2_H */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/ikev2_pld.c.html b/coverage/latest/report/linux/src/openiked-portable/iked/ikev2_pld.c.html index 43e51451a..dddcaa0de 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/ikev2_pld.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/ikev2_pld.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/ikev2_pld.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2_pld.c,v 1.133 2023/09/02 18:36:30 tobhe Exp $ */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2014 Hans-Joerg Hoexer
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <string.h>
32
#include <signal.h>
33
#include <endian.h>
34
#include <errno.h>
35
#include <err.h>
36
#include <event.h>
37
38
#include <openssl/sha.h>
39
#include <openssl/evp.h>
40
41
#include "iked.h"
42
#include "ikev2.h"
43
#include "eap.h"
44
#include "dh.h"
45
46
int  ikev2_validate_pld(struct iked_message *, size_t, size_t,
47
      struct ikev2_payload *);
48
int  ikev2_pld_payloads(struct iked *, struct iked_message *,
49
      size_t, size_t, unsigned int);
50
int  ikev2_validate_sa(struct iked_message *, size_t, size_t,
51
      struct ikev2_sa_proposal *);
52
int  ikev2_pld_sa(struct iked *, struct ikev2_payload *,
53
      struct iked_message *, size_t, size_t);
54
int  ikev2_validate_xform(struct iked_message *, size_t, size_t,
55
      struct ikev2_transform *);
56
int  ikev2_pld_xform(struct iked *, struct iked_message *,
57
      size_t, size_t);
58
int  ikev2_validate_attr(struct iked_message *, size_t, size_t,
59
      struct ikev2_attribute *);
60
int  ikev2_pld_attr(struct iked *, struct ikev2_transform *,
61
      struct iked_message *, size_t, size_t);
62
int  ikev2_validate_ke(struct iked_message *, size_t, size_t,
63
      struct ikev2_keyexchange *);
64
int  ikev2_pld_ke(struct iked *, struct ikev2_payload *,
65
      struct iked_message *, size_t, size_t);
66
int  ikev2_validate_id(struct iked_message *, size_t, size_t,
67
      struct ikev2_id *);
68
int  ikev2_pld_id(struct iked *, struct ikev2_payload *,
69
      struct iked_message *, size_t, size_t, unsigned int);
70
int  ikev2_validate_cert(struct iked_message *, size_t, size_t,
71
      struct ikev2_cert *);
72
int  ikev2_pld_cert(struct iked *, struct ikev2_payload *,
73
      struct iked_message *, size_t, size_t);
74
int  ikev2_validate_certreq(struct iked_message *, size_t, size_t,
75
      struct ikev2_cert *);
76
int  ikev2_pld_certreq(struct iked *, struct ikev2_payload *,
77
      struct iked_message *, size_t, size_t);
78
int  ikev2_pld_nonce(struct iked *, struct ikev2_payload *,
79
      struct iked_message *, size_t, size_t);
80
int  ikev2_validate_notify(struct iked_message *, size_t, size_t,
81
      struct ikev2_notify *);
82
int  ikev2_pld_notify(struct iked *, struct ikev2_payload *,
83
      struct iked_message *, size_t, size_t);
84
int  ikev2_validate_delete(struct iked_message *, size_t, size_t,
85
      struct ikev2_delete *);
86
int  ikev2_pld_delete(struct iked *, struct ikev2_payload *,
87
      struct iked_message *, size_t, size_t);
88
int  ikev2_validate_tss(struct iked_message *, size_t, size_t,
89
      struct ikev2_tsp *);
90
int  ikev2_pld_tss(struct iked *, struct ikev2_payload *,
91
      struct iked_message *, size_t, size_t);
92
int  ikev2_validate_ts(struct iked_message *, size_t, size_t,
93
      struct ikev2_ts *);
94
int  ikev2_pld_ts(struct iked *, struct ikev2_payload *,
95
      struct iked_message *, size_t, size_t, unsigned int);
96
int  ikev2_validate_auth(struct iked_message *, size_t, size_t,
97
      struct ikev2_auth *);
98
int  ikev2_pld_auth(struct iked *, struct ikev2_payload *,
99
      struct iked_message *, size_t, size_t);
100
int  ikev2_pld_e(struct iked *, struct ikev2_payload *,
101
      struct iked_message *, size_t, size_t);
102
int  ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
103
      struct iked_message *msg, size_t offset, size_t left);
104
int  ikev2_frags_reassemble(struct iked *env,
105
      struct ikev2_payload *pld, struct iked_message *msg);
106
int  ikev2_validate_cp(struct iked_message *, size_t, size_t,
107
      struct ikev2_cp *);
108
int  ikev2_pld_cp(struct iked *, struct ikev2_payload *,
109
      struct iked_message *, size_t, size_t);
110
int  ikev2_validate_eap(struct iked_message *, size_t, size_t,
111
      struct eap_header *);
112
int  ikev2_pld_eap(struct iked *, struct ikev2_payload *,
113
      struct iked_message *, size_t, size_t);
114
115
int
116
ikev2_pld_parse(struct iked *env, struct ike_header *hdr,
117
    struct iked_message *msg, size_t offset)
118
13.0k
{
119
13.0k
  log_debug("%s: header ispi %s rspi %s"
120
13.0k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
13.0k
      " msgid %d length %u response %d", __func__,
122
13.0k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
13.0k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
13.0k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
13.0k
      hdr->ike_version,
126
13.0k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
13.0k
      hdr->ike_flags,
128
13.0k
      betoh32(hdr->ike_msgid),
129
13.0k
      betoh32(hdr->ike_length),
130
13.0k
      msg->msg_response);
131
132
13.0k
  if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) {
133
4
    log_debug("%s: short message", __func__);
134
4
    return (-1);
135
4
  }
136
137
13.0k
  offset += sizeof(*hdr);
138
139
13.0k
  return (ikev2_pld_payloads(env, msg, offset,
140
13.0k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
13.0k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
234k
{
147
234k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
234k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
234k
  if (left < sizeof(*pld)) {
152
1.71k
    log_debug("%s: malformed payload: too short for generic "
153
1.71k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.71k
    return (-1);
155
1.71k
  }
156
232k
  memcpy(pld, msgbuf + offset, sizeof(*pld));
157
158
  /*
159
   * We need at least the specified number of bytes.
160
   * pld_length is the full size of the payload including
161
   * the generic payload header.
162
   */
163
232k
  pld_length = betoh16(pld->pld_length);
164
232k
  if (left < pld_length) {
165
5.81k
    log_debug("%s: malformed payload: shorter than specified "
166
5.81k
        "(%zu < %zu)", __func__, left, pld_length);
167
5.81k
    return (-1);
168
5.81k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
227k
  if (pld_length < sizeof(*pld)) {
174
2.33k
    log_debug("%s: malformed payload: shorter than minimum "
175
2.33k
        "header size (%zu < %zu)", __func__, pld_length,
176
2.33k
        sizeof(*pld));
177
2.33k
    return (-1);
178
2.33k
  }
179
180
224k
  return (0);
181
227k
}
182
183
int
184
ikev2_pld_payloads(struct iked *env, struct iked_message *msg,
185
    size_t offset, size_t length, unsigned int payload)
186
13.0k
{
187
13.0k
  struct ikev2_payload   pld;
188
13.0k
  unsigned int     e;
189
13.0k
  int      ret;
190
13.0k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
13.0k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
13.0k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
13.0k
  total = length - offset;
198
199
237k
  while (payload != 0 && offset < length) {
200
234k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
9.86k
      return (-1);
202
203
224k
    log_debug("%s: %spayload %s"
204
224k
        " nextpayload %s critical 0x%02x length %d",
205
224k
        __func__, e ? "decrypted " : "",
206
224k
        print_map(payload, ikev2_payload_map),
207
224k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
224k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
224k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
224k
    offset += sizeof(pld);
213
224k
    total -= sizeof(pld);
214
224k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
224k
    ret = 0;
216
217
224k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
28.1k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
28.1k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
28.1k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
8.28k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
8.28k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
8.28k
      break;
226
12.8k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
19.4k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
19.4k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
19.4k
          payload);
230
19.4k
      break;
231
5.80k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.80k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.80k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
12.1k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
12.1k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
12.1k
      break;
238
8.17k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
8.17k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
8.17k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
242
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
242
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
242
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
32.0k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
32.0k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
32.0k
      break;
249
7.11k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
7.11k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
7.11k
      break;
252
4.64k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
18.0k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
18.0k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
18.0k
      break;
256
0
    case IKEV2_PAYLOAD_SK:
257
0
      ret = ikev2_pld_e(env, &pld, msg, offset, left);
258
0
      break;
259
0
    case IKEV2_PAYLOAD_SKF:
260
0
      ret = ikev2_pld_ef(env, &pld, msg, offset, left);
261
0
      break;
262
9.77k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
9.77k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
9.77k
      break;
265
17.0k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
17.0k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
17.0k
      break;
268
58.3k
    default:
269
58.3k
      print_hex(msgbuf, offset,
270
58.3k
          betoh16(pld.pld_length) - sizeof(pld));
271
58.3k
      break;
272
224k
    }
273
274
224k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
722
      (void)ikev2_send_informational(env, msg);
276
722
      return (-1);
277
722
    }
278
279
    /* Encrypted payloads must appear last */
280
224k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
224k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
224k
    payload = pld.pld_nextpayload;
285
224k
    offset += left;
286
224k
    total -= left;
287
224k
  }
288
289
2.45k
  return (0);
290
13.0k
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
32.5k
{
296
32.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
32.5k
  size_t     sap_length;
298
299
32.5k
  if (left < sizeof(*sap)) {
300
13.8k
    log_debug("%s: malformed payload: too short for header "
301
13.8k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.8k
    return (-1);
303
13.8k
  }
304
18.6k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.6k
  sap_length = betoh16(sap->sap_length);
307
18.6k
  if (sap_length < sizeof(*sap)) {
308
5.01k
    log_debug("%s: malformed payload: shorter than minimum header "
309
5.01k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
5.01k
    return (-1);
311
5.01k
  }
312
13.6k
  if (left < sap_length) {
313
2.30k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.30k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.30k
    return (-1);
316
2.30k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
11.3k
  if (!sap->sap_more && left != sap_length) {
322
30
    log_debug("%s: malformed payload: SA payload length mismatches "
323
30
        "single proposal substructure length (%zu != %zu)",
324
30
        __func__, left, sap_length);
325
30
    return (-1);
326
30
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
11.3k
  if (sap->sap_more && left <= sap_length) {
332
839
    log_debug("%s: malformed payload: SA payload too small for "
333
839
        "further proposals (%zu <= %zu)", __func__,
334
839
        left, sap_length);
335
839
    return (-1);
336
839
  }
337
10.5k
  return (0);
338
11.3k
}
339
340
int
341
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
342
    struct iked_message *msg, size_t offset, size_t left)
343
28.1k
{
344
28.1k
  struct ikev2_sa_proposal   sap;
345
28.1k
  struct iked_proposal    *prop = NULL;
346
28.1k
  uint32_t       spi32;
347
28.1k
  uint64_t       spi = 0, spi64;
348
28.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
28.1k
  int        r;
350
28.1k
  struct iked_proposals   *props;
351
28.1k
  size_t         total;
352
353
32.5k
  do {
354
32.5k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
22.0k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.5k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.5k
    props = &msg->msg_parent->msg_proposals;
361
362
10.5k
    offset += sizeof(sap);
363
10.5k
    left -= sizeof(sap);
364
365
10.5k
    if (sap.sap_spisize) {
366
1.40k
      if (left < sap.sap_spisize) {
367
646
        log_debug("%s: malformed payload: SPI larger than "
368
646
            "actual payload (%zu < %d)", __func__, left,
369
646
            sap.sap_spisize);
370
646
        return (-1);
371
646
      }
372
755
      if (total < sap.sap_spisize) {
373
135
        log_debug("%s: malformed payload: SPI larger than "
374
135
            "proposal (%zu < %d)", __func__, total,
375
135
            sap.sap_spisize);
376
135
        return (-1);
377
135
      }
378
620
      switch (sap.sap_spisize) {
379
290
      case 4:
380
290
        memcpy(&spi32, msgbuf + offset, 4);
381
290
        spi = betoh32(spi32);
382
290
        break;
383
200
      case 8:
384
200
        memcpy(&spi64, msgbuf + offset, 8);
385
200
        spi = betoh64(spi64);
386
200
        break;
387
130
      default:
388
130
        log_debug("%s: unsupported SPI size %d",
389
130
            __func__, sap.sap_spisize);
390
130
        return (-1);
391
620
      }
392
393
490
      offset += sap.sap_spisize;
394
490
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
490
      total -= sap.sap_spisize;
398
490
    }
399
400
    /*
401
     * As we verified sanity of packet headers, this check will
402
     * be always false, but just to be sure we keep it.
403
     */
404
9.59k
    if (left < total) {
405
0
      log_debug("%s: malformed payload: too long for payload "
406
0
          "(%zu < %zu)", __func__, left, total);
407
0
      return (-1);
408
0
    }
409
410
9.59k
    log_debug("%s: more %d reserved %d length %d"
411
9.59k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.59k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.59k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.59k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.59k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.59k
    if (ikev2_msg_frompeer(msg)) {
418
69
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
69
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
69
        log_debug("%s: invalid proposal", __func__);
421
69
        return (-1);
422
69
      }
423
0
      prop = msg->msg_parent->msg_prop;
424
0
      prop->prop_peerspi.spi = spi;
425
0
      prop->prop_peerspi.spi_protoid = sap.sap_protoid;
426
0
      prop->prop_peerspi.spi_size = sap.sap_spisize;
427
428
0
      prop->prop_localspi.spi_protoid = sap.sap_protoid;
429
0
      prop->prop_localspi.spi_size = sap.sap_spisize;
430
0
    }
431
432
    /*
433
     * Parse the attached transforms
434
     */
435
9.52k
    if (sap.sap_transforms) {
436
5.44k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.44k
      if ((r == -2) && ikev2_msg_frompeer(msg)) {
438
0
        log_debug("%s: invalid proposal transform",
439
0
            __func__);
440
441
        /* cleanup and ignore proposal */
442
0
        config_free_proposal(props, prop);
443
0
        prop = msg->msg_parent->msg_prop = NULL;
444
5.44k
      } else if (r != 0) {
445
4.37k
        log_debug("%s: invalid proposal transforms",
446
4.37k
            __func__);
447
4.37k
        return (-1);
448
4.37k
      }
449
5.44k
    }
450
451
5.14k
    offset += total;
452
5.14k
    left -= total;
453
5.14k
  } while (sap.sap_more);
454
455
747
  return (0);
456
28.1k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
7.29k
{
462
7.29k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
7.29k
  size_t     xfrm_length;
464
465
7.29k
  if (total < sizeof(*xfrm)) {
466
625
    log_debug("%s: malformed payload: too short for header "
467
625
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
625
    return (-1);
469
625
  }
470
6.67k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.67k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.67k
  if (xfrm_length < sizeof(*xfrm)) {
474
1.12k
    log_debug("%s: malformed payload: shorter than minimum header "
475
1.12k
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
1.12k
    return (-1);
477
1.12k
  }
478
5.54k
  if (total < xfrm_length) {
479
644
    log_debug("%s: malformed payload: too long for payload size "
480
644
        "(%zu < %zu)", __func__, total, xfrm_length);
481
644
    return (-1);
482
644
  }
483
484
4.90k
  return (0);
485
5.54k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
7.29k
{
491
7.29k
  struct ikev2_transform     xfrm;
492
7.29k
  char         id[BUFSIZ];
493
7.29k
  int        ret = 0;
494
7.29k
  int        r;
495
7.29k
  size_t         xfrm_length;
496
497
7.29k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.39k
    return (-1);
499
500
4.90k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.90k
  switch (xfrm.xfrm_type) {
503
1.07k
  case IKEV2_XFORMTYPE_ENCR:
504
1.07k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.07k
        ikev2_xformencr_map), sizeof(id));
506
1.07k
    break;
507
777
  case IKEV2_XFORMTYPE_PRF:
508
777
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
777
        ikev2_xformprf_map), sizeof(id));
510
777
    break;
511
154
  case IKEV2_XFORMTYPE_INTEGR:
512
154
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
154
        ikev2_xformauth_map), sizeof(id));
514
154
    break;
515
567
  case IKEV2_XFORMTYPE_DH:
516
567
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
567
        ikev2_xformdh_map), sizeof(id));
518
567
    break;
519
1.00k
  case IKEV2_XFORMTYPE_ESN:
520
1.00k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
1.00k
        ikev2_xformesn_map), sizeof(id));
522
1.00k
    break;
523
1.32k
  default:
524
1.32k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.32k
    break;
526
4.90k
  }
527
528
4.90k
  log_debug("%s: more %d reserved %d length %zu"
529
4.90k
      " type %s id %s",
530
4.90k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.90k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.90k
  msg->msg_attrlength = 0;
537
4.90k
  if (xfrm_length > sizeof(xfrm)) {
538
2.34k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.34k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.80k
      return (-1);
541
1.80k
    }
542
2.34k
  }
543
544
3.09k
  if (ikev2_msg_frompeer(msg)) {
545
0
    r = config_add_transform(msg->msg_parent->msg_prop,
546
0
        xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
547
0
        msg->msg_attrlength, msg->msg_attrlength);
548
0
    if (r == -1) {
549
0
      log_debug("%s: failed to add transform: alloc error",
550
0
          __func__);
551
0
      return (r);
552
0
    } else if (r == -2) {
553
0
      log_debug("%s: failed to add transform: unknown type",
554
0
          __func__);
555
0
      return (r);
556
0
    }
557
0
  }
558
559
  /* Next transform */
560
3.09k
  offset += xfrm_length;
561
3.09k
  total -= xfrm_length;
562
3.09k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.85k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.24k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
177
    log_debug("%s: less data than specified, %zu bytes left",
567
177
        __func__, total);
568
177
    ret = -1;
569
177
  }
570
571
3.09k
  return (ret);
572
3.09k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
29.4k
{
578
29.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
29.4k
  if (total < sizeof(*attr)) {
581
817
    log_debug("%s: malformed payload: too short for header "
582
817
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
817
    return (-1);
584
817
  }
585
28.6k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.6k
  return (0);
588
29.4k
}
589
590
int
591
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
592
    struct iked_message *msg, size_t offset, size_t total)
593
29.4k
{
594
29.4k
  struct ikev2_attribute     attr;
595
29.4k
  unsigned int       type;
596
29.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
29.4k
  int        ret = 0;
598
29.4k
  size_t         attr_length;
599
600
29.4k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
817
    return (-1);
602
603
28.6k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.6k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.6k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.6k
      betoh16(attr.attr_length), total);
608
609
28.6k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
22.1k
    offset += sizeof(attr);
612
22.1k
    total -= sizeof(attr);
613
614
22.1k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
47
      msg->msg_attrlength = betoh16(attr.attr_length);
616
22.1k
  } else {
617
    /* Type-Length-Value attribute */
618
6.49k
    attr_length = betoh16(attr.attr_length);
619
6.49k
    if (attr_length < sizeof(attr)) {
620
543
      log_debug("%s: malformed payload: shorter than "
621
543
          "minimum header size (%zu < %zu)", __func__,
622
543
          attr_length, sizeof(attr));
623
543
      return (-1);
624
543
    }
625
5.94k
    if (total < attr_length) {
626
443
      log_debug("%s: malformed payload: attribute larger "
627
443
          "than actual payload (%zu < %zu)", __func__,
628
443
          total, attr_length);
629
443
      return (-1);
630
443
    }
631
5.50k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.50k
        attr_length - sizeof(attr));
633
5.50k
    offset += attr_length;
634
5.50k
    total -= attr_length;
635
5.50k
  }
636
637
27.6k
  if (total > 0) {
638
    /* Next attribute */
639
27.0k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
27.0k
  }
641
642
27.6k
  return (ret);
643
28.6k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
8.28k
{
649
8.28k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
8.28k
  if (left < sizeof(*kex)) {
652
5.11k
    log_debug("%s: malformed payload: too short for header "
653
5.11k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
5.11k
    return (-1);
655
5.11k
  }
656
3.16k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
3.16k
  return (0);
659
8.28k
}
660
661
int
662
ikev2_pld_ke(struct iked *env, struct ikev2_payload *pld,
663
    struct iked_message *msg, size_t offset, size_t left)
664
8.28k
{
665
8.28k
  struct ikev2_keyexchange   kex;
666
8.28k
  uint8_t       *buf;
667
8.28k
  size_t         len;
668
8.28k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
8.28k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
5.11k
    return (-1);
672
673
3.16k
  log_debug("%s: dh group %s reserved %d", __func__,
674
3.16k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
3.16k
      betoh16(kex.kex_reserved));
676
677
3.16k
  buf = msgbuf + offset + sizeof(kex);
678
3.16k
  len = left - sizeof(kex);
679
680
3.16k
  if (len == 0) {
681
1.41k
    log_debug("%s: malformed payload: no KE data given", __func__);
682
1.41k
    return (-1);
683
1.41k
  }
684
685
1.75k
  print_hex(buf, 0, len);
686
687
1.75k
  if (ikev2_msg_frompeer(msg)) {
688
27
    if (msg->msg_parent->msg_ke != NULL) {
689
4
      log_info("%s: duplicate KE payload", __func__);
690
4
      return (-1);
691
4
    }
692
23
    if ((msg->msg_parent->msg_ke = ibuf_new(buf, len)) == NULL) {
693
0
      log_debug("%s: failed to get exchange", __func__);
694
0
      return (-1);
695
0
    }
696
23
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
23
  }
698
699
1.74k
  return (0);
700
1.75k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
19.4k
{
706
19.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
19.4k
  if (left < sizeof(*id)) {
709
7.62k
    log_debug("%s: malformed payload: too short for header "
710
7.62k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.62k
    return (-1);
712
7.62k
  }
713
11.8k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.8k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.46k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.46k
        __func__);
718
6.46k
    return (-1);
719
6.46k
  }
720
721
5.38k
  return (0);
722
11.8k
}
723
724
int
725
ikev2_pld_id(struct iked *env, struct ikev2_payload *pld,
726
    struct iked_message *msg, size_t offset, size_t left, unsigned int payload)
727
19.4k
{
728
19.4k
  uint8_t       *ptr;
729
19.4k
  struct ikev2_id      id;
730
19.4k
  size_t         len;
731
19.4k
  struct iked_id      *idp, idb;
732
19.4k
  const struct iked_sa    *sa = msg->msg_sa;
733
19.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
19.4k
  char         idstr[IKED_ID_SIZE];
735
736
19.4k
  if (ikev2_validate_id(msg, offset, left, &id))
737
14.0k
    return (-1);
738
739
5.38k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
5.38k
  ptr = msgbuf + offset;
743
5.38k
  len = left;
744
745
5.38k
  idb.id_type = id.id_type;
746
5.38k
  idb.id_offset = sizeof(id);
747
5.38k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
5.38k
  if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) {
751
0
    ibuf_free(idb.id_buf);
752
0
    log_debug("%s: malformed id", __func__);
753
0
    return (-1);
754
0
  }
755
756
5.38k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
5.38k
  if (!ikev2_msg_frompeer(msg)) {
759
5.28k
    ibuf_free(idb.id_buf);
760
5.28k
    return (0);
761
5.28k
  }
762
763
101
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
101
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
59
    idp = &msg->msg_parent->msg_peerid;
766
42
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
42
    idp = &msg->msg_parent->msg_localid;
768
0
  else {
769
0
    ibuf_free(idb.id_buf);
770
0
    log_debug("%s: unexpected id payload", __func__);
771
0
    return (0);
772
0
  }
773
774
101
  if (idp->id_type) {
775
16
    ibuf_free(idb.id_buf);
776
16
    log_debug("%s: duplicate id payload", __func__);
777
16
    return (-1);
778
16
  }
779
780
85
  idp->id_buf = idb.id_buf;
781
85
  idp->id_offset = idb.id_offset;
782
85
  idp->id_type = idb.id_type;
783
784
85
  return (0);
785
101
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
5.80k
{
791
5.80k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.80k
  if (left < sizeof(*cert)) {
794
1.46k
    log_debug("%s: malformed payload: too short for header "
795
1.46k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.46k
    return (-1);
797
1.46k
  }
798
4.34k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.34k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
982
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
982
    return (-1);
802
982
  }
803
804
3.36k
  return (0);
805
4.34k
}
806
807
int
808
ikev2_pld_cert(struct iked *env, struct ikev2_payload *pld,
809
    struct iked_message *msg, size_t offset, size_t left)
810
5.80k
{
811
5.80k
  struct ikev2_cert    cert;
812
5.80k
  uint8_t       *buf;
813
5.80k
  size_t         len;
814
5.80k
  struct iked_id      *certid;
815
5.80k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.80k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.80k
  int        i;
818
819
5.80k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.44k
    return (-1);
821
3.36k
  offset += sizeof(cert);
822
823
3.36k
  buf = msgbuf + offset;
824
3.36k
  len = left - sizeof(cert);
825
826
3.36k
  log_debug("%s: type %s length %zu",
827
3.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.36k
  print_hex(buf, 0, len);
830
831
3.36k
  if (!ikev2_msg_frompeer(msg))
832
1.41k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.94k
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
290
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
290
       SPI_SA(sa, __func__));
838
290
    return (0);
839
290
  }
840
841
1.65k
  certid = &msg->msg_parent->msg_cert;
842
1.65k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
4.10k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
3.35k
      certid = &msg->msg_parent->msg_scert[i];
846
3.35k
      if (!certid->id_type)
847
605
        break;
848
3.35k
    }
849
1.35k
    if (certid->id_type) {
850
748
      log_debug("%s: too many cert payloads, ignoring",
851
748
         SPI_SA(sa, __func__));
852
748
      return (0);
853
748
    }
854
1.35k
  }
855
856
911
  if ((certid->id_buf = ibuf_new(buf, len)) == NULL) {
857
0
    log_debug("%s: failed to save cert", __func__);
858
0
    return (-1);
859
0
  }
860
911
  certid->id_type = cert.cert_type;
861
911
  certid->id_offset = 0;
862
863
911
  return (0);
864
911
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
12.1k
{
870
12.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
12.1k
  if (left < sizeof(*cert)) {
873
2.65k
    log_debug("%s: malformed payload: too short for header "
874
2.65k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.65k
    return (-1);
876
2.65k
  }
877
9.48k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
9.48k
  return (0);
880
12.1k
}
881
882
int
883
ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
884
    struct iked_message *msg, size_t offset, size_t left)
885
12.1k
{
886
12.1k
  struct ikev2_cert    cert;
887
12.1k
  struct iked_certreq   *cr;
888
12.1k
  uint8_t       *buf;
889
12.1k
  ssize_t        len;
890
12.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
12.1k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.65k
    return (-1);
894
9.48k
  offset += sizeof(cert);
895
896
9.48k
  buf = msgbuf + offset;
897
9.48k
  len = left - sizeof(cert);
898
899
9.48k
  log_debug("%s: type %s length %zd",
900
9.48k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
9.48k
  print_hex(buf, 0, len);
903
904
9.48k
  if (!ikev2_msg_frompeer(msg))
905
8.30k
    return (0);
906
907
1.18k
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
321
    if (len == 0) {
909
279
      log_info("%s: invalid length 0", __func__);
910
279
      return (0);
911
279
    }
912
42
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
9
      log_info("%s: invalid certificate request",
914
9
          __func__);
915
9
      return (-1);
916
9
    }
917
42
  }
918
919
897
  if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) {
920
0
    log_info("%s: failed to allocate certreq.", __func__);
921
0
    return (-1);
922
0
  }
923
897
  if ((cr->cr_data = ibuf_new(buf, len)) == NULL) {
924
0
    log_info("%s: failed to allocate buffer.", __func__);
925
0
    free(cr);
926
0
    return (-1);
927
0
  }
928
897
  cr->cr_type = cert.cert_type;
929
897
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
897
  return (0);
932
897
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
8.17k
{
938
8.17k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
8.17k
  if (left < sizeof(*auth)) {
941
1.85k
    log_debug("%s: malformed payload: too short for header "
942
1.85k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.85k
    return (-1);
944
1.85k
  }
945
6.31k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.31k
  if (auth->auth_method == 0) {
948
3.36k
    log_info("%s: malformed payload: invalid auth method",
949
3.36k
        __func__);
950
3.36k
    return (-1);
951
3.36k
  }
952
953
2.95k
  return (0);
954
6.31k
}
955
956
int
957
ikev2_pld_auth(struct iked *env, struct ikev2_payload *pld,
958
    struct iked_message *msg, size_t offset, size_t left)
959
8.17k
{
960
8.17k
  struct ikev2_auth    auth;
961
8.17k
  struct iked_id      *idp;
962
8.17k
  uint8_t       *buf;
963
8.17k
  size_t         len;
964
8.17k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
8.17k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.21k
    return (-1);
968
2.95k
  offset += sizeof(auth);
969
970
2.95k
  buf = msgbuf + offset;
971
2.95k
  len = left - sizeof(auth);
972
973
2.95k
  log_debug("%s: method %s length %zu",
974
2.95k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.95k
  print_hex(buf, 0, len);
977
978
2.95k
  if (!ikev2_msg_frompeer(msg))
979
2.91k
    return (0);
980
981
42
  idp = &msg->msg_parent->msg_auth;
982
42
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
41
  ibuf_free(idp->id_buf);
988
41
  idp->id_type = auth.auth_method;
989
41
  idp->id_offset = 0;
990
41
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
41
  return (0);
994
41
}
995
996
int
997
ikev2_pld_nonce(struct iked *env, struct ikev2_payload *pld,
998
    struct iked_message *msg, size_t offset, size_t left)
999
242
{
1000
242
  size_t     len;
1001
242
  uint8_t   *buf;
1002
242
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
242
  buf = msgbuf + offset;
1005
242
  len = left;
1006
1007
242
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
160
  print_hex(buf, 0, len);
1013
1014
160
  if (ikev2_msg_frompeer(msg)) {
1015
61
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
42
    if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) {
1020
0
      log_debug("%s: failed to get peer nonce", __func__);
1021
0
      return (-1);
1022
0
    }
1023
42
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
42
  }
1025
1026
141
  return (0);
1027
160
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
32.0k
{
1033
32.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
32.0k
  if (left < sizeof(*n)) {
1036
3.51k
    log_debug("%s: malformed payload: too short for header "
1037
3.51k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.51k
    return (-1);
1039
3.51k
  }
1040
28.5k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
28.5k
  return (0);
1043
32.0k
}
1044
1045
int
1046
ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
1047
    struct iked_message *msg, size_t offset, size_t left)
1048
32.0k
{
1049
32.0k
  struct ikev2_notify  n;
1050
32.0k
  const struct iked_sa  *sa = msg->msg_sa;
1051
32.0k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
32.0k
  uint32_t     spi32;
1053
32.0k
  uint64_t     spi64;
1054
32.0k
  struct iked_spi   *rekey;
1055
32.0k
  uint16_t     type;
1056
32.0k
  uint16_t     signature_hash;
1057
1058
32.0k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.51k
    return (-1);
1060
28.5k
  type = betoh16(n.n_type);
1061
1062
28.5k
  log_debug("%s: protoid %s spisize %d type %s",
1063
28.5k
      __func__,
1064
28.5k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
28.5k
      print_map(type, ikev2_n_map));
1066
1067
28.5k
  left -= sizeof(n);
1068
28.5k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
28.5k
  print_hex(buf, 0, left);
1072
1073
28.5k
  if (!ikev2_msg_frompeer(msg))
1074
1.44k
    return (0);
1075
1076
27.0k
  switch (type) {
1077
3.05k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
22.6k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
22.6k
    if (left != sizeof(md)) {
1080
16
      log_debug("%s: malformed payload: hash size mismatch"
1081
16
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
16
      return (-1);
1083
16
    }
1084
22.6k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
22.6k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
22.6k
    if (memcmp(buf, md, left) != 0) {
1088
22.6k
      log_debug("%s: %s detected NAT", __func__,
1089
22.6k
          print_map(type, ikev2_n_map));
1090
22.6k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
3.04k
        msg->msg_parent->msg_nat_detected
1092
3.04k
            |= IKED_MSG_NAT_SRC_IP;
1093
19.5k
      else
1094
19.5k
        msg->msg_parent->msg_nat_detected
1095
19.5k
            |= IKED_MSG_NAT_DST_IP;
1096
22.6k
    }
1097
22.6k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
22.6k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
22.6k
    break;
1101
6
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
6
    if (!msg->msg_e) {
1103
0
      log_debug("%s: AUTHENTICATION_FAILED not encrypted",
1104
0
          __func__);
1105
0
      return (-1);
1106
0
    }
1107
    /*
1108
     * If we are the responder, then we only accept
1109
     * AUTHENTICATION_FAILED from authenticated peers.
1110
     * If we are the initiator, the peer cannot be authenticated.
1111
     */
1112
6
    if (!sa->sa_hdr.sh_initiator) {
1113
6
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
6
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
6
            " from unauthenticated initiator",
1116
6
            __func__);
1117
6
        return (-1);
1118
6
      }
1119
6
    } else {
1120
0
      if (sa_stateok(sa, IKEV2_STATE_VALID)) {
1121
0
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1122
0
            " from authenticated responder",
1123
0
            __func__);
1124
0
        return (-1);
1125
0
      }
1126
0
    }
1127
0
    msg->msg_parent->msg_flags
1128
0
        |= IKED_MSG_FLAGS_AUTHENTICATION_FAILED;
1129
0
    break;
1130
135
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
135
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
135
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
135
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
4
      log_debug("%s: malformed payload: group size mismatch"
1139
4
          " (%zu != %zu)", __func__, left,
1140
4
          sizeof(msg->msg_parent->msg_group));
1141
4
      return (-1);
1142
4
    }
1143
131
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
131
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
131
    break;
1146
241
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
241
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
241
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
241
    break;
1154
75
  case IKEV2_N_REKEY_SA:
1155
75
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
75
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
70
    rekey = &msg->msg_parent->msg_rekey;
1164
70
    if (rekey->spi != 0) {
1165
5
      log_debug("%s: rekeying of multiple SAs not supported",
1166
5
          __func__);
1167
5
      return (-1);
1168
5
    }
1169
65
    switch (n.n_spisize) {
1170
59
    case 4:
1171
59
      memcpy(&spi32, buf, left);
1172
59
      rekey->spi = betoh32(spi32);
1173
59
      break;
1174
3
    case 8:
1175
3
      memcpy(&spi64, buf, left);
1176
3
      rekey->spi = betoh64(spi64);
1177
3
      break;
1178
3
    default:
1179
3
      log_debug("%s: invalid spi size %d", __func__,
1180
3
          n.n_spisize);
1181
3
      return (-1);
1182
65
    }
1183
62
    rekey->spi_size = n.n_spisize;
1184
62
    rekey->spi_protoid = n.n_protoid;
1185
1186
62
    log_debug("%s: rekey %s spi %s", __func__,
1187
62
        print_map(n.n_protoid, ikev2_saproto_map),
1188
62
        print_spi(rekey->spi, n.n_spisize));
1189
62
    break;
1190
348
  case IKEV2_N_TEMPORARY_FAILURE:
1191
348
    if (!msg->msg_e) {
1192
0
      log_debug("%s: IKEV2_N_TEMPORARY_FAILURE not encrypted",
1193
0
          __func__);
1194
0
      return (-1);
1195
0
    }
1196
348
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
348
    break;
1198
255
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
255
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
255
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
255
        sizeof(msg->msg_parent->msg_transform)) {
1206
127
      log_debug("%s: ignoring malformed ipcomp notification",
1207
127
          __func__);
1208
127
      return (0);
1209
127
    }
1210
128
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
128
        sizeof(msg->msg_parent->msg_cpi));
1212
128
    memcpy(&msg->msg_parent->msg_transform,
1213
128
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
128
        sizeof(msg->msg_parent->msg_transform));
1215
1216
128
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
128
        msg->msg_parent->msg_response ? "res" : "req",
1218
128
        betoh16(msg->msg_parent->msg_cpi),
1219
128
        print_map(msg->msg_parent->msg_transform,
1220
128
        ikev2_ipcomp_map), left);
1221
1222
128
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
128
    break;
1224
73
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
73
    if (!msg->msg_e) {
1226
0
      log_debug("%s: N_CHILD_SA_NOT_FOUND not encrypted",
1227
0
          __func__);
1228
0
      return (-1);
1229
0
    }
1230
73
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
73
    break;
1232
36
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
36
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
36
    break;
1235
267
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
267
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
267
    if (left != 0) {
1242
131
      log_debug("%s: ignoring malformed mobike"
1243
131
          " notification: %zu", __func__, left);
1244
131
      return (0);
1245
131
    }
1246
136
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
136
    break;
1248
316
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
316
    if (!msg->msg_e) {
1250
0
      log_debug("%s: N_USE_TRANSPORT_MODE not encrypted",
1251
0
          __func__);
1252
0
      return (-1);
1253
0
    }
1254
316
    if (left != 0) {
1255
77
      log_debug("%s: ignoring malformed transport mode"
1256
77
          " notification: %zu", __func__, left);
1257
77
      return (0);
1258
77
    }
1259
239
    if (msg->msg_parent->msg_response) {
1260
0
      if (!(msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT)) {
1261
0
        log_debug("%s: ignoring transport mode"
1262
0
            " notification (policy)", __func__);
1263
0
        return (0);
1264
0
      }
1265
0
    }
1266
239
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
239
    break;
1268
388
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
388
    if (!msg->msg_e) {
1270
0
      log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted",
1271
0
          __func__);
1272
0
      return (-1);
1273
0
    }
1274
388
    if (!sa->sa_mobike) {
1275
388
      log_debug("%s: ignoring update sa addresses"
1276
388
          " notification w/o mobike: %zu", __func__, left);
1277
388
      return (0);
1278
388
    }
1279
0
    if (left != 0) {
1280
0
      log_debug("%s: ignoring malformed update sa addresses"
1281
0
          " notification: %zu", __func__, left);
1282
0
      return (0);
1283
0
    }
1284
0
    msg->msg_parent->msg_update_sa_addresses = 1;
1285
0
    break;
1286
202
  case IKEV2_N_COOKIE2:
1287
202
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
202
    if (!sa->sa_mobike) {
1293
202
      log_debug("%s: ignoring cookie2 notification"
1294
202
          " w/o mobike: %zu", __func__, left);
1295
202
      return (0);
1296
202
    }
1297
0
    if (left < IKED_COOKIE2_MIN || left > IKED_COOKIE2_MAX) {
1298
0
      log_debug("%s: ignoring malformed cookie2"
1299
0
          " notification: %zu", __func__, left);
1300
0
      return (0);
1301
0
    }
1302
0
    ibuf_free(msg->msg_cookie2);  /* should not happen */
1303
0
    if ((msg->msg_cookie2 = ibuf_new(buf, left)) == NULL) {
1304
0
      log_debug("%s: failed to get peer cookie2", __func__);
1305
0
      return (-1);
1306
0
    }
1307
0
    msg->msg_parent->msg_cookie2 = msg->msg_cookie2;
1308
0
    break;
1309
2
  case IKEV2_N_COOKIE:
1310
2
    if (msg->msg_e) {
1311
2
      log_debug("%s: N_COOKIE encrypted",
1312
2
          __func__);
1313
2
      return (-1);
1314
2
    }
1315
0
    if (left < IKED_COOKIE_MIN || left > IKED_COOKIE_MAX) {
1316
0
      log_debug("%s: ignoring malformed cookie"
1317
0
          " notification: %zu", __func__, left);
1318
0
      return (0);
1319
0
    }
1320
0
    log_debug("%s: received cookie, len %zu", __func__, left);
1321
0
    print_hex(buf, 0, left);
1322
1323
0
    ibuf_free(msg->msg_cookie);
1324
0
    if ((msg->msg_cookie = ibuf_new(buf, left)) == NULL) {
1325
0
      log_debug("%s: failed to get peer cookie", __func__);
1326
0
      return (-1);
1327
0
    }
1328
0
    msg->msg_parent->msg_cookie = msg->msg_cookie;
1329
0
    break;
1330
14
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
14
    if (msg->msg_e) {
1332
14
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
14
          __func__);
1334
14
      return (-1);
1335
14
    }
1336
0
    if (left != 0) {
1337
0
      log_debug("%s: ignoring malformed fragmentation"
1338
0
          " notification: %zu", __func__, left);
1339
0
      return (0);
1340
0
    }
1341
0
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_FRAGMENTATION;
1342
0
    break;
1343
7
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
7
    if (msg->msg_e) {
1345
7
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
7
          __func__);
1347
7
      return (-1);
1348
7
    }
1349
0
    if (sa == NULL) {
1350
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: no SA",
1351
0
          __func__);
1352
0
      return (-1);
1353
0
    }
1354
0
    if (sa->sa_sigsha2) {
1355
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: "
1356
0
          "duplicate notify", __func__);
1357
0
      return (0);
1358
0
    }
1359
0
    if (left < sizeof(signature_hash) ||
1360
0
        left % sizeof(signature_hash)) {
1361
0
      log_debug("%s: malformed signature hash notification"
1362
0
          "(%zu bytes)", __func__, left);
1363
0
      return (0);
1364
0
    }
1365
0
    while (left >= sizeof(signature_hash)) {
1366
0
      memcpy(&signature_hash, buf, sizeof(signature_hash));
1367
0
      signature_hash = betoh16(signature_hash);
1368
0
      log_debug("%s: signature hash %s (%x)", __func__,
1369
0
          print_map(signature_hash, ikev2_sighash_map),
1370
0
          signature_hash);
1371
0
      left -= sizeof(signature_hash);
1372
0
      buf += sizeof(signature_hash);
1373
0
      if (signature_hash == IKEV2_SIGHASH_SHA2_256)
1374
0
        msg->msg_parent->msg_flags
1375
0
            |= IKED_MSG_FLAGS_SIGSHA2;
1376
0
    }
1377
0
    break;
1378
27.0k
  }
1379
1380
26.0k
  return (0);
1381
27.0k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
7.11k
{
1387
7.11k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
7.11k
  if (left < sizeof(*del)) {
1390
1.39k
    log_debug("%s: malformed payload: too short for header "
1391
1.39k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.39k
    return (-1);
1393
1.39k
  }
1394
5.72k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.72k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.63k
  return (0);
1402
5.72k
}
1403
1404
int
1405
ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
1406
    struct iked_message *msg, size_t offset, size_t left)
1407
7.11k
{
1408
7.11k
  struct ikev2_delete  del;
1409
7.11k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
7.11k
  size_t       cnt, sz, len;
1411
1412
7.11k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.47k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.63k
  if (ikev2_msg_frompeer(msg) &&
1417
5.63k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.63k
  cnt = betoh16(del.del_nspi);
1421
5.63k
  sz = del.del_spisize;
1422
1423
5.63k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.63k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.63k
      sz, cnt);
1426
1427
5.63k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.32k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.32k
    return (0);
1430
5.32k
  }
1431
1432
315
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
315
  msg->msg_parent->msg_del_cnt = cnt;
1434
315
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
315
  buf = msgbuf + offset + sizeof(del);
1437
315
  len = left - sizeof(del);
1438
315
  if (len == 0 || sz == 0 || cnt == 0)
1439
292
    return (0);
1440
1441
23
  if ((len / sz) != cnt) {
1442
21
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
21
        __func__, len, sz, cnt);
1444
21
    return (-1);
1445
21
  }
1446
1447
2
  print_hex(buf, 0, len);
1448
1449
2
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
2
  return (0);
1452
23
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
18.0k
{
1458
18.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
18.0k
  if (left < sizeof(*tsp)) {
1461
2.39k
    log_debug("%s: malformed payload: too short for header "
1462
2.39k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.39k
    return (-1);
1464
2.39k
  }
1465
15.6k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
15.6k
  return (0);
1468
18.0k
}
1469
1470
int
1471
ikev2_pld_tss(struct iked *env, struct ikev2_payload *pld,
1472
    struct iked_message *msg, size_t offset, size_t left)
1473
18.0k
{
1474
18.0k
  struct ikev2_tsp     tsp;
1475
18.0k
  struct ikev2_ts      ts;
1476
18.0k
  size_t         ts_len, i;
1477
1478
18.0k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.39k
    return (-1);
1480
1481
15.6k
  offset += sizeof(tsp);
1482
15.6k
  left -= sizeof(tsp);
1483
1484
15.6k
  log_debug("%s: count %d length %zu", __func__,
1485
15.6k
      tsp.tsp_count, left);
1486
1487
30.8k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
29.2k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
12.3k
      return (-1);
1490
1491
16.8k
    log_debug("%s: type %s protoid %u length %d "
1492
16.8k
        "startport %u endport %u", __func__,
1493
16.8k
        print_map(ts.ts_type, ikev2_ts_map),
1494
16.8k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
16.8k
        betoh16(ts.ts_startport),
1496
16.8k
        betoh16(ts.ts_endport));
1497
1498
16.8k
    offset += sizeof(ts);
1499
16.8k
    left -= sizeof(ts);
1500
1501
16.8k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
16.8k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.68k
      return (-1);
1504
1505
15.1k
    offset += ts_len;
1506
15.1k
    left -= ts_len;
1507
15.1k
  }
1508
1509
1.59k
  return (0);
1510
15.6k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
29.2k
{
1516
29.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
29.2k
  size_t     ts_length;
1518
1519
29.2k
  if (left < sizeof(*ts)) {
1520
11.2k
    log_debug("%s: malformed payload: too short for header "
1521
11.2k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
11.2k
    return (-1);
1523
11.2k
  }
1524
18.0k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
18.0k
  ts_length = betoh16(ts->ts_length);
1527
18.0k
  if (ts_length < sizeof(*ts)) {
1528
312
    log_debug("%s: malformed payload: shorter than minimum header "
1529
312
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
312
    return (-1);
1531
312
  }
1532
17.7k
  if (left < ts_length) {
1533
864
    log_debug("%s: malformed payload: too long for payload size "
1534
864
        "(%zu < %zu)", __func__, left, ts_length);
1535
864
    return (-1);
1536
864
  }
1537
1538
16.8k
  return (0);
1539
17.7k
}
1540
1541
int
1542
ikev2_pld_ts(struct iked *env, struct ikev2_payload *pld,
1543
    struct iked_message *msg, size_t offset, size_t left, unsigned int type)
1544
16.8k
{
1545
16.8k
  struct sockaddr_in     start4, end4;
1546
16.8k
  struct sockaddr_in6    start6, end6;
1547
16.8k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
16.8k
  uint8_t       *ptr;
1549
1550
16.8k
  ptr = msgbuf + offset;
1551
1552
16.8k
  switch (type) {
1553
6.12k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
6.12k
    if (left < 2 * 4) {
1555
323
      log_debug("%s: malformed payload: too short "
1556
323
          "for ipv4 addr range (%zu < %u)",
1557
323
          __func__, left, 2 * 4);
1558
323
      return (-1);
1559
323
    }
1560
1561
5.80k
    bzero(&start4, sizeof(start4));
1562
5.80k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
5.80k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
5.80k
    ptr += 4;
1568
5.80k
    left -= 4;
1569
1570
5.80k
    bzero(&end4, sizeof(end4));
1571
5.80k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
5.80k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
5.80k
    left -= 4;
1577
1578
5.80k
    log_debug("%s: start %s end %s", __func__,
1579
5.80k
        print_addr(&start4), print_addr(&end4));
1580
5.80k
    break;
1581
1.35k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.35k
    if (left < 2 * 16) {
1583
252
      log_debug("%s: malformed payload: too short "
1584
252
          "for ipv6 addr range (%zu < %u)",
1585
252
          __func__, left, 2 * 16);
1586
252
      return (-1);
1587
252
    }
1588
1.09k
    bzero(&start6, sizeof(start6));
1589
1.09k
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
1.09k
    memcpy(&start6.sin6_addr, ptr, 16);
1594
1.09k
    ptr += 16;
1595
1.09k
    left -= 16;
1596
1597
1.09k
    bzero(&end6, sizeof(end6));
1598
1.09k
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
1.09k
    memcpy(&end6.sin6_addr, ptr, 16);
1603
1.09k
    left -= 16;
1604
1605
1.09k
    log_debug("%s: start %s end %s", __func__,
1606
1.09k
        print_addr(&start6), print_addr(&end6));
1607
1.09k
    break;
1608
9.40k
  default:
1609
9.40k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
9.40k
    return (0);
1611
16.8k
  }
1612
1613
6.90k
  if (left > 0) {
1614
1.10k
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
1.10k
        __func__, left);
1616
1.10k
    return (-1);
1617
1.10k
  }
1618
1619
5.79k
  return (0);
1620
6.90k
}
1621
1622
int
1623
ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
1624
    struct iked_message *msg, size_t offset, size_t left)
1625
0
{
1626
0
  struct iked_sa      *sa = msg->msg_sa;
1627
0
  struct iked_frag    *sa_frag = &sa->sa_fragments;
1628
0
  struct iked_frag_entry    *el;
1629
0
  struct ikev2_frag_payload  frag;
1630
0
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1631
0
  uint8_t       *buf;
1632
0
  struct ibuf     *e = NULL;
1633
0
  size_t         frag_num, frag_total;
1634
0
  size_t         len;
1635
0
  int        ret = -1;
1636
0
  int        processed = 0;
1637
0
  ssize_t        elen;
1638
1639
0
  buf = msgbuf + offset;
1640
0
  memcpy(&frag, buf, sizeof(frag));
1641
0
  frag_num = betoh16(frag.frag_num);
1642
0
  frag_total = betoh16(frag.frag_total);
1643
1644
0
  offset += sizeof(frag);
1645
0
  buf = msgbuf + offset;
1646
0
  len = left - sizeof(frag);
1647
1648
0
  ikestat_inc(env, ikes_frag_rcvd);
1649
1650
  /* Limit number of total fragments to avoid DOS */
1651
0
  if (frag_total > IKED_FRAG_TOTAL_MAX ) {
1652
0
    log_debug("%s: Total Fragments too big  %zu",
1653
0
        __func__, frag_total);
1654
0
    goto dropall;
1655
0
  }
1656
1657
  /* Check sanity of fragment header */
1658
0
  if (frag_num == 0 || frag_total == 0) {
1659
0
    log_debug("%s: Malformed fragment received: %zu of %zu",
1660
0
        __func__, frag_num, frag_total);
1661
0
    goto done;
1662
0
  }
1663
0
  log_debug("%s: Received fragment: %zu of %zu",
1664
0
      __func__, frag_num, frag_total);
1665
1666
  /* Drop fragment if frag_num and frag_total don't match */
1667
0
  if (frag_num > frag_total)
1668
0
    goto done;
1669
1670
  /* Decrypt fragment */
1671
0
  if ((e = ibuf_new(buf, len)) == NULL)
1672
0
    goto done;
1673
1674
0
  if ((e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e))
1675
0
      == NULL ) {
1676
0
    log_debug("%s: Failed to decrypt fragment: %zu of %zu",
1677
0
        __func__, frag_num, frag_total);
1678
0
    goto done;
1679
0
  }
1680
0
  elen = ibuf_size(e);
1681
1682
  /* Check new fragmented message */
1683
0
  if (sa_frag->frag_arr == NULL) {
1684
0
    sa_frag->frag_arr = recallocarray(NULL, 0, frag_total,
1685
0
        sizeof(struct iked_frag_entry*));
1686
0
    if (sa_frag->frag_arr == NULL) {
1687
0
      log_info("%s: recallocarray sa_frag->frag_arr.", __func__);
1688
0
      goto done;
1689
0
    }
1690
0
    sa_frag->frag_total = frag_total;
1691
0
  } else {
1692
    /* Drop all fragments if frag_total doesn't match previous */
1693
0
    if (frag_total != sa_frag->frag_total)
1694
0
      goto dropall;
1695
1696
    /* Silent drop if fragment already stored */
1697
0
    if (sa_frag->frag_arr[frag_num-1] != NULL)
1698
0
      goto done;
1699
0
  }
1700
1701
  /* The first fragments IKE header determines pld_nextpayload */
1702
0
  if (frag_num == 1)
1703
0
    sa_frag->frag_nextpayload = pld->pld_nextpayload;
1704
1705
  /* Insert new list element */
1706
0
  el = calloc(1, sizeof(struct iked_frag_entry));
1707
0
  if (el == NULL) {
1708
0
    log_info("%s: Failed allocating new fragment: %zu of %zu",
1709
0
        __func__, frag_num, frag_total);
1710
0
    goto done;
1711
0
  }
1712
1713
0
  sa_frag->frag_arr[frag_num-1] = el;
1714
0
  el->frag_size = elen;
1715
0
  el->frag_data = calloc(1, elen);
1716
0
  if (el->frag_data == NULL) {
1717
0
    log_debug("%s: Failed allocating new fragment data: %zu of %zu",
1718
0
        __func__, frag_num, frag_total);
1719
0
    goto done;
1720
0
  }
1721
1722
  /* Copy plaintext to fragment */
1723
0
  memcpy(el->frag_data, ibuf_seek(e, 0, 0), elen);
1724
0
  sa_frag->frag_total_size += elen;
1725
0
  sa_frag->frag_count++;
1726
1727
  /* If all frags are received start reassembly */
1728
0
  if (sa_frag->frag_count == sa_frag->frag_total) {
1729
0
    log_debug("%s: All fragments received: %zu of %zu",
1730
0
        __func__, frag_num, frag_total);
1731
0
    ret = ikev2_frags_reassemble(env, pld, msg);
1732
0
  } else {
1733
0
    ret = 0;
1734
0
  }
1735
0
  processed = 1;
1736
1737
0
done:
1738
0
  if (!processed)
1739
0
    ikestat_inc(env, ikes_frag_rcvd_drop);
1740
0
  ibuf_free(e);
1741
0
  return (ret);
1742
0
dropall:
1743
0
  ikestat_add(env, ikes_frag_rcvd_drop, sa_frag->frag_count + 1);
1744
0
  config_free_fragments(sa_frag);
1745
0
  ibuf_free(e);
1746
0
  return -1;
1747
0
}
1748
1749
int
1750
ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
1751
    struct iked_message *msg)
1752
0
{
1753
0
  struct iked_frag    *sa_frag = &msg->msg_sa->sa_fragments;
1754
0
  struct ibuf     *e = NULL;
1755
0
  struct iked_frag_entry    *el;
1756
0
  uint8_t       *ptr;
1757
0
  size_t         offset;
1758
0
  size_t         i;
1759
0
  struct iked_message    emsg;
1760
0
  int        ret = -1;
1761
0
  int        processed = 0;
1762
1763
  /* Reassemble fragments to single buffer */
1764
0
  if ((e = ibuf_new(NULL, sa_frag->frag_total_size)) == NULL) {
1765
0
    log_debug("%s: Failed allocating SK buffer.", __func__);
1766
0
    goto done;
1767
0
  }
1768
1769
  /* Empty queue to new buffer */
1770
0
  offset = 0;
1771
0
  for (i = 0; i < sa_frag->frag_total; i++) {
1772
0
    if ((el = sa_frag->frag_arr[i]) == NULL)
1773
0
      fatalx("Tried to reassemble shallow frag_arr");
1774
0
    ptr = ibuf_seek(e, offset, el->frag_size);
1775
0
    if (ptr == NULL) {
1776
0
      log_info("%s: failed to reassemble fragments", __func__);
1777
0
      goto done;
1778
0
    }
1779
0
    memcpy(ptr, el->frag_data, el->frag_size);
1780
0
    offset += el->frag_size;
1781
0
  }
1782
1783
0
  log_debug("%s: Defragmented length %zd", __func__,
1784
0
      sa_frag->frag_total_size);
1785
0
  print_hex(ibuf_data(e), 0,  sa_frag->frag_total_size);
1786
1787
  /* Drop the original request's packets from the retransmit queue */
1788
0
  if (msg->msg_response)
1789
0
    ikev2_msg_dispose(env, &msg->msg_sa->sa_requests,
1790
0
        ikev2_msg_lookup(env, &msg->msg_sa->sa_requests, msg,
1791
0
        msg->msg_exchange));
1792
1793
  /*
1794
   * Parse decrypted payload
1795
   */
1796
0
  bzero(&emsg, sizeof(emsg));
1797
0
  memcpy(&emsg, msg, sizeof(*msg));
1798
0
  emsg.msg_data = e;
1799
0
  emsg.msg_e = 1;
1800
0
  emsg.msg_parent = msg;
1801
0
  TAILQ_INIT(&emsg.msg_proposals);
1802
1803
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1804
0
      sa_frag->frag_nextpayload);
1805
0
  processed = 1;
1806
0
done:
1807
0
  if (processed)
1808
0
    ikestat_add(env, ikes_frag_reass_ok, sa_frag->frag_total);
1809
0
  else
1810
0
    ikestat_add(env, ikes_frag_reass_drop, sa_frag->frag_total);
1811
0
  config_free_fragments(sa_frag);
1812
0
  ibuf_free(e);
1813
1814
0
  return (ret);
1815
0
}
1816
1817
int
1818
ikev2_pld_e(struct iked *env, struct ikev2_payload *pld,
1819
    struct iked_message *msg, size_t offset, size_t left)
1820
0
{
1821
0
  struct iked_sa    *sa = msg->msg_sa;
1822
0
  struct ibuf   *e = NULL;
1823
0
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1824
0
  struct iked_message  emsg;
1825
0
  uint8_t     *buf;
1826
0
  size_t       len;
1827
0
  int      ret = -1;
1828
1829
0
  if (sa->sa_fragments.frag_arr != NULL) {
1830
0
    log_warn("%s: Received SK payload when SKFs are in queue.",
1831
0
        __func__);
1832
0
    config_free_fragments(&sa->sa_fragments);
1833
0
    return (ret);
1834
0
  }
1835
1836
0
  buf = msgbuf + offset;
1837
0
  len = left;
1838
1839
0
  if ((e = ibuf_new(buf, len)) == NULL)
1840
0
    goto done;
1841
1842
0
  if (ikev2_msg_frompeer(msg)) {
1843
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1844
0
  } else {
1845
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1846
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1847
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1848
0
  }
1849
1850
0
  if (e == NULL)
1851
0
    goto done;
1852
1853
  /*
1854
   * Parse decrypted payload
1855
   */
1856
0
  bzero(&emsg, sizeof(emsg));
1857
0
  memcpy(&emsg, msg, sizeof(*msg));
1858
0
  emsg.msg_data = e;
1859
0
  emsg.msg_e = 1;
1860
0
  emsg.msg_parent = msg;
1861
0
  TAILQ_INIT(&emsg.msg_proposals);
1862
1863
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1864
0
      pld->pld_nextpayload);
1865
1866
0
 done:
1867
0
  ibuf_free(e);
1868
1869
0
  return (ret);
1870
0
}
1871
1872
int
1873
ikev2_validate_cp(struct iked_message *msg, size_t offset, size_t left,
1874
    struct ikev2_cp *cp)
1875
9.77k
{
1876
9.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
9.77k
  if (left < sizeof(*cp)) {
1879
3.14k
    log_debug("%s: malformed payload: too short for header "
1880
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
3.14k
    return (-1);
1882
3.14k
  }
1883
6.63k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
6.63k
  return (0);
1886
9.77k
}
1887
1888
int
1889
ikev2_pld_cp(struct iked *env, struct ikev2_payload *pld,
1890
    struct iked_message *msg, size_t offset, size_t left)
1891
9.77k
{
1892
9.77k
  struct ikev2_cp    cp;
1893
9.77k
  struct ikev2_cfg  *cfg;
1894
9.77k
  struct iked_addr  *addr;
1895
9.77k
  struct sockaddr_in  *in4;
1896
9.77k
  struct sockaddr_in6 *in6;
1897
9.77k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
9.77k
  uint8_t     *ptr;
1899
9.77k
  size_t       len;
1900
9.77k
  int      cfg_type;
1901
1902
9.77k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
3.14k
    return (-1);
1904
1905
6.63k
  ptr = msgbuf + offset + sizeof(cp);
1906
6.63k
  len = left - sizeof(cp);
1907
1908
6.63k
  log_debug("%s: type %s length %zu",
1909
6.63k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
6.63k
  print_hex(ptr, 0, len);
1911
1912
14.4k
  while (len > 0) {
1913
9.33k
    if (len < sizeof(*cfg)) {
1914
352
      log_debug("%s: malformed payload: too short for cfg "
1915
352
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
352
      return (-1);
1917
352
    }
1918
8.98k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.98k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.98k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.98k
        betoh16(cfg->cfg_type),
1923
8.98k
        betoh16(cfg->cfg_length));
1924
1925
8.98k
    ptr += sizeof(*cfg);
1926
8.98k
    len -= sizeof(*cfg);
1927
1928
8.98k
    if (len < betoh16(cfg->cfg_length)) {
1929
1.12k
      log_debug("%s: malformed payload: too short for "
1930
1.12k
          "cfg_length (%zu < %u)", __func__, len,
1931
1.12k
          betoh16(cfg->cfg_length));
1932
1.12k
      return (-1);
1933
1.12k
    }
1934
1935
7.85k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.85k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.85k
    switch (cfg_type) {
1939
844
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.50k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.50k
      if (!ikev2_msg_frompeer(msg))
1942
735
        break;
1943
769
      if (betoh16(cfg->cfg_length) == 0)
1944
309
        break;
1945
      /* XXX multiple-valued */
1946
460
      if (betoh16(cfg->cfg_length) < 4) {
1947
6
        log_debug("%s: malformed payload: too short "
1948
6
            "for ipv4 addr (%u < %u)",
1949
6
            __func__, betoh16(cfg->cfg_length), 4);
1950
6
        return (-1);
1951
6
      }
1952
454
      switch(cfg_type) {
1953
355
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
355
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
238
          log_debug("%s: address already set", __func__);
1956
238
          goto skip;
1957
238
        }
1958
117
        break;
1959
117
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
99
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
51
          log_debug("%s: dns already set", __func__);
1962
51
          goto skip;
1963
51
        }
1964
48
        break;
1965
48
      default:
1966
0
        break;
1967
454
      }
1968
165
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
165
      addr->addr_af = AF_INET;
1973
165
      in4 = (struct sockaddr_in *)&addr->addr;
1974
165
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
165
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
165
      switch(cfg_type) {
1980
117
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
117
        msg->msg_parent->msg_cp_addr = addr;
1982
117
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
117
            print_addr(&addr->addr));
1984
117
        break;
1985
48
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
48
        msg->msg_parent->msg_cp_dns = addr;
1987
48
        log_debug("%s: IP4_DNS %s", __func__,
1988
48
            print_addr(&addr->addr));
1989
48
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
165
      }
1995
165
      break;
1996
2.25k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
3.05k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
3.05k
      if (!ikev2_msg_frompeer(msg))
1999
2.86k
        break;
2000
198
      if (betoh16(cfg->cfg_length) == 0)
2001
67
        break;
2002
      /* XXX multiple-valued */
2003
131
      if (betoh16(cfg->cfg_length) < 16) {
2004
4
        log_debug("%s: malformed payload: too short "
2005
4
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
4
            __func__, betoh16(cfg->cfg_length), 16);
2007
4
        return (-1);
2008
4
      }
2009
127
      switch(cfg_type) {
2010
87
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
87
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
40
        break;
2016
40
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
40
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
36
          log_debug("%s: dns already set", __func__);
2019
36
          goto skip;
2020
36
        }
2021
4
        break;
2022
127
      }
2023
44
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
44
      addr->addr_af = AF_INET6;
2028
44
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
44
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
44
      memcpy(&in6->sin6_addr, ptr, 16);
2034
44
      switch(cfg_type) {
2035
40
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
40
        msg->msg_parent->msg_cp_addr6 = addr;
2037
40
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
40
            print_addr(&addr->addr));
2039
40
        break;
2040
4
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
4
        msg->msg_parent->msg_cp_dns = addr;
2042
4
        log_debug("%s: IP6_DNS %s", __func__,
2043
4
            print_addr(&addr->addr));
2044
4
        break;
2045
0
      default:
2046
0
        log_debug("%s: cfg %s/%d", __func__,
2047
0
            print_addr(&addr->addr), ptr[16]);
2048
0
        break;
2049
44
      }
2050
44
      break;
2051
7.85k
    }
2052
2053
7.84k
 skip:
2054
7.84k
    ptr += betoh16(cfg->cfg_length);
2055
7.84k
    len -= betoh16(cfg->cfg_length);
2056
7.84k
  }
2057
2058
5.15k
  if (!ikev2_msg_frompeer(msg))
2059
4.95k
    return (0);
2060
2061
192
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
192
  return (0);
2064
5.15k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
17.0k
{
2070
17.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
17.0k
  if (left < sizeof(*hdr)) {
2073
7.15k
    log_debug("%s: malformed payload: too short for header "
2074
7.15k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
7.15k
    return (-1);
2076
7.15k
  }
2077
9.94k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.94k
  return (0);
2080
17.0k
}
2081
2082
int
2083
ikev2_pld_eap(struct iked *env, struct ikev2_payload *pld,
2084
    struct iked_message *msg, size_t offset, size_t left)
2085
17.0k
{
2086
17.0k
  struct eap_header    hdr;
2087
17.0k
  struct eap_message    *eap = NULL;
2088
17.0k
  const struct iked_sa    *sa = msg->msg_sa;
2089
17.0k
  size_t         len;
2090
2091
17.0k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
7.15k
    return (-1);
2093
9.94k
  len = betoh16(hdr.eap_length);
2094
2095
9.94k
  if (len < sizeof(*eap)) {
2096
3.45k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.45k
        print_map(hdr.eap_code, eap_code_map),
2098
3.45k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
6.48k
  } else {
2100
    /* Now try to get the indicated length */
2101
6.48k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
3.28k
      log_debug("%s: invalid EAP length", __func__);
2103
3.28k
      return (-1);
2104
3.28k
    }
2105
2106
3.20k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.20k
        print_map(eap->eap_code, eap_code_map),
2108
3.20k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.20k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.20k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.20k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.20k
  }
2115
2116
6.65k
  return (0);
2117
9.94k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/ikev2_pld.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2_pld.c,v 1.133 2023/09/02 18:36:30 tobhe Exp $ */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2014 Hans-Joerg Hoexer
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <string.h>
32
#include <signal.h>
33
#include <endian.h>
34
#include <errno.h>
35
#include <err.h>
36
#include <event.h>
37
38
#include <openssl/sha.h>
39
#include <openssl/evp.h>
40
41
#include "iked.h"
42
#include "ikev2.h"
43
#include "eap.h"
44
#include "dh.h"
45
46
int  ikev2_validate_pld(struct iked_message *, size_t, size_t,
47
      struct ikev2_payload *);
48
int  ikev2_pld_payloads(struct iked *, struct iked_message *,
49
      size_t, size_t, unsigned int);
50
int  ikev2_validate_sa(struct iked_message *, size_t, size_t,
51
      struct ikev2_sa_proposal *);
52
int  ikev2_pld_sa(struct iked *, struct ikev2_payload *,
53
      struct iked_message *, size_t, size_t);
54
int  ikev2_validate_xform(struct iked_message *, size_t, size_t,
55
      struct ikev2_transform *);
56
int  ikev2_pld_xform(struct iked *, struct iked_message *,
57
      size_t, size_t);
58
int  ikev2_validate_attr(struct iked_message *, size_t, size_t,
59
      struct ikev2_attribute *);
60
int  ikev2_pld_attr(struct iked *, struct ikev2_transform *,
61
      struct iked_message *, size_t, size_t);
62
int  ikev2_validate_ke(struct iked_message *, size_t, size_t,
63
      struct ikev2_keyexchange *);
64
int  ikev2_pld_ke(struct iked *, struct ikev2_payload *,
65
      struct iked_message *, size_t, size_t);
66
int  ikev2_validate_id(struct iked_message *, size_t, size_t,
67
      struct ikev2_id *);
68
int  ikev2_pld_id(struct iked *, struct ikev2_payload *,
69
      struct iked_message *, size_t, size_t, unsigned int);
70
int  ikev2_validate_cert(struct iked_message *, size_t, size_t,
71
      struct ikev2_cert *);
72
int  ikev2_pld_cert(struct iked *, struct ikev2_payload *,
73
      struct iked_message *, size_t, size_t);
74
int  ikev2_validate_certreq(struct iked_message *, size_t, size_t,
75
      struct ikev2_cert *);
76
int  ikev2_pld_certreq(struct iked *, struct ikev2_payload *,
77
      struct iked_message *, size_t, size_t);
78
int  ikev2_pld_nonce(struct iked *, struct ikev2_payload *,
79
      struct iked_message *, size_t, size_t);
80
int  ikev2_validate_notify(struct iked_message *, size_t, size_t,
81
      struct ikev2_notify *);
82
int  ikev2_pld_notify(struct iked *, struct ikev2_payload *,
83
      struct iked_message *, size_t, size_t);
84
int  ikev2_validate_delete(struct iked_message *, size_t, size_t,
85
      struct ikev2_delete *);
86
int  ikev2_pld_delete(struct iked *, struct ikev2_payload *,
87
      struct iked_message *, size_t, size_t);
88
int  ikev2_validate_tss(struct iked_message *, size_t, size_t,
89
      struct ikev2_tsp *);
90
int  ikev2_pld_tss(struct iked *, struct ikev2_payload *,
91
      struct iked_message *, size_t, size_t);
92
int  ikev2_validate_ts(struct iked_message *, size_t, size_t,
93
      struct ikev2_ts *);
94
int  ikev2_pld_ts(struct iked *, struct ikev2_payload *,
95
      struct iked_message *, size_t, size_t, unsigned int);
96
int  ikev2_validate_auth(struct iked_message *, size_t, size_t,
97
      struct ikev2_auth *);
98
int  ikev2_pld_auth(struct iked *, struct ikev2_payload *,
99
      struct iked_message *, size_t, size_t);
100
int  ikev2_pld_e(struct iked *, struct ikev2_payload *,
101
      struct iked_message *, size_t, size_t);
102
int  ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
103
      struct iked_message *msg, size_t offset, size_t left);
104
int  ikev2_frags_reassemble(struct iked *env,
105
      struct ikev2_payload *pld, struct iked_message *msg);
106
int  ikev2_validate_cp(struct iked_message *, size_t, size_t,
107
      struct ikev2_cp *);
108
int  ikev2_pld_cp(struct iked *, struct ikev2_payload *,
109
      struct iked_message *, size_t, size_t);
110
int  ikev2_validate_eap(struct iked_message *, size_t, size_t,
111
      struct eap_header *);
112
int  ikev2_pld_eap(struct iked *, struct ikev2_payload *,
113
      struct iked_message *, size_t, size_t);
114
115
int
116
ikev2_pld_parse(struct iked *env, struct ike_header *hdr,
117
    struct iked_message *msg, size_t offset)
118
13.1k
{
119
13.1k
  log_debug("%s: header ispi %s rspi %s"
120
13.1k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
13.1k
      " msgid %d length %u response %d", __func__,
122
13.1k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
13.1k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
13.1k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
13.1k
      hdr->ike_version,
126
13.1k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
13.1k
      hdr->ike_flags,
128
13.1k
      betoh32(hdr->ike_msgid),
129
13.1k
      betoh32(hdr->ike_length),
130
13.1k
      msg->msg_response);
131
132
13.1k
  if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) {
133
4
    log_debug("%s: short message", __func__);
134
4
    return (-1);
135
4
  }
136
137
13.1k
  offset += sizeof(*hdr);
138
139
13.1k
  return (ikev2_pld_payloads(env, msg, offset,
140
13.1k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
13.1k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
235k
{
147
235k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
235k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
235k
  if (left < sizeof(*pld)) {
152
1.73k
    log_debug("%s: malformed payload: too short for generic "
153
1.73k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.73k
    return (-1);
155
1.73k
  }
156
233k
  memcpy(pld, msgbuf + offset, sizeof(*pld));
157
158
  /*
159
   * We need at least the specified number of bytes.
160
   * pld_length is the full size of the payload including
161
   * the generic payload header.
162
   */
163
233k
  pld_length = betoh16(pld->pld_length);
164
233k
  if (left < pld_length) {
165
5.87k
    log_debug("%s: malformed payload: shorter than specified "
166
5.87k
        "(%zu < %zu)", __func__, left, pld_length);
167
5.87k
    return (-1);
168
5.87k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
228k
  if (pld_length < sizeof(*pld)) {
174
2.36k
    log_debug("%s: malformed payload: shorter than minimum "
175
2.36k
        "header size (%zu < %zu)", __func__, pld_length,
176
2.36k
        sizeof(*pld));
177
2.36k
    return (-1);
178
2.36k
  }
179
180
225k
  return (0);
181
228k
}
182
183
int
184
ikev2_pld_payloads(struct iked *env, struct iked_message *msg,
185
    size_t offset, size_t length, unsigned int payload)
186
13.1k
{
187
13.1k
  struct ikev2_payload   pld;
188
13.1k
  unsigned int     e;
189
13.1k
  int      ret;
190
13.1k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
13.1k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
13.1k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
13.1k
  total = length - offset;
198
199
238k
  while (payload != 0 && offset < length) {
200
235k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
9.97k
      return (-1);
202
203
225k
    log_debug("%s: %spayload %s"
204
225k
        " nextpayload %s critical 0x%02x length %d",
205
225k
        __func__, e ? "decrypted " : "",
206
225k
        print_map(payload, ikev2_payload_map),
207
225k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
225k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
225k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
225k
    offset += sizeof(pld);
213
225k
    total -= sizeof(pld);
214
225k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
225k
    ret = 0;
216
217
225k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
28.2k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
28.2k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
28.2k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
8.28k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
8.28k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
8.28k
      break;
226
12.9k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
19.4k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
19.4k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
19.4k
          payload);
230
19.4k
      break;
231
5.80k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.80k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.80k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
12.1k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
12.1k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
12.1k
      break;
238
8.17k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
8.17k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
8.17k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
242
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
242
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
242
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
32.4k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
32.4k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
32.4k
      break;
249
7.11k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
7.11k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
7.11k
      break;
252
4.65k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
18.1k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
18.1k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
18.1k
      break;
256
0
    case IKEV2_PAYLOAD_SK:
257
0
      ret = ikev2_pld_e(env, &pld, msg, offset, left);
258
0
      break;
259
0
    case IKEV2_PAYLOAD_SKF:
260
0
      ret = ikev2_pld_ef(env, &pld, msg, offset, left);
261
0
      break;
262
9.77k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
9.77k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
9.77k
      break;
265
17.1k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
17.1k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
17.1k
      break;
268
58.8k
    default:
269
58.8k
      print_hex(msgbuf, offset,
270
58.8k
          betoh16(pld.pld_length) - sizeof(pld));
271
58.8k
      break;
272
225k
    }
273
274
225k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
723
      (void)ikev2_send_informational(env, msg);
276
723
      return (-1);
277
723
    }
278
279
    /* Encrypted payloads must appear last */
280
224k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
224k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
224k
    payload = pld.pld_nextpayload;
285
224k
    offset += left;
286
224k
    total -= left;
287
224k
  }
288
289
2.47k
  return (0);
290
13.1k
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
32.6k
{
296
32.6k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
32.6k
  size_t     sap_length;
298
299
32.6k
  if (left < sizeof(*sap)) {
300
13.9k
    log_debug("%s: malformed payload: too short for header "
301
13.9k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.9k
    return (-1);
303
13.9k
  }
304
18.7k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.7k
  sap_length = betoh16(sap->sap_length);
307
18.7k
  if (sap_length < sizeof(*sap)) {
308
5.01k
    log_debug("%s: malformed payload: shorter than minimum header "
309
5.01k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
5.01k
    return (-1);
311
5.01k
  }
312
13.6k
  if (left < sap_length) {
313
2.30k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.30k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.30k
    return (-1);
316
2.30k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
11.3k
  if (!sap->sap_more && left != sap_length) {
322
30
    log_debug("%s: malformed payload: SA payload length mismatches "
323
30
        "single proposal substructure length (%zu != %zu)",
324
30
        __func__, left, sap_length);
325
30
    return (-1);
326
30
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
11.3k
  if (sap->sap_more && left <= sap_length) {
332
839
    log_debug("%s: malformed payload: SA payload too small for "
333
839
        "further proposals (%zu <= %zu)", __func__,
334
839
        left, sap_length);
335
839
    return (-1);
336
839
  }
337
10.5k
  return (0);
338
11.3k
}
339
340
int
341
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
342
    struct iked_message *msg, size_t offset, size_t left)
343
28.2k
{
344
28.2k
  struct ikev2_sa_proposal   sap;
345
28.2k
  struct iked_proposal    *prop = NULL;
346
28.2k
  uint32_t       spi32;
347
28.2k
  uint64_t       spi = 0, spi64;
348
28.2k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
28.2k
  int        r;
350
28.2k
  struct iked_proposals   *props;
351
28.2k
  size_t         total;
352
353
32.6k
  do {
354
32.6k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
22.0k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.5k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.5k
    props = &msg->msg_parent->msg_proposals;
361
362
10.5k
    offset += sizeof(sap);
363
10.5k
    left -= sizeof(sap);
364
365
10.5k
    if (sap.sap_spisize) {
366
1.40k
      if (left < sap.sap_spisize) {
367
646
        log_debug("%s: malformed payload: SPI larger than "
368
646
            "actual payload (%zu < %d)", __func__, left,
369
646
            sap.sap_spisize);
370
646
        return (-1);
371
646
      }
372
755
      if (total < sap.sap_spisize) {
373
135
        log_debug("%s: malformed payload: SPI larger than "
374
135
            "proposal (%zu < %d)", __func__, total,
375
135
            sap.sap_spisize);
376
135
        return (-1);
377
135
      }
378
620
      switch (sap.sap_spisize) {
379
290
      case 4:
380
290
        memcpy(&spi32, msgbuf + offset, 4);
381
290
        spi = betoh32(spi32);
382
290
        break;
383
200
      case 8:
384
200
        memcpy(&spi64, msgbuf + offset, 8);
385
200
        spi = betoh64(spi64);
386
200
        break;
387
130
      default:
388
130
        log_debug("%s: unsupported SPI size %d",
389
130
            __func__, sap.sap_spisize);
390
130
        return (-1);
391
620
      }
392
393
490
      offset += sap.sap_spisize;
394
490
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
490
      total -= sap.sap_spisize;
398
490
    }
399
400
    /*
401
     * As we verified sanity of packet headers, this check will
402
     * be always false, but just to be sure we keep it.
403
     */
404
9.60k
    if (left < total) {
405
0
      log_debug("%s: malformed payload: too long for payload "
406
0
          "(%zu < %zu)", __func__, left, total);
407
0
      return (-1);
408
0
    }
409
410
9.60k
    log_debug("%s: more %d reserved %d length %d"
411
9.60k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.60k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.60k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.60k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.60k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.60k
    if (ikev2_msg_frompeer(msg)) {
418
69
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
69
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
69
        log_debug("%s: invalid proposal", __func__);
421
69
        return (-1);
422
69
      }
423
0
      prop = msg->msg_parent->msg_prop;
424
0
      prop->prop_peerspi.spi = spi;
425
0
      prop->prop_peerspi.spi_protoid = sap.sap_protoid;
426
0
      prop->prop_peerspi.spi_size = sap.sap_spisize;
427
428
0
      prop->prop_localspi.spi_protoid = sap.sap_protoid;
429
0
      prop->prop_localspi.spi_size = sap.sap_spisize;
430
0
    }
431
432
    /*
433
     * Parse the attached transforms
434
     */
435
9.53k
    if (sap.sap_transforms) {
436
5.45k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.45k
      if ((r == -2) && ikev2_msg_frompeer(msg)) {
438
0
        log_debug("%s: invalid proposal transform",
439
0
            __func__);
440
441
        /* cleanup and ignore proposal */
442
0
        config_free_proposal(props, prop);
443
0
        prop = msg->msg_parent->msg_prop = NULL;
444
5.45k
      } else if (r != 0) {
445
4.37k
        log_debug("%s: invalid proposal transforms",
446
4.37k
            __func__);
447
4.37k
        return (-1);
448
4.37k
      }
449
5.45k
    }
450
451
5.16k
    offset += total;
452
5.16k
    left -= total;
453
5.16k
  } while (sap.sap_more);
454
455
750
  return (0);
456
28.2k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
7.30k
{
462
7.30k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
7.30k
  size_t     xfrm_length;
464
465
7.30k
  if (total < sizeof(*xfrm)) {
466
625
    log_debug("%s: malformed payload: too short for header "
467
625
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
625
    return (-1);
469
625
  }
470
6.67k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.67k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.67k
  if (xfrm_length < sizeof(*xfrm)) {
474
1.12k
    log_debug("%s: malformed payload: shorter than minimum header "
475
1.12k
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
1.12k
    return (-1);
477
1.12k
  }
478
5.54k
  if (total < xfrm_length) {
479
644
    log_debug("%s: malformed payload: too long for payload size "
480
644
        "(%zu < %zu)", __func__, total, xfrm_length);
481
644
    return (-1);
482
644
  }
483
484
4.90k
  return (0);
485
5.54k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
7.30k
{
491
7.30k
  struct ikev2_transform     xfrm;
492
7.30k
  char         id[BUFSIZ];
493
7.30k
  int        ret = 0;
494
7.30k
  int        r;
495
7.30k
  size_t         xfrm_length;
496
497
7.30k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.39k
    return (-1);
499
500
4.90k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.90k
  switch (xfrm.xfrm_type) {
503
1.07k
  case IKEV2_XFORMTYPE_ENCR:
504
1.07k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.07k
        ikev2_xformencr_map), sizeof(id));
506
1.07k
    break;
507
777
  case IKEV2_XFORMTYPE_PRF:
508
777
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
777
        ikev2_xformprf_map), sizeof(id));
510
777
    break;
511
154
  case IKEV2_XFORMTYPE_INTEGR:
512
154
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
154
        ikev2_xformauth_map), sizeof(id));
514
154
    break;
515
567
  case IKEV2_XFORMTYPE_DH:
516
567
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
567
        ikev2_xformdh_map), sizeof(id));
518
567
    break;
519
1.00k
  case IKEV2_XFORMTYPE_ESN:
520
1.00k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
1.00k
        ikev2_xformesn_map), sizeof(id));
522
1.00k
    break;
523
1.32k
  default:
524
1.32k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.32k
    break;
526
4.90k
  }
527
528
4.90k
  log_debug("%s: more %d reserved %d length %zu"
529
4.90k
      " type %s id %s",
530
4.90k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.90k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.90k
  msg->msg_attrlength = 0;
537
4.90k
  if (xfrm_length > sizeof(xfrm)) {
538
2.34k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.34k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.80k
      return (-1);
541
1.80k
    }
542
2.34k
  }
543
544
3.10k
  if (ikev2_msg_frompeer(msg)) {
545
0
    r = config_add_transform(msg->msg_parent->msg_prop,
546
0
        xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
547
0
        msg->msg_attrlength, msg->msg_attrlength);
548
0
    if (r == -1) {
549
0
      log_debug("%s: failed to add transform: alloc error",
550
0
          __func__);
551
0
      return (r);
552
0
    } else if (r == -2) {
553
0
      log_debug("%s: failed to add transform: unknown type",
554
0
          __func__);
555
0
      return (r);
556
0
    }
557
0
  }
558
559
  /* Next transform */
560
3.10k
  offset += xfrm_length;
561
3.10k
  total -= xfrm_length;
562
3.10k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.85k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.25k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
177
    log_debug("%s: less data than specified, %zu bytes left",
567
177
        __func__, total);
568
177
    ret = -1;
569
177
  }
570
571
3.10k
  return (ret);
572
3.10k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
29.4k
{
578
29.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
29.4k
  if (total < sizeof(*attr)) {
581
817
    log_debug("%s: malformed payload: too short for header "
582
817
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
817
    return (-1);
584
817
  }
585
28.6k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.6k
  return (0);
588
29.4k
}
589
590
int
591
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
592
    struct iked_message *msg, size_t offset, size_t total)
593
29.4k
{
594
29.4k
  struct ikev2_attribute     attr;
595
29.4k
  unsigned int       type;
596
29.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
29.4k
  int        ret = 0;
598
29.4k
  size_t         attr_length;
599
600
29.4k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
817
    return (-1);
602
603
28.6k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.6k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.6k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.6k
      betoh16(attr.attr_length), total);
608
609
28.6k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
22.1k
    offset += sizeof(attr);
612
22.1k
    total -= sizeof(attr);
613
614
22.1k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
47
      msg->msg_attrlength = betoh16(attr.attr_length);
616
22.1k
  } else {
617
    /* Type-Length-Value attribute */
618
6.49k
    attr_length = betoh16(attr.attr_length);
619
6.49k
    if (attr_length < sizeof(attr)) {
620
543
      log_debug("%s: malformed payload: shorter than "
621
543
          "minimum header size (%zu < %zu)", __func__,
622
543
          attr_length, sizeof(attr));
623
543
      return (-1);
624
543
    }
625
5.94k
    if (total < attr_length) {
626
443
      log_debug("%s: malformed payload: attribute larger "
627
443
          "than actual payload (%zu < %zu)", __func__,
628
443
          total, attr_length);
629
443
      return (-1);
630
443
    }
631
5.50k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.50k
        attr_length - sizeof(attr));
633
5.50k
    offset += attr_length;
634
5.50k
    total -= attr_length;
635
5.50k
  }
636
637
27.6k
  if (total > 0) {
638
    /* Next attribute */
639
27.0k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
27.0k
  }
641
642
27.6k
  return (ret);
643
28.6k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
8.28k
{
649
8.28k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
8.28k
  if (left < sizeof(*kex)) {
652
5.12k
    log_debug("%s: malformed payload: too short for header "
653
5.12k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
5.12k
    return (-1);
655
5.12k
  }
656
3.16k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
3.16k
  return (0);
659
8.28k
}
660
661
int
662
ikev2_pld_ke(struct iked *env, struct ikev2_payload *pld,
663
    struct iked_message *msg, size_t offset, size_t left)
664
8.28k
{
665
8.28k
  struct ikev2_keyexchange   kex;
666
8.28k
  uint8_t       *buf;
667
8.28k
  size_t         len;
668
8.28k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
8.28k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
5.12k
    return (-1);
672
673
3.16k
  log_debug("%s: dh group %s reserved %d", __func__,
674
3.16k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
3.16k
      betoh16(kex.kex_reserved));
676
677
3.16k
  buf = msgbuf + offset + sizeof(kex);
678
3.16k
  len = left - sizeof(kex);
679
680
3.16k
  if (len == 0) {
681
1.41k
    log_debug("%s: malformed payload: no KE data given", __func__);
682
1.41k
    return (-1);
683
1.41k
  }
684
685
1.75k
  print_hex(buf, 0, len);
686
687
1.75k
  if (ikev2_msg_frompeer(msg)) {
688
27
    if (msg->msg_parent->msg_ke != NULL) {
689
4
      log_info("%s: duplicate KE payload", __func__);
690
4
      return (-1);
691
4
    }
692
23
    if ((msg->msg_parent->msg_ke = ibuf_new(buf, len)) == NULL) {
693
0
      log_debug("%s: failed to get exchange", __func__);
694
0
      return (-1);
695
0
    }
696
23
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
23
  }
698
699
1.74k
  return (0);
700
1.75k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
19.4k
{
706
19.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
19.4k
  if (left < sizeof(*id)) {
709
7.63k
    log_debug("%s: malformed payload: too short for header "
710
7.63k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.63k
    return (-1);
712
7.63k
  }
713
11.8k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.8k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.46k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.46k
        __func__);
718
6.46k
    return (-1);
719
6.46k
  }
720
721
5.38k
  return (0);
722
11.8k
}
723
724
int
725
ikev2_pld_id(struct iked *env, struct ikev2_payload *pld,
726
    struct iked_message *msg, size_t offset, size_t left, unsigned int payload)
727
19.4k
{
728
19.4k
  uint8_t       *ptr;
729
19.4k
  struct ikev2_id      id;
730
19.4k
  size_t         len;
731
19.4k
  struct iked_id      *idp, idb;
732
19.4k
  const struct iked_sa    *sa = msg->msg_sa;
733
19.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
19.4k
  char         idstr[IKED_ID_SIZE];
735
736
19.4k
  if (ikev2_validate_id(msg, offset, left, &id))
737
14.0k
    return (-1);
738
739
5.38k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
5.38k
  ptr = msgbuf + offset;
743
5.38k
  len = left;
744
745
5.38k
  idb.id_type = id.id_type;
746
5.38k
  idb.id_offset = sizeof(id);
747
5.38k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
5.38k
  if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) {
751
0
    ibuf_free(idb.id_buf);
752
0
    log_debug("%s: malformed id", __func__);
753
0
    return (-1);
754
0
  }
755
756
5.38k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
5.38k
  if (!ikev2_msg_frompeer(msg)) {
759
5.28k
    ibuf_free(idb.id_buf);
760
5.28k
    return (0);
761
5.28k
  }
762
763
101
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
101
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
59
    idp = &msg->msg_parent->msg_peerid;
766
42
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
42
    idp = &msg->msg_parent->msg_localid;
768
0
  else {
769
0
    ibuf_free(idb.id_buf);
770
0
    log_debug("%s: unexpected id payload", __func__);
771
0
    return (0);
772
0
  }
773
774
101
  if (idp->id_type) {
775
16
    ibuf_free(idb.id_buf);
776
16
    log_debug("%s: duplicate id payload", __func__);
777
16
    return (-1);
778
16
  }
779
780
85
  idp->id_buf = idb.id_buf;
781
85
  idp->id_offset = idb.id_offset;
782
85
  idp->id_type = idb.id_type;
783
784
85
  return (0);
785
101
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
5.80k
{
791
5.80k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.80k
  if (left < sizeof(*cert)) {
794
1.46k
    log_debug("%s: malformed payload: too short for header "
795
1.46k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.46k
    return (-1);
797
1.46k
  }
798
4.34k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.34k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
982
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
982
    return (-1);
802
982
  }
803
804
3.36k
  return (0);
805
4.34k
}
806
807
int
808
ikev2_pld_cert(struct iked *env, struct ikev2_payload *pld,
809
    struct iked_message *msg, size_t offset, size_t left)
810
5.80k
{
811
5.80k
  struct ikev2_cert    cert;
812
5.80k
  uint8_t       *buf;
813
5.80k
  size_t         len;
814
5.80k
  struct iked_id      *certid;
815
5.80k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.80k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.80k
  int        i;
818
819
5.80k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.44k
    return (-1);
821
3.36k
  offset += sizeof(cert);
822
823
3.36k
  buf = msgbuf + offset;
824
3.36k
  len = left - sizeof(cert);
825
826
3.36k
  log_debug("%s: type %s length %zu",
827
3.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.36k
  print_hex(buf, 0, len);
830
831
3.36k
  if (!ikev2_msg_frompeer(msg))
832
1.41k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.94k
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
290
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
290
       SPI_SA(sa, __func__));
838
290
    return (0);
839
290
  }
840
841
1.65k
  certid = &msg->msg_parent->msg_cert;
842
1.65k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
4.10k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
3.35k
      certid = &msg->msg_parent->msg_scert[i];
846
3.35k
      if (!certid->id_type)
847
605
        break;
848
3.35k
    }
849
1.35k
    if (certid->id_type) {
850
748
      log_debug("%s: too many cert payloads, ignoring",
851
748
         SPI_SA(sa, __func__));
852
748
      return (0);
853
748
    }
854
1.35k
  }
855
856
911
  if ((certid->id_buf = ibuf_new(buf, len)) == NULL) {
857
0
    log_debug("%s: failed to save cert", __func__);
858
0
    return (-1);
859
0
  }
860
911
  certid->id_type = cert.cert_type;
861
911
  certid->id_offset = 0;
862
863
911
  return (0);
864
911
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
12.1k
{
870
12.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
12.1k
  if (left < sizeof(*cert)) {
873
2.65k
    log_debug("%s: malformed payload: too short for header "
874
2.65k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.65k
    return (-1);
876
2.65k
  }
877
9.48k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
9.48k
  return (0);
880
12.1k
}
881
882
int
883
ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
884
    struct iked_message *msg, size_t offset, size_t left)
885
12.1k
{
886
12.1k
  struct ikev2_cert    cert;
887
12.1k
  struct iked_certreq   *cr;
888
12.1k
  uint8_t       *buf;
889
12.1k
  ssize_t        len;
890
12.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
12.1k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.65k
    return (-1);
894
9.48k
  offset += sizeof(cert);
895
896
9.48k
  buf = msgbuf + offset;
897
9.48k
  len = left - sizeof(cert);
898
899
9.48k
  log_debug("%s: type %s length %zd",
900
9.48k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
9.48k
  print_hex(buf, 0, len);
903
904
9.48k
  if (!ikev2_msg_frompeer(msg))
905
8.30k
    return (0);
906
907
1.18k
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
321
    if (len == 0) {
909
279
      log_info("%s: invalid length 0", __func__);
910
279
      return (0);
911
279
    }
912
42
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
9
      log_info("%s: invalid certificate request",
914
9
          __func__);
915
9
      return (-1);
916
9
    }
917
42
  }
918
919
897
  if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) {
920
0
    log_info("%s: failed to allocate certreq.", __func__);
921
0
    return (-1);
922
0
  }
923
897
  if ((cr->cr_data = ibuf_new(buf, len)) == NULL) {
924
0
    log_info("%s: failed to allocate buffer.", __func__);
925
0
    free(cr);
926
0
    return (-1);
927
0
  }
928
897
  cr->cr_type = cert.cert_type;
929
897
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
897
  return (0);
932
897
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
8.17k
{
938
8.17k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
8.17k
  if (left < sizeof(*auth)) {
941
1.85k
    log_debug("%s: malformed payload: too short for header "
942
1.85k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.85k
    return (-1);
944
1.85k
  }
945
6.31k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.31k
  if (auth->auth_method == 0) {
948
3.36k
    log_info("%s: malformed payload: invalid auth method",
949
3.36k
        __func__);
950
3.36k
    return (-1);
951
3.36k
  }
952
953
2.95k
  return (0);
954
6.31k
}
955
956
int
957
ikev2_pld_auth(struct iked *env, struct ikev2_payload *pld,
958
    struct iked_message *msg, size_t offset, size_t left)
959
8.17k
{
960
8.17k
  struct ikev2_auth    auth;
961
8.17k
  struct iked_id      *idp;
962
8.17k
  uint8_t       *buf;
963
8.17k
  size_t         len;
964
8.17k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
8.17k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.21k
    return (-1);
968
2.95k
  offset += sizeof(auth);
969
970
2.95k
  buf = msgbuf + offset;
971
2.95k
  len = left - sizeof(auth);
972
973
2.95k
  log_debug("%s: method %s length %zu",
974
2.95k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.95k
  print_hex(buf, 0, len);
977
978
2.95k
  if (!ikev2_msg_frompeer(msg))
979
2.91k
    return (0);
980
981
42
  idp = &msg->msg_parent->msg_auth;
982
42
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
41
  ibuf_free(idp->id_buf);
988
41
  idp->id_type = auth.auth_method;
989
41
  idp->id_offset = 0;
990
41
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
41
  return (0);
994
41
}
995
996
int
997
ikev2_pld_nonce(struct iked *env, struct ikev2_payload *pld,
998
    struct iked_message *msg, size_t offset, size_t left)
999
242
{
1000
242
  size_t     len;
1001
242
  uint8_t   *buf;
1002
242
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
242
  buf = msgbuf + offset;
1005
242
  len = left;
1006
1007
242
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
160
  print_hex(buf, 0, len);
1013
1014
160
  if (ikev2_msg_frompeer(msg)) {
1015
61
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
42
    if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) {
1020
0
      log_debug("%s: failed to get peer nonce", __func__);
1021
0
      return (-1);
1022
0
    }
1023
42
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
42
  }
1025
1026
141
  return (0);
1027
160
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
32.4k
{
1033
32.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
32.4k
  if (left < sizeof(*n)) {
1036
3.51k
    log_debug("%s: malformed payload: too short for header "
1037
3.51k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.51k
    return (-1);
1039
3.51k
  }
1040
28.8k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
28.8k
  return (0);
1043
32.4k
}
1044
1045
int
1046
ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
1047
    struct iked_message *msg, size_t offset, size_t left)
1048
32.4k
{
1049
32.4k
  struct ikev2_notify  n;
1050
32.4k
  const struct iked_sa  *sa = msg->msg_sa;
1051
32.4k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
32.4k
  uint32_t     spi32;
1053
32.4k
  uint64_t     spi64;
1054
32.4k
  struct iked_spi   *rekey;
1055
32.4k
  uint16_t     type;
1056
32.4k
  uint16_t     signature_hash;
1057
1058
32.4k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.51k
    return (-1);
1060
28.8k
  type = betoh16(n.n_type);
1061
1062
28.8k
  log_debug("%s: protoid %s spisize %d type %s",
1063
28.8k
      __func__,
1064
28.8k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
28.8k
      print_map(type, ikev2_n_map));
1066
1067
28.8k
  left -= sizeof(n);
1068
28.8k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
28.8k
  print_hex(buf, 0, left);
1072
1073
28.8k
  if (!ikev2_msg_frompeer(msg))
1074
1.44k
    return (0);
1075
1076
27.4k
  switch (type) {
1077
3.05k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
23.0k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
23.0k
    if (left != sizeof(md)) {
1080
16
      log_debug("%s: malformed payload: hash size mismatch"
1081
16
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
16
      return (-1);
1083
16
    }
1084
22.9k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
22.9k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
22.9k
    if (memcmp(buf, md, left) != 0) {
1088
22.9k
      log_debug("%s: %s detected NAT", __func__,
1089
22.9k
          print_map(type, ikev2_n_map));
1090
22.9k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
3.05k
        msg->msg_parent->msg_nat_detected
1092
3.05k
            |= IKED_MSG_NAT_SRC_IP;
1093
19.9k
      else
1094
19.9k
        msg->msg_parent->msg_nat_detected
1095
19.9k
            |= IKED_MSG_NAT_DST_IP;
1096
22.9k
    }
1097
22.9k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
22.9k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
22.9k
    break;
1101
6
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
6
    if (!msg->msg_e) {
1103
0
      log_debug("%s: AUTHENTICATION_FAILED not encrypted",
1104
0
          __func__);
1105
0
      return (-1);
1106
0
    }
1107
    /*
1108
     * If we are the responder, then we only accept
1109
     * AUTHENTICATION_FAILED from authenticated peers.
1110
     * If we are the initiator, the peer cannot be authenticated.
1111
     */
1112
6
    if (!sa->sa_hdr.sh_initiator) {
1113
6
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
6
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
6
            " from unauthenticated initiator",
1116
6
            __func__);
1117
6
        return (-1);
1118
6
      }
1119
6
    } else {
1120
0
      if (sa_stateok(sa, IKEV2_STATE_VALID)) {
1121
0
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1122
0
            " from authenticated responder",
1123
0
            __func__);
1124
0
        return (-1);
1125
0
      }
1126
0
    }
1127
0
    msg->msg_parent->msg_flags
1128
0
        |= IKED_MSG_FLAGS_AUTHENTICATION_FAILED;
1129
0
    break;
1130
135
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
135
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
135
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
135
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
4
      log_debug("%s: malformed payload: group size mismatch"
1139
4
          " (%zu != %zu)", __func__, left,
1140
4
          sizeof(msg->msg_parent->msg_group));
1141
4
      return (-1);
1142
4
    }
1143
131
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
131
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
131
    break;
1146
241
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
241
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
241
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
241
    break;
1154
75
  case IKEV2_N_REKEY_SA:
1155
75
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
75
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
70
    rekey = &msg->msg_parent->msg_rekey;
1164
70
    if (rekey->spi != 0) {
1165
5
      log_debug("%s: rekeying of multiple SAs not supported",
1166
5
          __func__);
1167
5
      return (-1);
1168
5
    }
1169
65
    switch (n.n_spisize) {
1170
59
    case 4:
1171
59
      memcpy(&spi32, buf, left);
1172
59
      rekey->spi = betoh32(spi32);
1173
59
      break;
1174
3
    case 8:
1175
3
      memcpy(&spi64, buf, left);
1176
3
      rekey->spi = betoh64(spi64);
1177
3
      break;
1178
3
    default:
1179
3
      log_debug("%s: invalid spi size %d", __func__,
1180
3
          n.n_spisize);
1181
3
      return (-1);
1182
65
    }
1183
62
    rekey->spi_size = n.n_spisize;
1184
62
    rekey->spi_protoid = n.n_protoid;
1185
1186
62
    log_debug("%s: rekey %s spi %s", __func__,
1187
62
        print_map(n.n_protoid, ikev2_saproto_map),
1188
62
        print_spi(rekey->spi, n.n_spisize));
1189
62
    break;
1190
348
  case IKEV2_N_TEMPORARY_FAILURE:
1191
348
    if (!msg->msg_e) {
1192
0
      log_debug("%s: IKEV2_N_TEMPORARY_FAILURE not encrypted",
1193
0
          __func__);
1194
0
      return (-1);
1195
0
    }
1196
348
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
348
    break;
1198
255
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
255
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
255
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
255
        sizeof(msg->msg_parent->msg_transform)) {
1206
127
      log_debug("%s: ignoring malformed ipcomp notification",
1207
127
          __func__);
1208
127
      return (0);
1209
127
    }
1210
128
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
128
        sizeof(msg->msg_parent->msg_cpi));
1212
128
    memcpy(&msg->msg_parent->msg_transform,
1213
128
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
128
        sizeof(msg->msg_parent->msg_transform));
1215
1216
128
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
128
        msg->msg_parent->msg_response ? "res" : "req",
1218
128
        betoh16(msg->msg_parent->msg_cpi),
1219
128
        print_map(msg->msg_parent->msg_transform,
1220
128
        ikev2_ipcomp_map), left);
1221
1222
128
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
128
    break;
1224
73
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
73
    if (!msg->msg_e) {
1226
0
      log_debug("%s: N_CHILD_SA_NOT_FOUND not encrypted",
1227
0
          __func__);
1228
0
      return (-1);
1229
0
    }
1230
73
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
73
    break;
1232
36
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
36
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
36
    break;
1235
267
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
267
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
267
    if (left != 0) {
1242
131
      log_debug("%s: ignoring malformed mobike"
1243
131
          " notification: %zu", __func__, left);
1244
131
      return (0);
1245
131
    }
1246
136
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
136
    break;
1248
316
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
316
    if (!msg->msg_e) {
1250
0
      log_debug("%s: N_USE_TRANSPORT_MODE not encrypted",
1251
0
          __func__);
1252
0
      return (-1);
1253
0
    }
1254
316
    if (left != 0) {
1255
77
      log_debug("%s: ignoring malformed transport mode"
1256
77
          " notification: %zu", __func__, left);
1257
77
      return (0);
1258
77
    }
1259
239
    if (msg->msg_parent->msg_response) {
1260
0
      if (!(msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT)) {
1261
0
        log_debug("%s: ignoring transport mode"
1262
0
            " notification (policy)", __func__);
1263
0
        return (0);
1264
0
      }
1265
0
    }
1266
239
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
239
    break;
1268
388
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
388
    if (!msg->msg_e) {
1270
0
      log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted",
1271
0
          __func__);
1272
0
      return (-1);
1273
0
    }
1274
388
    if (!sa->sa_mobike) {
1275
388
      log_debug("%s: ignoring update sa addresses"
1276
388
          " notification w/o mobike: %zu", __func__, left);
1277
388
      return (0);
1278
388
    }
1279
0
    if (left != 0) {
1280
0
      log_debug("%s: ignoring malformed update sa addresses"
1281
0
          " notification: %zu", __func__, left);
1282
0
      return (0);
1283
0
    }
1284
0
    msg->msg_parent->msg_update_sa_addresses = 1;
1285
0
    break;
1286
202
  case IKEV2_N_COOKIE2:
1287
202
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
202
    if (!sa->sa_mobike) {
1293
202
      log_debug("%s: ignoring cookie2 notification"
1294
202
          " w/o mobike: %zu", __func__, left);
1295
202
      return (0);
1296
202
    }
1297
0
    if (left < IKED_COOKIE2_MIN || left > IKED_COOKIE2_MAX) {
1298
0
      log_debug("%s: ignoring malformed cookie2"
1299
0
          " notification: %zu", __func__, left);
1300
0
      return (0);
1301
0
    }
1302
0
    ibuf_free(msg->msg_cookie2);  /* should not happen */
1303
0
    if ((msg->msg_cookie2 = ibuf_new(buf, left)) == NULL) {
1304
0
      log_debug("%s: failed to get peer cookie2", __func__);
1305
0
      return (-1);
1306
0
    }
1307
0
    msg->msg_parent->msg_cookie2 = msg->msg_cookie2;
1308
0
    break;
1309
2
  case IKEV2_N_COOKIE:
1310
2
    if (msg->msg_e) {
1311
2
      log_debug("%s: N_COOKIE encrypted",
1312
2
          __func__);
1313
2
      return (-1);
1314
2
    }
1315
0
    if (left < IKED_COOKIE_MIN || left > IKED_COOKIE_MAX) {
1316
0
      log_debug("%s: ignoring malformed cookie"
1317
0
          " notification: %zu", __func__, left);
1318
0
      return (0);
1319
0
    }
1320
0
    log_debug("%s: received cookie, len %zu", __func__, left);
1321
0
    print_hex(buf, 0, left);
1322
1323
0
    ibuf_free(msg->msg_cookie);
1324
0
    if ((msg->msg_cookie = ibuf_new(buf, left)) == NULL) {
1325
0
      log_debug("%s: failed to get peer cookie", __func__);
1326
0
      return (-1);
1327
0
    }
1328
0
    msg->msg_parent->msg_cookie = msg->msg_cookie;
1329
0
    break;
1330
14
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
14
    if (msg->msg_e) {
1332
14
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
14
          __func__);
1334
14
      return (-1);
1335
14
    }
1336
0
    if (left != 0) {
1337
0
      log_debug("%s: ignoring malformed fragmentation"
1338
0
          " notification: %zu", __func__, left);
1339
0
      return (0);
1340
0
    }
1341
0
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_FRAGMENTATION;
1342
0
    break;
1343
7
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
7
    if (msg->msg_e) {
1345
7
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
7
          __func__);
1347
7
      return (-1);
1348
7
    }
1349
0
    if (sa == NULL) {
1350
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: no SA",
1351
0
          __func__);
1352
0
      return (-1);
1353
0
    }
1354
0
    if (sa->sa_sigsha2) {
1355
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: "
1356
0
          "duplicate notify", __func__);
1357
0
      return (0);
1358
0
    }
1359
0
    if (left < sizeof(signature_hash) ||
1360
0
        left % sizeof(signature_hash)) {
1361
0
      log_debug("%s: malformed signature hash notification"
1362
0
          "(%zu bytes)", __func__, left);
1363
0
      return (0);
1364
0
    }
1365
0
    while (left >= sizeof(signature_hash)) {
1366
0
      memcpy(&signature_hash, buf, sizeof(signature_hash));
1367
0
      signature_hash = betoh16(signature_hash);
1368
0
      log_debug("%s: signature hash %s (%x)", __func__,
1369
0
          print_map(signature_hash, ikev2_sighash_map),
1370
0
          signature_hash);
1371
0
      left -= sizeof(signature_hash);
1372
0
      buf += sizeof(signature_hash);
1373
0
      if (signature_hash == IKEV2_SIGHASH_SHA2_256)
1374
0
        msg->msg_parent->msg_flags
1375
0
            |= IKED_MSG_FLAGS_SIGSHA2;
1376
0
    }
1377
0
    break;
1378
27.4k
  }
1379
1380
26.4k
  return (0);
1381
27.4k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
7.11k
{
1387
7.11k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
7.11k
  if (left < sizeof(*del)) {
1390
1.39k
    log_debug("%s: malformed payload: too short for header "
1391
1.39k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.39k
    return (-1);
1393
1.39k
  }
1394
5.72k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.72k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.64k
  return (0);
1402
5.72k
}
1403
1404
int
1405
ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
1406
    struct iked_message *msg, size_t offset, size_t left)
1407
7.11k
{
1408
7.11k
  struct ikev2_delete  del;
1409
7.11k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
7.11k
  size_t       cnt, sz, len;
1411
1412
7.11k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.47k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.64k
  if (ikev2_msg_frompeer(msg) &&
1417
5.64k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.64k
  cnt = betoh16(del.del_nspi);
1421
5.64k
  sz = del.del_spisize;
1422
1423
5.64k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.64k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.64k
      sz, cnt);
1426
1427
5.64k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.32k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.32k
    return (0);
1430
5.32k
  }
1431
1432
316
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
316
  msg->msg_parent->msg_del_cnt = cnt;
1434
316
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
316
  buf = msgbuf + offset + sizeof(del);
1437
316
  len = left - sizeof(del);
1438
316
  if (len == 0 || sz == 0 || cnt == 0)
1439
293
    return (0);
1440
1441
23
  if ((len / sz) != cnt) {
1442
21
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
21
        __func__, len, sz, cnt);
1444
21
    return (-1);
1445
21
  }
1446
1447
2
  print_hex(buf, 0, len);
1448
1449
2
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
2
  return (0);
1452
23
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
18.1k
{
1458
18.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
18.1k
  if (left < sizeof(*tsp)) {
1461
2.39k
    log_debug("%s: malformed payload: too short for header "
1462
2.39k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.39k
    return (-1);
1464
2.39k
  }
1465
15.7k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
15.7k
  return (0);
1468
18.1k
}
1469
1470
int
1471
ikev2_pld_tss(struct iked *env, struct ikev2_payload *pld,
1472
    struct iked_message *msg, size_t offset, size_t left)
1473
18.1k
{
1474
18.1k
  struct ikev2_tsp     tsp;
1475
18.1k
  struct ikev2_ts      ts;
1476
18.1k
  size_t         ts_len, i;
1477
1478
18.1k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.39k
    return (-1);
1480
1481
15.7k
  offset += sizeof(tsp);
1482
15.7k
  left -= sizeof(tsp);
1483
1484
15.7k
  log_debug("%s: count %d length %zu", __func__,
1485
15.7k
      tsp.tsp_count, left);
1486
1487
31.1k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
29.5k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
12.4k
      return (-1);
1490
1491
17.1k
    log_debug("%s: type %s protoid %u length %d "
1492
17.1k
        "startport %u endport %u", __func__,
1493
17.1k
        print_map(ts.ts_type, ikev2_ts_map),
1494
17.1k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
17.1k
        betoh16(ts.ts_startport),
1496
17.1k
        betoh16(ts.ts_endport));
1497
1498
17.1k
    offset += sizeof(ts);
1499
17.1k
    left -= sizeof(ts);
1500
1501
17.1k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
17.1k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.69k
      return (-1);
1504
1505
15.4k
    offset += ts_len;
1506
15.4k
    left -= ts_len;
1507
15.4k
  }
1508
1509
1.59k
  return (0);
1510
15.7k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
29.5k
{
1516
29.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
29.5k
  size_t     ts_length;
1518
1519
29.5k
  if (left < sizeof(*ts)) {
1520
11.2k
    log_debug("%s: malformed payload: too short for header "
1521
11.2k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
11.2k
    return (-1);
1523
11.2k
  }
1524
18.3k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
18.3k
  ts_length = betoh16(ts->ts_length);
1527
18.3k
  if (ts_length < sizeof(*ts)) {
1528
315
    log_debug("%s: malformed payload: shorter than minimum header "
1529
315
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
315
    return (-1);
1531
315
  }
1532
18.0k
  if (left < ts_length) {
1533
873
    log_debug("%s: malformed payload: too long for payload size "
1534
873
        "(%zu < %zu)", __func__, left, ts_length);
1535
873
    return (-1);
1536
873
  }
1537
1538
17.1k
  return (0);
1539
18.0k
}
1540
1541
int
1542
ikev2_pld_ts(struct iked *env, struct ikev2_payload *pld,
1543
    struct iked_message *msg, size_t offset, size_t left, unsigned int type)
1544
17.1k
{
1545
17.1k
  struct sockaddr_in     start4, end4;
1546
17.1k
  struct sockaddr_in6    start6, end6;
1547
17.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
17.1k
  uint8_t       *ptr;
1549
1550
17.1k
  ptr = msgbuf + offset;
1551
1552
17.1k
  switch (type) {
1553
6.22k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
6.22k
    if (left < 2 * 4) {
1555
323
      log_debug("%s: malformed payload: too short "
1556
323
          "for ipv4 addr range (%zu < %u)",
1557
323
          __func__, left, 2 * 4);
1558
323
      return (-1);
1559
323
    }
1560
1561
5.90k
    bzero(&start4, sizeof(start4));
1562
5.90k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
5.90k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
5.90k
    ptr += 4;
1568
5.90k
    left -= 4;
1569
1570
5.90k
    bzero(&end4, sizeof(end4));
1571
5.90k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
5.90k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
5.90k
    left -= 4;
1577
1578
5.90k
    log_debug("%s: start %s end %s", __func__,
1579
5.90k
        print_addr(&start4), print_addr(&end4));
1580
5.90k
    break;
1581
1.36k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.36k
    if (left < 2 * 16) {
1583
252
      log_debug("%s: malformed payload: too short "
1584
252
          "for ipv6 addr range (%zu < %u)",
1585
252
          __func__, left, 2 * 16);
1586
252
      return (-1);
1587
252
    }
1588
1.11k
    bzero(&start6, sizeof(start6));
1589
1.11k
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
1.11k
    memcpy(&start6.sin6_addr, ptr, 16);
1594
1.11k
    ptr += 16;
1595
1.11k
    left -= 16;
1596
1597
1.11k
    bzero(&end6, sizeof(end6));
1598
1.11k
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
1.11k
    memcpy(&end6.sin6_addr, ptr, 16);
1603
1.11k
    left -= 16;
1604
1605
1.11k
    log_debug("%s: start %s end %s", __func__,
1606
1.11k
        print_addr(&start6), print_addr(&end6));
1607
1.11k
    break;
1608
9.54k
  default:
1609
9.54k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
9.54k
    return (0);
1611
17.1k
  }
1612
1613
7.01k
  if (left > 0) {
1614
1.12k
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
1.12k
        __func__, left);
1616
1.12k
    return (-1);
1617
1.12k
  }
1618
1619
5.89k
  return (0);
1620
7.01k
}
1621
1622
int
1623
ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
1624
    struct iked_message *msg, size_t offset, size_t left)
1625
0
{
1626
0
  struct iked_sa      *sa = msg->msg_sa;
1627
0
  struct iked_frag    *sa_frag = &sa->sa_fragments;
1628
0
  struct iked_frag_entry    *el;
1629
0
  struct ikev2_frag_payload  frag;
1630
0
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1631
0
  uint8_t       *buf;
1632
0
  struct ibuf     *e = NULL;
1633
0
  size_t         frag_num, frag_total;
1634
0
  size_t         len;
1635
0
  int        ret = -1;
1636
0
  int        processed = 0;
1637
0
  ssize_t        elen;
1638
1639
0
  buf = msgbuf + offset;
1640
0
  memcpy(&frag, buf, sizeof(frag));
1641
0
  frag_num = betoh16(frag.frag_num);
1642
0
  frag_total = betoh16(frag.frag_total);
1643
1644
0
  offset += sizeof(frag);
1645
0
  buf = msgbuf + offset;
1646
0
  len = left - sizeof(frag);
1647
1648
0
  ikestat_inc(env, ikes_frag_rcvd);
1649
1650
  /* Limit number of total fragments to avoid DOS */
1651
0
  if (frag_total > IKED_FRAG_TOTAL_MAX ) {
1652
0
    log_debug("%s: Total Fragments too big  %zu",
1653
0
        __func__, frag_total);
1654
0
    goto dropall;
1655
0
  }
1656
1657
  /* Check sanity of fragment header */
1658
0
  if (frag_num == 0 || frag_total == 0) {
1659
0
    log_debug("%s: Malformed fragment received: %zu of %zu",
1660
0
        __func__, frag_num, frag_total);
1661
0
    goto done;
1662
0
  }
1663
0
  log_debug("%s: Received fragment: %zu of %zu",
1664
0
      __func__, frag_num, frag_total);
1665
1666
  /* Drop fragment if frag_num and frag_total don't match */
1667
0
  if (frag_num > frag_total)
1668
0
    goto done;
1669
1670
  /* Decrypt fragment */
1671
0
  if ((e = ibuf_new(buf, len)) == NULL)
1672
0
    goto done;
1673
1674
0
  if ((e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e))
1675
0
      == NULL ) {
1676
0
    log_debug("%s: Failed to decrypt fragment: %zu of %zu",
1677
0
        __func__, frag_num, frag_total);
1678
0
    goto done;
1679
0
  }
1680
0
  elen = ibuf_size(e);
1681
1682
  /* Check new fragmented message */
1683
0
  if (sa_frag->frag_arr == NULL) {
1684
0
    sa_frag->frag_arr = recallocarray(NULL, 0, frag_total,
1685
0
        sizeof(struct iked_frag_entry*));
1686
0
    if (sa_frag->frag_arr == NULL) {
1687
0
      log_info("%s: recallocarray sa_frag->frag_arr.", __func__);
1688
0
      goto done;
1689
0
    }
1690
0
    sa_frag->frag_total = frag_total;
1691
0
  } else {
1692
    /* Drop all fragments if frag_total doesn't match previous */
1693
0
    if (frag_total != sa_frag->frag_total)
1694
0
      goto dropall;
1695
1696
    /* Silent drop if fragment already stored */
1697
0
    if (sa_frag->frag_arr[frag_num-1] != NULL)
1698
0
      goto done;
1699
0
  }
1700
1701
  /* The first fragments IKE header determines pld_nextpayload */
1702
0
  if (frag_num == 1)
1703
0
    sa_frag->frag_nextpayload = pld->pld_nextpayload;
1704
1705
  /* Insert new list element */
1706
0
  el = calloc(1, sizeof(struct iked_frag_entry));
1707
0
  if (el == NULL) {
1708
0
    log_info("%s: Failed allocating new fragment: %zu of %zu",
1709
0
        __func__, frag_num, frag_total);
1710
0
    goto done;
1711
0
  }
1712
1713
0
  sa_frag->frag_arr[frag_num-1] = el;
1714
0
  el->frag_size = elen;
1715
0
  el->frag_data = calloc(1, elen);
1716
0
  if (el->frag_data == NULL) {
1717
0
    log_debug("%s: Failed allocating new fragment data: %zu of %zu",
1718
0
        __func__, frag_num, frag_total);
1719
0
    goto done;
1720
0
  }
1721
1722
  /* Copy plaintext to fragment */
1723
0
  memcpy(el->frag_data, ibuf_seek(e, 0, 0), elen);
1724
0
  sa_frag->frag_total_size += elen;
1725
0
  sa_frag->frag_count++;
1726
1727
  /* If all frags are received start reassembly */
1728
0
  if (sa_frag->frag_count == sa_frag->frag_total) {
1729
0
    log_debug("%s: All fragments received: %zu of %zu",
1730
0
        __func__, frag_num, frag_total);
1731
0
    ret = ikev2_frags_reassemble(env, pld, msg);
1732
0
  } else {
1733
0
    ret = 0;
1734
0
  }
1735
0
  processed = 1;
1736
1737
0
done:
1738
0
  if (!processed)
1739
0
    ikestat_inc(env, ikes_frag_rcvd_drop);
1740
0
  ibuf_free(e);
1741
0
  return (ret);
1742
0
dropall:
1743
0
  ikestat_add(env, ikes_frag_rcvd_drop, sa_frag->frag_count + 1);
1744
0
  config_free_fragments(sa_frag);
1745
0
  ibuf_free(e);
1746
0
  return -1;
1747
0
}
1748
1749
int
1750
ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
1751
    struct iked_message *msg)
1752
0
{
1753
0
  struct iked_frag    *sa_frag = &msg->msg_sa->sa_fragments;
1754
0
  struct ibuf     *e = NULL;
1755
0
  struct iked_frag_entry    *el;
1756
0
  uint8_t       *ptr;
1757
0
  size_t         offset;
1758
0
  size_t         i;
1759
0
  struct iked_message    emsg;
1760
0
  int        ret = -1;
1761
0
  int        processed = 0;
1762
1763
  /* Reassemble fragments to single buffer */
1764
0
  if ((e = ibuf_new(NULL, sa_frag->frag_total_size)) == NULL) {
1765
0
    log_debug("%s: Failed allocating SK buffer.", __func__);
1766
0
    goto done;
1767
0
  }
1768
1769
  /* Empty queue to new buffer */
1770
0
  offset = 0;
1771
0
  for (i = 0; i < sa_frag->frag_total; i++) {
1772
0
    if ((el = sa_frag->frag_arr[i]) == NULL)
1773
0
      fatalx("Tried to reassemble shallow frag_arr");
1774
0
    ptr = ibuf_seek(e, offset, el->frag_size);
1775
0
    if (ptr == NULL) {
1776
0
      log_info("%s: failed to reassemble fragments", __func__);
1777
0
      goto done;
1778
0
    }
1779
0
    memcpy(ptr, el->frag_data, el->frag_size);
1780
0
    offset += el->frag_size;
1781
0
  }
1782
1783
0
  log_debug("%s: Defragmented length %zd", __func__,
1784
0
      sa_frag->frag_total_size);
1785
0
  print_hex(ibuf_data(e), 0,  sa_frag->frag_total_size);
1786
1787
  /* Drop the original request's packets from the retransmit queue */
1788
0
  if (msg->msg_response)
1789
0
    ikev2_msg_dispose(env, &msg->msg_sa->sa_requests,
1790
0
        ikev2_msg_lookup(env, &msg->msg_sa->sa_requests, msg,
1791
0
        msg->msg_exchange));
1792
1793
  /*
1794
   * Parse decrypted payload
1795
   */
1796
0
  bzero(&emsg, sizeof(emsg));
1797
0
  memcpy(&emsg, msg, sizeof(*msg));
1798
0
  emsg.msg_data = e;
1799
0
  emsg.msg_e = 1;
1800
0
  emsg.msg_parent = msg;
1801
0
  TAILQ_INIT(&emsg.msg_proposals);
1802
1803
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1804
0
      sa_frag->frag_nextpayload);
1805
0
  processed = 1;
1806
0
done:
1807
0
  if (processed)
1808
0
    ikestat_add(env, ikes_frag_reass_ok, sa_frag->frag_total);
1809
0
  else
1810
0
    ikestat_add(env, ikes_frag_reass_drop, sa_frag->frag_total);
1811
0
  config_free_fragments(sa_frag);
1812
0
  ibuf_free(e);
1813
1814
0
  return (ret);
1815
0
}
1816
1817
int
1818
ikev2_pld_e(struct iked *env, struct ikev2_payload *pld,
1819
    struct iked_message *msg, size_t offset, size_t left)
1820
0
{
1821
0
  struct iked_sa    *sa = msg->msg_sa;
1822
0
  struct ibuf   *e = NULL;
1823
0
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1824
0
  struct iked_message  emsg;
1825
0
  uint8_t     *buf;
1826
0
  size_t       len;
1827
0
  int      ret = -1;
1828
1829
0
  if (sa->sa_fragments.frag_arr != NULL) {
1830
0
    log_warn("%s: Received SK payload when SKFs are in queue.",
1831
0
        __func__);
1832
0
    config_free_fragments(&sa->sa_fragments);
1833
0
    return (ret);
1834
0
  }
1835
1836
0
  buf = msgbuf + offset;
1837
0
  len = left;
1838
1839
0
  if ((e = ibuf_new(buf, len)) == NULL)
1840
0
    goto done;
1841
1842
0
  if (ikev2_msg_frompeer(msg)) {
1843
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1844
0
  } else {
1845
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1846
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1847
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1848
0
  }
1849
1850
0
  if (e == NULL)
1851
0
    goto done;
1852
1853
  /*
1854
   * Parse decrypted payload
1855
   */
1856
0
  bzero(&emsg, sizeof(emsg));
1857
0
  memcpy(&emsg, msg, sizeof(*msg));
1858
0
  emsg.msg_data = e;
1859
0
  emsg.msg_e = 1;
1860
0
  emsg.msg_parent = msg;
1861
0
  TAILQ_INIT(&emsg.msg_proposals);
1862
1863
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1864
0
      pld->pld_nextpayload);
1865
1866
0
 done:
1867
0
  ibuf_free(e);
1868
1869
0
  return (ret);
1870
0
}
1871
1872
int
1873
ikev2_validate_cp(struct iked_message *msg, size_t offset, size_t left,
1874
    struct ikev2_cp *cp)
1875
9.77k
{
1876
9.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
9.77k
  if (left < sizeof(*cp)) {
1879
3.14k
    log_debug("%s: malformed payload: too short for header "
1880
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
3.14k
    return (-1);
1882
3.14k
  }
1883
6.63k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
6.63k
  return (0);
1886
9.77k
}
1887
1888
int
1889
ikev2_pld_cp(struct iked *env, struct ikev2_payload *pld,
1890
    struct iked_message *msg, size_t offset, size_t left)
1891
9.77k
{
1892
9.77k
  struct ikev2_cp    cp;
1893
9.77k
  struct ikev2_cfg  *cfg;
1894
9.77k
  struct iked_addr  *addr;
1895
9.77k
  struct sockaddr_in  *in4;
1896
9.77k
  struct sockaddr_in6 *in6;
1897
9.77k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
9.77k
  uint8_t     *ptr;
1899
9.77k
  size_t       len;
1900
9.77k
  int      cfg_type;
1901
1902
9.77k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
3.14k
    return (-1);
1904
1905
6.63k
  ptr = msgbuf + offset + sizeof(cp);
1906
6.63k
  len = left - sizeof(cp);
1907
1908
6.63k
  log_debug("%s: type %s length %zu",
1909
6.63k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
6.63k
  print_hex(ptr, 0, len);
1911
1912
14.4k
  while (len > 0) {
1913
9.33k
    if (len < sizeof(*cfg)) {
1914
352
      log_debug("%s: malformed payload: too short for cfg "
1915
352
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
352
      return (-1);
1917
352
    }
1918
8.98k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.98k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.98k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.98k
        betoh16(cfg->cfg_type),
1923
8.98k
        betoh16(cfg->cfg_length));
1924
1925
8.98k
    ptr += sizeof(*cfg);
1926
8.98k
    len -= sizeof(*cfg);
1927
1928
8.98k
    if (len < betoh16(cfg->cfg_length)) {
1929
1.12k
      log_debug("%s: malformed payload: too short for "
1930
1.12k
          "cfg_length (%zu < %u)", __func__, len,
1931
1.12k
          betoh16(cfg->cfg_length));
1932
1.12k
      return (-1);
1933
1.12k
    }
1934
1935
7.86k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.86k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.86k
    switch (cfg_type) {
1939
844
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.50k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.50k
      if (!ikev2_msg_frompeer(msg))
1942
735
        break;
1943
769
      if (betoh16(cfg->cfg_length) == 0)
1944
309
        break;
1945
      /* XXX multiple-valued */
1946
460
      if (betoh16(cfg->cfg_length) < 4) {
1947
6
        log_debug("%s: malformed payload: too short "
1948
6
            "for ipv4 addr (%u < %u)",
1949
6
            __func__, betoh16(cfg->cfg_length), 4);
1950
6
        return (-1);
1951
6
      }
1952
454
      switch(cfg_type) {
1953
355
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
355
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
238
          log_debug("%s: address already set", __func__);
1956
238
          goto skip;
1957
238
        }
1958
117
        break;
1959
117
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
99
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
51
          log_debug("%s: dns already set", __func__);
1962
51
          goto skip;
1963
51
        }
1964
48
        break;
1965
48
      default:
1966
0
        break;
1967
454
      }
1968
165
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
165
      addr->addr_af = AF_INET;
1973
165
      in4 = (struct sockaddr_in *)&addr->addr;
1974
165
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
165
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
165
      switch(cfg_type) {
1980
117
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
117
        msg->msg_parent->msg_cp_addr = addr;
1982
117
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
117
            print_addr(&addr->addr));
1984
117
        break;
1985
48
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
48
        msg->msg_parent->msg_cp_dns = addr;
1987
48
        log_debug("%s: IP4_DNS %s", __func__,
1988
48
            print_addr(&addr->addr));
1989
48
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
165
      }
1995
165
      break;
1996
2.25k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
3.06k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
3.06k
      if (!ikev2_msg_frompeer(msg))
1999
2.86k
        break;
2000
199
      if (betoh16(cfg->cfg_length) == 0)
2001
67
        break;
2002
      /* XXX multiple-valued */
2003
132
      if (betoh16(cfg->cfg_length) < 16) {
2004
5
        log_debug("%s: malformed payload: too short "
2005
5
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
5
            __func__, betoh16(cfg->cfg_length), 16);
2007
5
        return (-1);
2008
5
      }
2009
127
      switch(cfg_type) {
2010
87
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
87
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
40
        break;
2016
40
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
40
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
36
          log_debug("%s: dns already set", __func__);
2019
36
          goto skip;
2020
36
        }
2021
4
        break;
2022
127
      }
2023
44
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
44
      addr->addr_af = AF_INET6;
2028
44
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
44
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
44
      memcpy(&in6->sin6_addr, ptr, 16);
2034
44
      switch(cfg_type) {
2035
40
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
40
        msg->msg_parent->msg_cp_addr6 = addr;
2037
40
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
40
            print_addr(&addr->addr));
2039
40
        break;
2040
4
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
4
        msg->msg_parent->msg_cp_dns = addr;
2042
4
        log_debug("%s: IP6_DNS %s", __func__,
2043
4
            print_addr(&addr->addr));
2044
4
        break;
2045
0
      default:
2046
0
        log_debug("%s: cfg %s/%d", __func__,
2047
0
            print_addr(&addr->addr), ptr[16]);
2048
0
        break;
2049
44
      }
2050
44
      break;
2051
7.86k
    }
2052
2053
7.84k
 skip:
2054
7.84k
    ptr += betoh16(cfg->cfg_length);
2055
7.84k
    len -= betoh16(cfg->cfg_length);
2056
7.84k
  }
2057
2058
5.15k
  if (!ikev2_msg_frompeer(msg))
2059
4.95k
    return (0);
2060
2061
192
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
192
  return (0);
2064
5.15k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
17.1k
{
2070
17.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
17.1k
  if (left < sizeof(*hdr)) {
2073
7.15k
    log_debug("%s: malformed payload: too short for header "
2074
7.15k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
7.15k
    return (-1);
2076
7.15k
  }
2077
9.94k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.94k
  return (0);
2080
17.1k
}
2081
2082
int
2083
ikev2_pld_eap(struct iked *env, struct ikev2_payload *pld,
2084
    struct iked_message *msg, size_t offset, size_t left)
2085
17.1k
{
2086
17.1k
  struct eap_header    hdr;
2087
17.1k
  struct eap_message    *eap = NULL;
2088
17.1k
  const struct iked_sa    *sa = msg->msg_sa;
2089
17.1k
  size_t         len;
2090
2091
17.1k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
7.15k
    return (-1);
2093
9.94k
  len = betoh16(hdr.eap_length);
2094
2095
9.94k
  if (len < sizeof(*eap)) {
2096
3.45k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.45k
        print_map(hdr.eap_code, eap_code_map),
2098
3.45k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
6.48k
  } else {
2100
    /* Now try to get the indicated length */
2101
6.48k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
3.28k
      log_debug("%s: invalid EAP length", __func__);
2103
3.28k
      return (-1);
2104
3.28k
    }
2105
2106
3.20k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.20k
        print_map(eap->eap_code, eap_code_map),
2108
3.20k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.20k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.20k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.20k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.20k
  }
2115
2116
6.66k
  return (0);
2117
9.94k
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/imsg_util.c.html b/coverage/latest/report/linux/src/openiked-portable/iked/imsg_util.c.html index a6da5db72..bf125d947 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/imsg_util.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/imsg_util.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/imsg_util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg_util.c,v 1.21 2023/07/18 15:07:41 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <netdb.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <fcntl.h>
30
#include <ctype.h>
31
#include <event.h>
32
33
#include "iked.h"
34
35
/*
36
 * Extending the imsg buffer API for internal use
37
 */
38
39
struct ibuf *
40
ibuf_new(const void *data, size_t len)
41
20.3k
{
42
20.3k
  struct ibuf *buf;
43
44
20.3k
  if ((buf = ibuf_dynamic(len,
45
20.3k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
20.3k
  if (len == 0)
49
1.41k
    return (buf);
50
51
18.9k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
18.9k
  } else {
57
18.9k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
18.9k
  }
62
63
18.9k
  return (buf);
64
18.9k
}
65
66
struct ibuf *
67
ibuf_static(void)
68
0
{
69
0
  return ibuf_open(IKED_MSGBUF_MAX);
70
0
}
71
72
size_t
73
ibuf_length(struct ibuf *buf)
74
0
{
75
0
  if (buf == NULL)
76
0
    return (0);
77
0
  return (ibuf_size(buf));
78
0
}
79
80
struct ibuf *
81
ibuf_getdata(struct ibuf *buf, size_t len)
82
0
{
83
0
  void  *data;
84
85
0
  if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
86
0
    return (NULL);
87
0
  buf->rpos += len;
88
89
0
  return (ibuf_new(data, len));
90
0
}
91
92
struct ibuf *
93
ibuf_dup(struct ibuf *buf)
94
0
{
95
0
  if (buf == NULL)
96
0
    return (NULL);
97
0
  return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
98
0
}
99
100
struct ibuf *
101
ibuf_random(size_t len)
102
0
{
103
0
  struct ibuf *buf;
104
0
  void    *ptr;
105
106
0
  if ((buf = ibuf_open(len)) == NULL)
107
0
    return (NULL);
108
0
  if ((ptr = ibuf_reserve(buf, len)) == NULL) {
109
0
    ibuf_free(buf);
110
0
    return (NULL);
111
0
  }
112
0
  arc4random_buf(ptr, len);
113
0
  return (buf);
114
0
}
115
116
int
117
ibuf_setsize(struct ibuf *buf, size_t len)
118
0
{
119
0
  if (len > buf->size)
120
0
    return (-1);
121
0
  buf->wpos = len;
122
0
  return (0);
123
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/imsg_util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg_util.c,v 1.21 2023/07/18 15:07:41 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <netdb.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <fcntl.h>
30
#include <ctype.h>
31
#include <event.h>
32
33
#include "iked.h"
34
35
/*
36
 * Extending the imsg buffer API for internal use
37
 */
38
39
struct ibuf *
40
ibuf_new(const void *data, size_t len)
41
20.4k
{
42
20.4k
  struct ibuf *buf;
43
44
20.4k
  if ((buf = ibuf_dynamic(len,
45
20.4k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
20.4k
  if (len == 0)
49
1.41k
    return (buf);
50
51
19.0k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
19.0k
  } else {
57
19.0k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
19.0k
  }
62
63
19.0k
  return (buf);
64
19.0k
}
65
66
struct ibuf *
67
ibuf_static(void)
68
0
{
69
0
  return ibuf_open(IKED_MSGBUF_MAX);
70
0
}
71
72
size_t
73
ibuf_length(struct ibuf *buf)
74
0
{
75
0
  if (buf == NULL)
76
0
    return (0);
77
0
  return (ibuf_size(buf));
78
0
}
79
80
struct ibuf *
81
ibuf_getdata(struct ibuf *buf, size_t len)
82
0
{
83
0
  void  *data;
84
85
0
  if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
86
0
    return (NULL);
87
0
  buf->rpos += len;
88
89
0
  return (ibuf_new(data, len));
90
0
}
91
92
struct ibuf *
93
ibuf_dup(struct ibuf *buf)
94
0
{
95
0
  if (buf == NULL)
96
0
    return (NULL);
97
0
  return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
98
0
}
99
100
struct ibuf *
101
ibuf_random(size_t len)
102
0
{
103
0
  struct ibuf *buf;
104
0
  void    *ptr;
105
106
0
  if ((buf = ibuf_open(len)) == NULL)
107
0
    return (NULL);
108
0
  if ((ptr = ibuf_reserve(buf, len)) == NULL) {
109
0
    ibuf_free(buf);
110
0
    return (NULL);
111
0
  }
112
0
  arc4random_buf(ptr, len);
113
0
  return (buf);
114
0
}
115
116
int
117
ibuf_setsize(struct ibuf *buf, size_t len)
118
0
{
119
0
  if (len > buf->size)
120
0
    return (-1);
121
0
  buf->wpos = len;
122
0
  return (0);
123
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/log.c.html b/coverage/latest/report/linux/src/openiked-portable/iked/log.c.html index aa7c47bf4..8ef8b23a0 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/log.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/log.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/log.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: log.c,v 1.12 2017/03/21 12:06:55 bluhm Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <stdarg.h>
22
#include <string.h>
23
#include <syslog.h>
24
#include <errno.h>
25
#include <time.h>
26
27
static int   debug;
28
static int   verbose;
29
const char  *log_procname;
30
31
void  log_init(int, int);
32
void  log_procinit(const char *);
33
void  log_setverbose(int);
34
int log_getverbose(void);
35
void  log_warn(const char *, ...)
36
      __attribute__((__format__ (printf, 1, 2)));
37
void  log_warnx(const char *, ...)
38
      __attribute__((__format__ (printf, 1, 2)));
39
void  log_info(const char *, ...)
40
      __attribute__((__format__ (printf, 1, 2)));
41
void  log_debug(const char *, ...)
42
      __attribute__((__format__ (printf, 1, 2)));
43
void  logit(int, const char *, ...)
44
      __attribute__((__format__ (printf, 2, 3)));
45
void  vlog(int, const char *, va_list)
46
      __attribute__((__format__ (printf, 2, 0)));
47
__dead void fatal(const char *, ...)
48
      __attribute__((__format__ (printf, 1, 2)));
49
__dead void fatalx(const char *, ...)
50
      __attribute__((__format__ (printf, 1, 2)));
51
52
void
53
log_init(int n_debug, int facility)
54
0
{
55
0
  extern char *__progname;
56
57
0
  debug = n_debug;
58
0
  verbose = n_debug;
59
0
  log_procinit(__progname);
60
61
0
  if (!debug)
62
0
    openlog(__progname, LOG_PID | LOG_NDELAY, facility);
63
64
0
  tzset();
65
0
}
66
67
void
68
log_procinit(const char *procname)
69
0
{
70
0
  if (procname != NULL)
71
0
    log_procname = procname;
72
0
}
73
74
void
75
log_setverbose(int v)
76
0
{
77
0
  verbose = v;
78
0
}
79
80
int
81
log_getverbose(void)
82
147k
{
83
147k
  return (verbose);
84
147k
}
85
86
void
87
logit(int pri, const char *fmt, ...)
88
0
{
89
0
  va_list ap;
90
91
0
  va_start(ap, fmt);
92
0
  vlog(pri, fmt, ap);
93
0
  va_end(ap);
94
0
}
95
96
void
97
vlog(int pri, const char *fmt, va_list ap)
98
10.4k
{
99
10.4k
  char  *nfmt;
100
10.4k
  int  saved_errno = errno;
101
102
10.4k
  if (debug) {
103
    /* best effort in out of mem situations */
104
0
    if (asprintf(&nfmt, "%s\n", fmt) == -1) {
105
0
      vfprintf(stderr, fmt, ap);
106
0
      fprintf(stderr, "\n");
107
0
    } else {
108
0
      vfprintf(stderr, nfmt, ap);
109
0
      free(nfmt);
110
0
    }
111
0
    fflush(stderr);
112
0
  } else
113
10.4k
    vsyslog(pri, fmt, ap);
114
115
10.4k
  errno = saved_errno;
116
10.4k
}
117
118
void
119
log_warn(const char *emsg, ...)
120
0
{
121
0
  char    *nfmt;
122
0
  va_list    ap;
123
0
  int    saved_errno = errno;
124
125
  /* best effort to even work in out of memory situations */
126
0
  if (emsg == NULL)
127
0
    logit(LOG_ERR, "%s", strerror(saved_errno));
128
0
  else {
129
0
    va_start(ap, emsg);
130
131
0
    if (asprintf(&nfmt, "%s: %s", emsg,
132
0
        strerror(saved_errno)) == -1) {
133
      /* we tried it... */
134
0
      vlog(LOG_ERR, emsg, ap);
135
0
      logit(LOG_ERR, "%s", strerror(saved_errno));
136
0
    } else {
137
0
      vlog(LOG_ERR, nfmt, ap);
138
0
      free(nfmt);
139
0
    }
140
0
    va_end(ap);
141
0
  }
142
143
0
  errno = saved_errno;
144
0
}
145
146
void
147
log_warnx(const char *emsg, ...)
148
0
{
149
0
  va_list  ap;
150
151
0
  va_start(ap, emsg);
152
0
  vlog(LOG_ERR, emsg, ap);
153
0
  va_end(ap);
154
0
}
155
156
void
157
log_info(const char *emsg, ...)
158
10.4k
{
159
10.4k
  va_list  ap;
160
161
10.4k
  va_start(ap, emsg);
162
10.4k
  vlog(LOG_INFO, emsg, ap);
163
10.4k
  va_end(ap);
164
10.4k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
540k
{
169
540k
  va_list  ap;
170
171
540k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
540k
}
177
178
static void
179
vfatalc(int code, const char *emsg, va_list ap)
180
0
{
181
0
  static char s[BUFSIZ];
182
0
  const char  *sep;
183
184
0
  if (emsg != NULL) {
185
0
    (void)vsnprintf(s, sizeof(s), emsg, ap);
186
0
    sep = ": ";
187
0
  } else {
188
0
    s[0] = '\0';
189
0
    sep = "";
190
0
  }
191
0
  if (code)
192
0
    logit(LOG_CRIT, "%s: %s%s%s",
193
0
        log_procname, s, sep, strerror(code));
194
0
  else
195
0
    logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196
0
}
197
198
void
199
fatal(const char *emsg, ...)
200
0
{
201
0
  va_list ap;
202
203
0
  va_start(ap, emsg);
204
0
  vfatalc(errno, emsg, ap);
205
0
  va_end(ap);
206
0
  exit(1);
207
0
}
208
209
void
210
fatalx(const char *emsg, ...)
211
0
{
212
0
  va_list ap;
213
214
0
  va_start(ap, emsg);
215
0
  vfatalc(0, emsg, ap);
216
0
  va_end(ap);
217
0
  exit(1);
218
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/log.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: log.c,v 1.12 2017/03/21 12:06:55 bluhm Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <stdarg.h>
22
#include <string.h>
23
#include <syslog.h>
24
#include <errno.h>
25
#include <time.h>
26
27
static int   debug;
28
static int   verbose;
29
const char  *log_procname;
30
31
void  log_init(int, int);
32
void  log_procinit(const char *);
33
void  log_setverbose(int);
34
int log_getverbose(void);
35
void  log_warn(const char *, ...)
36
      __attribute__((__format__ (printf, 1, 2)));
37
void  log_warnx(const char *, ...)
38
      __attribute__((__format__ (printf, 1, 2)));
39
void  log_info(const char *, ...)
40
      __attribute__((__format__ (printf, 1, 2)));
41
void  log_debug(const char *, ...)
42
      __attribute__((__format__ (printf, 1, 2)));
43
void  logit(int, const char *, ...)
44
      __attribute__((__format__ (printf, 2, 3)));
45
void  vlog(int, const char *, va_list)
46
      __attribute__((__format__ (printf, 2, 0)));
47
__dead void fatal(const char *, ...)
48
      __attribute__((__format__ (printf, 1, 2)));
49
__dead void fatalx(const char *, ...)
50
      __attribute__((__format__ (printf, 1, 2)));
51
52
void
53
log_init(int n_debug, int facility)
54
0
{
55
0
  extern char *__progname;
56
57
0
  debug = n_debug;
58
0
  verbose = n_debug;
59
0
  log_procinit(__progname);
60
61
0
  if (!debug)
62
0
    openlog(__progname, LOG_PID | LOG_NDELAY, facility);
63
64
0
  tzset();
65
0
}
66
67
void
68
log_procinit(const char *procname)
69
0
{
70
0
  if (procname != NULL)
71
0
    log_procname = procname;
72
0
}
73
74
void
75
log_setverbose(int v)
76
0
{
77
0
  verbose = v;
78
0
}
79
80
int
81
log_getverbose(void)
82
148k
{
83
148k
  return (verbose);
84
148k
}
85
86
void
87
logit(int pri, const char *fmt, ...)
88
0
{
89
0
  va_list ap;
90
91
0
  va_start(ap, fmt);
92
0
  vlog(pri, fmt, ap);
93
0
  va_end(ap);
94
0
}
95
96
void
97
vlog(int pri, const char *fmt, va_list ap)
98
10.4k
{
99
10.4k
  char  *nfmt;
100
10.4k
  int  saved_errno = errno;
101
102
10.4k
  if (debug) {
103
    /* best effort in out of mem situations */
104
0
    if (asprintf(&nfmt, "%s\n", fmt) == -1) {
105
0
      vfprintf(stderr, fmt, ap);
106
0
      fprintf(stderr, "\n");
107
0
    } else {
108
0
      vfprintf(stderr, nfmt, ap);
109
0
      free(nfmt);
110
0
    }
111
0
    fflush(stderr);
112
0
  } else
113
10.4k
    vsyslog(pri, fmt, ap);
114
115
10.4k
  errno = saved_errno;
116
10.4k
}
117
118
void
119
log_warn(const char *emsg, ...)
120
0
{
121
0
  char    *nfmt;
122
0
  va_list    ap;
123
0
  int    saved_errno = errno;
124
125
  /* best effort to even work in out of memory situations */
126
0
  if (emsg == NULL)
127
0
    logit(LOG_ERR, "%s", strerror(saved_errno));
128
0
  else {
129
0
    va_start(ap, emsg);
130
131
0
    if (asprintf(&nfmt, "%s: %s", emsg,
132
0
        strerror(saved_errno)) == -1) {
133
      /* we tried it... */
134
0
      vlog(LOG_ERR, emsg, ap);
135
0
      logit(LOG_ERR, "%s", strerror(saved_errno));
136
0
    } else {
137
0
      vlog(LOG_ERR, nfmt, ap);
138
0
      free(nfmt);
139
0
    }
140
0
    va_end(ap);
141
0
  }
142
143
0
  errno = saved_errno;
144
0
}
145
146
void
147
log_warnx(const char *emsg, ...)
148
0
{
149
0
  va_list  ap;
150
151
0
  va_start(ap, emsg);
152
0
  vlog(LOG_ERR, emsg, ap);
153
0
  va_end(ap);
154
0
}
155
156
void
157
log_info(const char *emsg, ...)
158
10.4k
{
159
10.4k
  va_list  ap;
160
161
10.4k
  va_start(ap, emsg);
162
10.4k
  vlog(LOG_INFO, emsg, ap);
163
10.4k
  va_end(ap);
164
10.4k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
543k
{
169
543k
  va_list  ap;
170
171
543k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
543k
}
177
178
static void
179
vfatalc(int code, const char *emsg, va_list ap)
180
0
{
181
0
  static char s[BUFSIZ];
182
0
  const char  *sep;
183
184
0
  if (emsg != NULL) {
185
0
    (void)vsnprintf(s, sizeof(s), emsg, ap);
186
0
    sep = ": ";
187
0
  } else {
188
0
    s[0] = '\0';
189
0
    sep = "";
190
0
  }
191
0
  if (code)
192
0
    logit(LOG_CRIT, "%s: %s%s%s",
193
0
        log_procname, s, sep, strerror(code));
194
0
  else
195
0
    logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196
0
}
197
198
void
199
fatal(const char *emsg, ...)
200
0
{
201
0
  va_list ap;
202
203
0
  va_start(ap, emsg);
204
0
  vfatalc(errno, emsg, ap);
205
0
  va_end(ap);
206
0
  exit(1);
207
0
}
208
209
void
210
fatalx(const char *emsg, ...)
211
0
{
212
0
  va_list ap;
213
214
0
  va_start(ap, emsg);
215
0
  vfatalc(0, emsg, ap);
216
0
  va_end(ap);
217
0
  exit(1);
218
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/types.h.html b/coverage/latest/report/linux/src/openiked-portable/iked/types.h.html index 0ec7812fb..989374846 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/types.h.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/types.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/types.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: types.h,v 1.52 2023/03/04 22:22:51 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_TYPES_H
21
#define IKED_TYPES_H
22
23
#ifndef IKED_USER
24
#define IKED_USER   "_iked"
25
#endif
26
27
#ifndef IKED_CONFIG
28
#define IKED_CONFIG   "/etc/iked.conf"
29
#endif
30
31
#define IKED_SOCKET   "/var/run/iked.sock"
32
33
#ifndef IKED_CA
34
#define IKED_CA     "/etc/iked/"
35
#endif
36
37
#define IKED_CA_DIR   "ca/"
38
#define IKED_CRL_DIR    "crls/"
39
#define IKED_CERT_DIR   "certs/"
40
#define IKED_PUBKEY_DIR   "pubkeys/"
41
#define IKED_PRIVKEY    IKED_CA "private/local.key"
42
#define IKED_PUBKEY   "local.pub"
43
44
#define IKED_VENDOR_ID    "OpenIKED-"
45
46
#define IKED_OCSP_RESPCERT  "ocsp/responder.crt"
47
48
#define IKED_OPT_VERBOSE  0x00000001
49
#define IKED_OPT_NOACTION 0x00000002
50
#define IKED_OPT_PASSIVE  0x00000004
51
52
#define IKED_IKE_PORT   500
53
#define IKED_NATT_PORT    4500
54
55
#define IKED_NONCE_MIN    16  /* XXX 128 bits */
56
#define IKED_NONCE_SIZE   32  /* XXX 256 bits */
57
58
0
#define IKED_COOKIE_MIN   1  /* min 1 bytes */
59
0
#define IKED_COOKIE_MAX   64  /* max 64 bytes */
60
61
0
#define IKED_COOKIE2_MIN  8  /* min 8 bytes */
62
0
#define IKED_COOKIE2_MAX  64  /* max 64 bytes */
63
64
#define IKED_ID_SIZE    1024  /* XXX should be dynamic */
65
#define IKED_PSK_SIZE   1024  /* XXX should be dynamic */
66
20.3k
#define IKED_MSGBUF_MAX   8192
67
#define IKED_CFG_MAX    16  /* maximum CP attributes */
68
#define IKED_IPPROTO_MAX  16
69
#define IKED_TAG_SIZE   64
70
718k
#define IKED_CYCLE_BUFFERS  8  /* # of static buffers for mapping */
71
#define IKED_PASSWORD_SIZE  256 /* limited by most EAP types */
72
73
#define IKED_LIFETIME_BYTES 4294967296ULL /* 4 GB */
74
#define IKED_LIFETIME_SECONDS 10800     /* 3 hours */
75
76
196k
#define IKED_E      0x1000  /* Decrypted flag */
77
78
struct iked_constmap {
79
  unsigned int   cm_type;
80
  const char  *cm_name;
81
  const char  *cm_descr;
82
};
83
84
struct iked_transform {
85
  uint8_t        xform_type;
86
  uint16_t       xform_id;
87
  uint16_t       xform_length;
88
  uint16_t       xform_keylength;
89
  unsigned int       xform_score;
90
  struct iked_constmap    *xform_map;
91
};
92
93
enum imsg_type {
94
  IMSG_NONE,
95
  IMSG_CTL_OK,
96
  IMSG_CTL_FAIL,
97
  IMSG_CTL_VERBOSE,
98
  IMSG_CTL_NOTIFY,
99
  IMSG_CTL_RELOAD,
100
  IMSG_CTL_RESET,
101
  IMSG_CTL_COUPLE,
102
  IMSG_CTL_DECOUPLE,
103
  IMSG_CTL_ACTIVE,
104
  IMSG_CTL_PASSIVE,
105
  IMSG_CTL_RESET_ID,
106
  IMSG_CTL_SHOW_SA,
107
  IMSG_CTL_STATIC,
108
  IMSG_COMPILE,
109
  IMSG_UDP_SOCKET,
110
  IMSG_PFKEY_SOCKET,
111
  IMSG_IKE_MESSAGE,
112
  IMSG_CFG_POLICY,
113
  IMSG_CFG_FLOW,
114
  IMSG_CFG_USER,
115
  IMSG_CERTREQ,
116
  IMSG_CERT,
117
  IMSG_CERTVALID,
118
  IMSG_CERTINVALID,
119
  IMSG_CERT_PARTIAL_CHAIN,
120
  IMSG_SCERT,
121
  IMSG_IF_ADDADDR,
122
  IMSG_IF_DELADDR,
123
  IMSG_VROUTE_ADD,
124
  IMSG_VROUTE_DEL,
125
  IMSG_VROUTE_CLONE,
126
  IMSG_VDNS_ADD,
127
  IMSG_VDNS_DEL,
128
  IMSG_OCSP_FD,
129
  IMSG_OCSP_CFG,
130
  IMSG_AUTH,
131
  IMSG_PRIVKEY,
132
  IMSG_PUBKEY,
133
  IMSG_CTL_SHOW_CERTSTORE,
134
  IMSG_CTL_SHOW_STATS,
135
  IMSG_CTL_PROCFD,
136
};
137
138
enum privsep_procid {
139
  PROC_PARENT = 0,
140
  PROC_CONTROL,
141
  PROC_CERT,
142
  PROC_IKEV2,
143
  PROC_MAX
144
};
145
146
enum flushmode {
147
  RESET_RELOAD  = 0,
148
  RESET_ALL,
149
  RESET_CA,
150
  RESET_POLICY,
151
  RESET_SA,
152
  RESET_USER,
153
};
154
155
#ifndef nitems
156
#define nitems(_a)   (sizeof((_a)) / sizeof((_a)[0]))
157
#endif
158
159
#endif /* IKED_TYPES_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/types.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: types.h,v 1.52 2023/03/04 22:22:51 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_TYPES_H
21
#define IKED_TYPES_H
22
23
#ifndef IKED_USER
24
#define IKED_USER   "_iked"
25
#endif
26
27
#ifndef IKED_CONFIG
28
#define IKED_CONFIG   "/etc/iked.conf"
29
#endif
30
31
#define IKED_SOCKET   "/var/run/iked.sock"
32
33
#ifndef IKED_CA
34
#define IKED_CA     "/etc/iked/"
35
#endif
36
37
#define IKED_CA_DIR   "ca/"
38
#define IKED_CRL_DIR    "crls/"
39
#define IKED_CERT_DIR   "certs/"
40
#define IKED_PUBKEY_DIR   "pubkeys/"
41
#define IKED_PRIVKEY    IKED_CA "private/local.key"
42
#define IKED_PUBKEY   "local.pub"
43
44
#define IKED_VENDOR_ID    "OpenIKED-"
45
46
#define IKED_OCSP_RESPCERT  "ocsp/responder.crt"
47
48
#define IKED_OPT_VERBOSE  0x00000001
49
#define IKED_OPT_NOACTION 0x00000002
50
#define IKED_OPT_PASSIVE  0x00000004
51
52
#define IKED_IKE_PORT   500
53
#define IKED_NATT_PORT    4500
54
55
#define IKED_NONCE_MIN    16  /* XXX 128 bits */
56
#define IKED_NONCE_SIZE   32  /* XXX 256 bits */
57
58
0
#define IKED_COOKIE_MIN   1  /* min 1 bytes */
59
0
#define IKED_COOKIE_MAX   64  /* max 64 bytes */
60
61
0
#define IKED_COOKIE2_MIN  8  /* min 8 bytes */
62
0
#define IKED_COOKIE2_MAX  64  /* max 64 bytes */
63
64
#define IKED_ID_SIZE    1024  /* XXX should be dynamic */
65
#define IKED_PSK_SIZE   1024  /* XXX should be dynamic */
66
20.4k
#define IKED_MSGBUF_MAX   8192
67
#define IKED_CFG_MAX    16  /* maximum CP attributes */
68
#define IKED_IPPROTO_MAX  16
69
#define IKED_TAG_SIZE   64
70
722k
#define IKED_CYCLE_BUFFERS  8  /* # of static buffers for mapping */
71
#define IKED_PASSWORD_SIZE  256 /* limited by most EAP types */
72
73
#define IKED_LIFETIME_BYTES 4294967296ULL /* 4 GB */
74
#define IKED_LIFETIME_SECONDS 10800     /* 3 hours */
75
76
197k
#define IKED_E      0x1000  /* Decrypted flag */
77
78
struct iked_constmap {
79
  unsigned int   cm_type;
80
  const char  *cm_name;
81
  const char  *cm_descr;
82
};
83
84
struct iked_transform {
85
  uint8_t        xform_type;
86
  uint16_t       xform_id;
87
  uint16_t       xform_length;
88
  uint16_t       xform_keylength;
89
  unsigned int       xform_score;
90
  struct iked_constmap    *xform_map;
91
};
92
93
enum imsg_type {
94
  IMSG_NONE,
95
  IMSG_CTL_OK,
96
  IMSG_CTL_FAIL,
97
  IMSG_CTL_VERBOSE,
98
  IMSG_CTL_NOTIFY,
99
  IMSG_CTL_RELOAD,
100
  IMSG_CTL_RESET,
101
  IMSG_CTL_COUPLE,
102
  IMSG_CTL_DECOUPLE,
103
  IMSG_CTL_ACTIVE,
104
  IMSG_CTL_PASSIVE,
105
  IMSG_CTL_RESET_ID,
106
  IMSG_CTL_SHOW_SA,
107
  IMSG_CTL_STATIC,
108
  IMSG_COMPILE,
109
  IMSG_UDP_SOCKET,
110
  IMSG_PFKEY_SOCKET,
111
  IMSG_IKE_MESSAGE,
112
  IMSG_CFG_POLICY,
113
  IMSG_CFG_FLOW,
114
  IMSG_CFG_USER,
115
  IMSG_CERTREQ,
116
  IMSG_CERT,
117
  IMSG_CERTVALID,
118
  IMSG_CERTINVALID,
119
  IMSG_CERT_PARTIAL_CHAIN,
120
  IMSG_SCERT,
121
  IMSG_IF_ADDADDR,
122
  IMSG_IF_DELADDR,
123
  IMSG_VROUTE_ADD,
124
  IMSG_VROUTE_DEL,
125
  IMSG_VROUTE_CLONE,
126
  IMSG_VDNS_ADD,
127
  IMSG_VDNS_DEL,
128
  IMSG_OCSP_FD,
129
  IMSG_OCSP_CFG,
130
  IMSG_AUTH,
131
  IMSG_PRIVKEY,
132
  IMSG_PUBKEY,
133
  IMSG_CTL_SHOW_CERTSTORE,
134
  IMSG_CTL_SHOW_STATS,
135
  IMSG_CTL_PROCFD,
136
};
137
138
enum privsep_procid {
139
  PROC_PARENT = 0,
140
  PROC_CONTROL,
141
  PROC_CERT,
142
  PROC_IKEV2,
143
  PROC_MAX
144
};
145
146
enum flushmode {
147
  RESET_RELOAD  = 0,
148
  RESET_ALL,
149
  RESET_CA,
150
  RESET_POLICY,
151
  RESET_SA,
152
  RESET_USER,
153
};
154
155
#ifndef nitems
156
#define nitems(_a)   (sizeof((_a)) / sizeof((_a)[0]))
157
#endif
158
159
#endif /* IKED_TYPES_H */
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/iked/util.c.html b/coverage/latest/report/linux/src/openiked-portable/iked/util.c.html index c58d14a0a..999f87e04 100644 --- a/coverage/latest/report/linux/src/openiked-portable/iked/util.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/iked/util.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: util.c,v 1.43 2023/07/28 11:23:03 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <netinet/ip_ipsp.h>
27
28
#include <netdb.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <unistd.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <limits.h>
35
#include <fcntl.h>
36
#include <ctype.h>
37
#include <event.h>
38
39
#include "iked.h"
40
#include "ikev2.h"
41
42
int
43
socket_af(struct sockaddr *sa, in_port_t port)
44
0
{
45
0
  errno = 0;
46
0
  switch (sa->sa_family) {
47
0
  case AF_INET:
48
0
    ((struct sockaddr_in *)sa)->sin_port = port;
49
#ifdef HAVE_SOCKADDR_SA_LEN
50
    ((struct sockaddr_in *)sa)->sin_len =
51
        sizeof(struct sockaddr_in);
52
#endif
53
0
    break;
54
0
  case AF_INET6:
55
0
    ((struct sockaddr_in6 *)sa)->sin6_port = port;
56
#ifdef HAVE_SOCKADDR_SA_LEN
57
    ((struct sockaddr_in6 *)sa)->sin6_len =
58
        sizeof(struct sockaddr_in6);
59
#endif
60
0
    break;
61
0
  default:
62
0
    errno = EPFNOSUPPORT;
63
0
    return (-1);
64
0
  }
65
66
0
  return (0);
67
0
}
68
69
in_port_t
70
socket_getport(struct sockaddr *sa)
71
14.0k
{
72
14.0k
  switch (sa->sa_family) {
73
11.7k
  case AF_INET:
74
11.7k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
2.24k
  case AF_INET6:
76
2.24k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
14.0k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
14.0k
}
84
85
int
86
socket_setport(struct sockaddr *sa, in_port_t port)
87
0
{
88
0
  switch (sa->sa_family) {
89
0
  case AF_INET:
90
0
    ((struct sockaddr_in *)sa)->sin_port = htons(port);
91
0
    break;
92
0
  case AF_INET6:
93
0
    ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
94
0
    break;
95
0
  default:
96
0
    return (-1);
97
0
  }
98
0
  return (0);
99
0
}
100
101
int
102
socket_getaddr(int s, struct sockaddr_storage *ss)
103
0
{
104
0
  socklen_t sslen = sizeof(*ss);
105
106
0
  return (getsockname(s, (struct sockaddr *)ss, &sslen));
107
0
}
108
109
int
110
socket_bypass(int s, struct sockaddr *sa)
111
0
{
112
#if defined(__OpenBSD__)
113
  int  v, *a;
114
  int  a4[] = {
115
        IPPROTO_IP,
116
        IP_AUTH_LEVEL,
117
        IP_ESP_TRANS_LEVEL,
118
        IP_ESP_NETWORK_LEVEL,
119
#ifdef IPV6_IPCOMP_LEVEL
120
        IP_IPCOMP_LEVEL
121
#endif
122
  };
123
  int  a6[] = {
124
        IPPROTO_IPV6,
125
        IPV6_AUTH_LEVEL,
126
        IPV6_ESP_TRANS_LEVEL,
127
        IPV6_ESP_NETWORK_LEVEL,
128
#ifdef IPV6_IPCOMP_LEVEL
129
        IPV6_IPCOMP_LEVEL
130
#endif
131
  };
132
133
  switch (sa->sa_family) {
134
  case AF_INET:
135
    a = a4;
136
    break;
137
  case AF_INET6:
138
    a = a6;
139
    break;
140
  default:
141
    log_warn("%s: invalid address family", __func__);
142
    return (-1);
143
  }
144
145
  v = IPSEC_LEVEL_BYPASS;
146
  if (setsockopt(s, a[0], a[1], &v, sizeof(v)) == -1) {
147
    log_warn("%s: AUTH_LEVEL", __func__);
148
    return (-1);
149
  }
150
  if (setsockopt(s, a[0], a[2], &v, sizeof(v)) == -1) {
151
    log_warn("%s: ESP_TRANS_LEVEL", __func__);
152
    return (-1);
153
  }
154
  if (setsockopt(s, a[0], a[3], &v, sizeof(v)) == -1) {
155
    log_warn("%s: ESP_NETWORK_LEVEL", __func__);
156
    return (-1);
157
  }
158
#ifdef IP_IPCOMP_LEVEL
159
  if (setsockopt(s, a[0], a[4], &v, sizeof(v)) == -1) {
160
    log_warn("%s: IPCOMP_LEVEL", __func__);
161
    return (-1);
162
  }
163
#endif
164
#else /* __OpenBSD__ */
165
0
  int *a;
166
0
  int  a4[] = {
167
0
        IPPROTO_IP,
168
0
        IP_IPSEC_POLICY
169
0
  };
170
0
  int  a6[] = {
171
0
        IPPROTO_IPV6,
172
0
        IPV6_IPSEC_POLICY,
173
0
  };
174
0
  struct sadb_x_policy pol = {
175
0
        SADB_UPDATE,
176
0
        SADB_EXT_SENSITIVITY,
177
0
        IPSEC_POLICY_BYPASS,
178
0
        0, 0, 0, 0
179
0
  };
180
181
0
  switch (sa->sa_family) {
182
0
  case AF_INET:
183
0
    a = a4;
184
0
    break;
185
0
  case AF_INET6:
186
0
    a = a6;
187
0
    break;
188
0
  default:
189
0
    log_warn("%s: invalid address family", __func__);
190
0
    return (-1);
191
0
  }
192
193
0
  pol.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
194
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
195
0
    log_warn("%s: IPSEC_DIR_INBOUND", __func__);
196
0
    return (-1);
197
0
  }
198
0
  pol.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
199
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
200
0
    log_warn("%s: IPSEC_DIR_OUTBOUND", __func__);
201
0
    return (-1);
202
0
  }
203
0
#endif /* !__OpenBSD__ */
204
205
0
  return (0);
206
0
}
207
208
int
209
udp_bind(struct sockaddr *sa, in_port_t port)
210
0
{
211
0
  int  s, val;
212
213
0
  if (socket_af(sa, port) == -1) {
214
0
    log_warn("%s: failed to set UDP port", __func__);
215
0
    return (-1);
216
0
  }
217
218
0
  if ((s = socket(sa->sa_family,
219
0
      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1) {
220
0
    log_warn("%s: failed to get UDP socket", __func__);
221
0
    return (-1);
222
0
  }
223
224
  /* Skip IPsec processing (don't encrypt) for IKE messages */
225
0
  if (socket_bypass(s, sa) == -1) {
226
0
    log_warn("%s: failed to bypass IPsec on IKE socket",
227
0
        __func__);
228
0
    goto bad;
229
0
  }
230
231
0
  val = 1;
232
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) {
233
0
    log_warn("%s: failed to set reuseport", __func__);
234
0
    goto bad;
235
0
  }
236
0
  val = 1;
237
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) {
238
0
    log_warn("%s: failed to set reuseaddr", __func__);
239
0
    goto bad;
240
0
  }
241
242
0
  if (sa->sa_family == AF_INET) {
243
0
#if defined(IP_RECVORIGDSTADDR)
244
0
    val = 1;
245
0
    if (setsockopt(s, IPPROTO_IP, IP_RECVORIGDSTADDR,
246
0
        &val, sizeof(int)) == -1) {
247
0
      log_warn("%s: failed to set IPv4 packet info",
248
0
          __func__);
249
0
      goto bad;
250
0
    }
251
#elif defined(IP_RECVDSTADDR)
252
    val = 1;
253
    if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
254
        &val, sizeof(int)) == -1) {
255
      log_warn("%s: failed to set IPv4 packet info",
256
          __func__);
257
      goto bad;
258
    }
259
#endif
260
0
  } else {
261
0
#ifdef IPV6_RECVPKTINFO
262
0
    val = 1;
263
0
    if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO,
264
0
        &val, sizeof(int)) == -1) {
265
0
      log_warn("%s: failed to set IPv6 packet info",
266
0
          __func__);
267
0
      goto bad;
268
0
    }
269
0
#endif
270
0
  }
271
272
0
  if (bind(s, sa, SA_LEN(sa)) == -1) {
273
0
    log_warn("%s: failed to bind UDP socket", __func__);
274
0
    goto bad;
275
0
  }
276
277
0
  return (s);
278
0
 bad:
279
0
  close(s);
280
0
  return (-1);
281
0
}
282
283
int
284
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
285
0
{
286
0
  struct sockaddr_in  *a4, *b4;
287
0
  struct sockaddr_in6 *a6, *b6;
288
0
  uint32_t     av[4], bv[4], mv[4];
289
290
0
  if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
291
0
    return (0);
292
0
  else if (a->sa_family > b->sa_family)
293
0
    return (1);
294
0
  else if (a->sa_family < b->sa_family)
295
0
    return (-1);
296
297
0
  if (prefixlen == -1)
298
0
    memset(&mv, 0xff, sizeof(mv));
299
300
0
  switch (a->sa_family) {
301
0
  case AF_INET:
302
0
    a4 = (struct sockaddr_in *)a;
303
0
    b4 = (struct sockaddr_in *)b;
304
305
0
    av[0] = a4->sin_addr.s_addr;
306
0
    bv[0] = b4->sin_addr.s_addr;
307
0
    if (prefixlen != -1)
308
0
      mv[0] = prefixlen2mask(prefixlen);
309
310
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
311
0
      return (1);
312
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
313
0
      return (-1);
314
0
    break;
315
0
  case AF_INET6:
316
0
    a6 = (struct sockaddr_in6 *)a;
317
0
    b6 = (struct sockaddr_in6 *)b;
318
319
0
    memcpy(&av, &a6->sin6_addr.s6_addr, 16);
320
0
    memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
321
0
    if (prefixlen != -1)
322
0
      prefixlen2mask6(prefixlen, mv);
323
324
0
    if ((av[3] & mv[3]) > (bv[3] & mv[3]))
325
0
      return (1);
326
0
    if ((av[3] & mv[3]) < (bv[3] & mv[3]))
327
0
      return (-1);
328
0
    if ((av[2] & mv[2]) > (bv[2] & mv[2]))
329
0
      return (1);
330
0
    if ((av[2] & mv[2]) < (bv[2] & mv[2]))
331
0
      return (-1);
332
0
    if ((av[1] & mv[1]) > (bv[1] & mv[1]))
333
0
      return (1);
334
0
    if ((av[1] & mv[1]) < (bv[1] & mv[1]))
335
0
      return (-1);
336
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
337
0
      return (1);
338
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
339
0
      return (-1);
340
0
    break;
341
0
  }
342
343
0
  return (0);
344
0
}
345
346
ssize_t
347
sendtofrom(int s, void *buf, size_t len, int flags, struct sockaddr *to,
348
    socklen_t tolen, struct sockaddr *from, socklen_t fromlen)
349
0
{
350
0
  struct iovec     iov;
351
0
  struct msghdr    msg;
352
0
  struct cmsghdr    *cmsg;
353
#ifdef IP_SENDSRCADDR
354
  struct sockaddr_in  *in;
355
#endif
356
0
#ifdef IPV6_PKTINFO
357
0
  struct in6_pktinfo  *pkt6;
358
0
  struct sockaddr_in6 *in6;
359
0
#endif
360
0
  union {
361
0
    struct cmsghdr  hdr;
362
0
    char    inbuf[CMSG_SPACE(sizeof(struct in_addr))];
363
0
    char    in6buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
364
0
  } cmsgbuf;
365
366
0
  bzero(&msg, sizeof(msg));
367
0
  bzero(&cmsgbuf, sizeof(cmsgbuf));
368
369
0
  iov.iov_base = buf;
370
0
  iov.iov_len = len;
371
0
  msg.msg_iov = &iov;
372
0
  msg.msg_iovlen = 1;
373
0
  msg.msg_name = to;
374
0
  msg.msg_namelen = tolen;
375
0
  msg.msg_controllen = 0;
376
377
0
  switch (to->sa_family) {
378
0
  case AF_INET:
379
#ifdef IP_SENDSRCADDR
380
    in = (struct sockaddr_in *)from;
381
    if (in->sin_addr.s_addr == INADDR_ANY)
382
      break;
383
    msg.msg_control = &cmsgbuf;
384
    msg.msg_controllen += sizeof(cmsgbuf.inbuf);
385
    cmsg = CMSG_FIRSTHDR(&msg);
386
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
387
    cmsg->cmsg_level = IPPROTO_IP;
388
    cmsg->cmsg_type = IP_SENDSRCADDR;
389
    memcpy(CMSG_DATA(cmsg), &in->sin_addr, sizeof(struct in_addr));
390
#endif
391
0
    break;
392
0
  case AF_INET6:
393
0
#ifdef IPV6_PKTINFO
394
0
    msg.msg_control = &cmsgbuf;
395
0
    msg.msg_controllen += sizeof(cmsgbuf.in6buf);
396
0
    cmsg = CMSG_FIRSTHDR(&msg);
397
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
398
0
    cmsg->cmsg_level = IPPROTO_IPV6;
399
0
    cmsg->cmsg_type = IPV6_PKTINFO;
400
0
    in6 = (struct sockaddr_in6 *)from;
401
0
    pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
402
0
    pkt6->ipi6_addr = in6->sin6_addr;
403
0
#endif
404
0
    break;
405
0
  }
406
407
0
  return sendmsg(s, &msg, flags);
408
0
}
409
410
ssize_t
411
recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
412
    socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen)
413
0
{
414
0
  struct iovec     iov;
415
0
  struct msghdr    msg;
416
0
  struct cmsghdr    *cmsg;
417
#if !defined(IP_RECVORIGDSTADDR) && defined(IP_RECVDSTADDR)
418
  struct sockaddr_in  *in;
419
#endif
420
0
#ifdef IPV6_PKTINFO
421
0
  struct in6_pktinfo  *pkt6;
422
0
  struct sockaddr_in6 *in6;
423
0
#endif
424
0
  ssize_t      ret;
425
0
  union {
426
0
    struct cmsghdr hdr;
427
0
    char  buf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
428
0
  } cmsgbuf;
429
430
0
  bzero(&msg, sizeof(msg));
431
0
  bzero(&cmsgbuf.buf, sizeof(cmsgbuf.buf));
432
433
0
  iov.iov_base = buf;
434
0
  iov.iov_len = len;
435
0
  msg.msg_iov = &iov;
436
0
  msg.msg_iovlen = 1;
437
0
  msg.msg_name = from;
438
0
  msg.msg_namelen = *fromlen;
439
0
  msg.msg_control = &cmsgbuf.buf;
440
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
441
442
0
  if ((ret = recvmsg(s, &msg, flags)) == -1)
443
0
    return (-1);
444
445
0
  *fromlen = SA_LEN(from);
446
447
0
  if (getsockname(s, to, tolen) != 0)
448
0
    *tolen = 0;
449
450
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
451
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
452
0
    switch (from->sa_family) {
453
0
    case AF_INET:
454
0
#if defined(IP_RECVORIGDSTADDR)
455
0
      if (cmsg->cmsg_level == IPPROTO_IP &&
456
0
          cmsg->cmsg_type == IP_RECVORIGDSTADDR) {
457
0
        memcpy(to, CMSG_DATA(cmsg),
458
0
            sizeof(struct sockaddr_in));
459
0
      }
460
#elif defined(IP_RECVDSTADDR)
461
      if (cmsg->cmsg_level == IPPROTO_IP &&
462
          cmsg->cmsg_type == IP_RECVDSTADDR) {
463
        in = (struct sockaddr_in *)to;
464
        in->sin_family = AF_INET;
465
#ifdef HAVE_SOCKADDR_SA_LEN
466
        in->sin_len = *tolen = sizeof(*in);
467
#endif
468
        memcpy(&in->sin_addr, CMSG_DATA(cmsg),
469
            sizeof(struct in_addr));
470
      }
471
#endif /* defined(IP_RECVDSTADDR) */
472
0
      break;
473
0
    case AF_INET6:
474
0
#ifdef IPV6_PKTINFO
475
0
      if (cmsg->cmsg_level == IPPROTO_IPV6 &&
476
0
          cmsg->cmsg_type == IPV6_PKTINFO) {
477
0
        in6 = (struct sockaddr_in6 *)to;
478
0
        in6->sin6_family = AF_INET6;
479
#ifdef HAVE_SOCKADDR_SA_LEN
480
        in6->sin6_len = *tolen = sizeof(*in6);
481
#endif
482
0
        pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
483
0
        memcpy(&in6->sin6_addr, &pkt6->ipi6_addr,
484
0
            sizeof(struct in6_addr));
485
0
        if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
486
0
          in6->sin6_scope_id =
487
0
              pkt6->ipi6_ifindex;
488
0
      }
489
0
#endif
490
0
      break;
491
0
    }
492
0
  }
493
494
0
  return (ret);
495
0
}
496
497
const char *
498
print_spi(uint64_t spi, int size)
499
35.7k
{
500
35.7k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
35.7k
  static int     i = 0;
502
35.7k
  char      *ptr;
503
504
35.7k
  ptr = buf[i];
505
506
35.7k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
349
  case 4:
511
349
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
349
    break;
513
26.2k
  case 8:
514
26.2k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
26.2k
    break;
516
9.10k
  default:
517
9.10k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
9.10k
    break;
519
35.7k
  }
520
521
35.7k
  if (++i >= IKED_CYCLE_BUFFERS)
522
4.46k
    i = 0;
523
524
35.7k
  return (ptr);
525
35.7k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
669k
{
530
669k
  unsigned int     i;
531
669k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
669k
  static int     idx = 0;
533
669k
  const char    *name = NULL;
534
535
669k
  if (idx >= IKED_CYCLE_BUFFERS)
536
83.6k
    idx = 0;
537
669k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
14.1M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
13.4M
    if (map[i].cm_type == type)
541
465k
      name = map[i].cm_name;
542
13.4M
  }
543
544
669k
  if (name == NULL)
545
203k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
465k
  else
547
465k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
669k
  return (buf[idx++]);
550
669k
}
551
552
void
553
lc_idtype(char *str)
554
0
{
555
0
  for (; *str != '\0' && *str != '/'; str++)
556
0
    *str = tolower((unsigned char)*str);
557
0
}
558
559
void
560
print_hex(const uint8_t *buf, off_t offset, size_t length)
561
147k
{
562
147k
  unsigned int   i;
563
564
147k
  if (log_getverbose() < 3 || !length)
565
147k
    return;
566
567
0
  for (i = 0; i < length; i++) {
568
0
    if (i && (i % 4) == 0) {
569
0
      if ((i % 32) == 0)
570
0
        print_debug("\n");
571
0
      else
572
0
        print_debug(" ");
573
0
    }
574
0
    print_debug("%02x", buf[offset + i]);
575
0
  }
576
0
  print_debug("\n");
577
0
}
578
579
void
580
print_hexval(const uint8_t *buf, off_t offset, size_t length)
581
0
{
582
0
  unsigned int   i;
583
584
0
  if (log_getverbose() < 2 || !length)
585
0
    return;
586
587
0
  print_debug("0x");
588
0
  for (i = 0; i < length; i++)
589
0
    print_debug("%02x", buf[offset + i]);
590
0
  print_debug("\n");
591
0
}
592
593
void
594
print_hexbuf(struct ibuf *ibuf)
595
0
{
596
0
  print_hex(ibuf_data(ibuf), 0, ibuf_size(ibuf));
597
0
}
598
599
const char *
600
print_bits(unsigned short v, unsigned char *bits)
601
0
{
602
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
603
0
  static int   idx = 0;
604
0
  unsigned int   i, any = 0, j = 0;
605
0
  unsigned char  c;
606
607
0
  if (!bits)
608
0
    return ("");
609
610
0
  if (++idx >= IKED_CYCLE_BUFFERS)
611
0
    idx = 0;
612
613
0
  bzero(buf[idx], sizeof(buf[idx]));
614
615
0
  bits++;
616
0
  while ((i = *bits++)) {
617
0
    if (v & (1 << (i-1))) {
618
0
      if (any) {
619
0
        buf[idx][j++] = ',';
620
0
        if (j >= sizeof(buf[idx]))
621
0
          return (buf[idx]);
622
0
      }
623
0
      any = 1;
624
0
      for (; (c = *bits) > 32; bits++) {
625
0
        buf[idx][j++] = tolower((unsigned char)c);
626
0
        if (j >= sizeof(buf[idx]))
627
0
          return (buf[idx]);
628
0
      }
629
0
    } else
630
0
      for (; *bits > 32; bits++)
631
0
        ;
632
0
  }
633
634
0
  return (buf[idx]);
635
0
}
636
637
uint8_t
638
mask2prefixlen(struct sockaddr *sa)
639
0
{
640
0
  struct sockaddr_in  *sa_in = (struct sockaddr_in *)sa;
641
0
  in_addr_t    ina = sa_in->sin_addr.s_addr;
642
643
0
  if (ina == 0)
644
0
    return (0);
645
0
  else
646
0
    return (33 - ffs(ntohl(ina)));
647
0
}
648
649
uint8_t
650
mask2prefixlen6(struct sockaddr *sa)
651
0
{
652
0
  struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
653
0
  uint8_t     *ap, *ep;
654
0
  unsigned int     l = 0;
655
656
  /*
657
   * sin6_len is the size of the sockaddr so substract the offset of
658
   * the possibly truncated sin6_addr struct.
659
   */
660
0
  ap = (uint8_t *)&sa_in6->sin6_addr;
661
0
  ep = (uint8_t *)sa_in6 + SA_LEN(sa);
662
0
  for (; ap < ep; ap++) {
663
    /* this "beauty" is adopted from sbin/route/show.c ... */
664
0
    switch (*ap) {
665
0
    case 0xff:
666
0
      l += 8;
667
0
      break;
668
0
    case 0xfe:
669
0
      l += 7;
670
0
      goto done;
671
0
    case 0xfc:
672
0
      l += 6;
673
0
      goto done;
674
0
    case 0xf8:
675
0
      l += 5;
676
0
      goto done;
677
0
    case 0xf0:
678
0
      l += 4;
679
0
      goto done;
680
0
    case 0xe0:
681
0
      l += 3;
682
0
      goto done;
683
0
    case 0xc0:
684
0
      l += 2;
685
0
      goto done;
686
0
    case 0x80:
687
0
      l += 1;
688
0
      goto done;
689
0
    case 0x00:
690
0
      goto done;
691
0
    default:
692
0
      fatalx("non contiguous inet6 netmask");
693
0
    }
694
0
  }
695
696
0
done:
697
0
  if (l > sizeof(struct in6_addr) * 8)
698
0
    fatalx("%s: prefixlen %d out of bound", __func__, l);
699
0
  return (l);
700
0
}
701
702
uint32_t
703
prefixlen2mask(uint8_t prefixlen)
704
0
{
705
0
  if (prefixlen == 0)
706
0
    return (0);
707
708
0
  if (prefixlen > 32)
709
0
    prefixlen = 32;
710
711
0
  return (htonl(0xffffffff << (32 - prefixlen)));
712
0
}
713
714
struct in6_addr *
715
prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
716
0
{
717
0
  static struct in6_addr  s6;
718
0
  int     i;
719
720
0
  if (prefixlen > 128)
721
0
    prefixlen = 128;
722
723
0
  bzero(&s6, sizeof(s6));
724
0
  for (i = 0; i < prefixlen / 8; i++)
725
0
    s6.s6_addr[i] = 0xff;
726
0
  i = prefixlen % 8;
727
0
  if (i)
728
0
    s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
729
730
0
  memcpy(mask, &s6, sizeof(s6));
731
732
0
  return (&s6);
733
0
}
734
735
const char *
736
print_addr(void *addr)
737
14.0k
{
738
14.0k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
14.0k
  static int   idx;
740
14.0k
  struct sockaddr *sa = addr;
741
14.0k
  char    *buf;
742
14.0k
  size_t     len;
743
14.0k
  char     pbuf[7];
744
14.0k
  in_port_t  port;
745
746
14.0k
  buf = sbuf[idx];
747
14.0k
  len = sizeof(sbuf[idx]);
748
14.0k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.75k
    idx = 0;
750
751
14.0k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
14.0k
  if (getnameinfo(sa, SA_LEN(sa),
757
14.0k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
14.0k
  if ((port = socket_getport(sa)) != 0) {
763
0
    snprintf(pbuf, sizeof(pbuf), ":%d", port);
764
0
    (void)strlcat(buf, pbuf, len);
765
0
  }
766
767
14.0k
  return (buf);
768
14.0k
}
769
770
char *
771
get_string(uint8_t *ptr, size_t len)
772
0
{
773
0
  size_t   i;
774
775
0
  for (i = 0; i < len; i++)
776
0
    if (!isprint(ptr[i]))
777
0
      break;
778
779
0
  return strndup(ptr, i);
780
0
}
781
782
const char *
783
print_proto(uint8_t proto)
784
0
{
785
0
  struct protoent *p;
786
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
787
0
  static int   idx = 0;
788
789
0
  if (idx >= IKED_CYCLE_BUFFERS)
790
0
    idx = 0;
791
792
0
  if ((p = getprotobynumber(proto)) != NULL)
793
0
    strlcpy(buf[idx], p->p_name, sizeof(buf[idx]));
794
0
  else
795
0
    snprintf(buf[idx], sizeof(buf), "%u", proto);
796
797
798
0
  return (buf[idx++]);
799
0
}
800
801
int
802
expand_string(char *label, size_t len, const char *srch, const char *repl)
803
0
{
804
0
  char *tmp;
805
0
  char *p, *q;
806
807
0
  if ((tmp = calloc(1, len)) == NULL) {
808
0
    log_debug("%s: calloc", __func__);
809
0
    return (-1);
810
0
  }
811
0
  p = label;
812
0
  while ((q = strstr(p, srch)) != NULL) {
813
0
    *q = '\0';
814
0
    if ((strlcat(tmp, p, len) >= len) ||
815
0
        (strlcat(tmp, repl, len) >= len)) {
816
0
      log_debug("%s: string too long", __func__);
817
0
      free(tmp);
818
0
      return (-1);
819
0
    }
820
0
    q += strlen(srch);
821
0
    p = q;
822
0
  }
823
0
  if (strlcat(tmp, p, len) >= len) {
824
0
    log_debug("%s: string too long", __func__);
825
0
    free(tmp);
826
0
    return (-1);
827
0
  }
828
0
  strlcpy(label, tmp, len); /* always fits */
829
0
  free(tmp);
830
831
0
  return (0);
832
0
}
833
834
uint8_t *
835
string2unicode(const char *ascii, size_t *outlen)
836
0
{
837
0
  uint8_t   *uc = NULL;
838
0
  size_t     i, len = strlen(ascii);
839
840
0
  if ((uc = calloc(1, (len * 2) + 2)) == NULL)
841
0
    return (NULL);
842
843
0
  for (i = 0; i < len; i++) {
844
    /* XXX what about the byte order? */
845
0
    uc[i * 2] = ascii[i];
846
0
  }
847
0
  *outlen = len * 2;
848
849
0
  return (uc);
850
0
}
851
852
void
853
print_debug(const char *emsg, ...)
854
0
{
855
0
  va_list  ap;
856
857
0
  if (log_getverbose() > 2) {
858
0
    va_start(ap, emsg);
859
0
    vfprintf(stderr, emsg, ap);
860
0
    va_end(ap);
861
0
  }
862
0
}
863
864
void
865
print_verbose(const char *emsg, ...)
866
0
{
867
0
  va_list  ap;
868
869
0
  if (log_getverbose()) {
870
0
    va_start(ap, emsg);
871
0
    vfprintf(stderr, emsg, ap);
872
0
    va_end(ap);
873
0
  }
874
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: util.c,v 1.43 2023/07/28 11:23:03 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <netinet/ip_ipsp.h>
27
28
#include <netdb.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <unistd.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <limits.h>
35
#include <fcntl.h>
36
#include <ctype.h>
37
#include <event.h>
38
39
#include "iked.h"
40
#include "ikev2.h"
41
42
int
43
socket_af(struct sockaddr *sa, in_port_t port)
44
0
{
45
0
  errno = 0;
46
0
  switch (sa->sa_family) {
47
0
  case AF_INET:
48
0
    ((struct sockaddr_in *)sa)->sin_port = port;
49
#ifdef HAVE_SOCKADDR_SA_LEN
50
    ((struct sockaddr_in *)sa)->sin_len =
51
        sizeof(struct sockaddr_in);
52
#endif
53
0
    break;
54
0
  case AF_INET6:
55
0
    ((struct sockaddr_in6 *)sa)->sin6_port = port;
56
#ifdef HAVE_SOCKADDR_SA_LEN
57
    ((struct sockaddr_in6 *)sa)->sin6_len =
58
        sizeof(struct sockaddr_in6);
59
#endif
60
0
    break;
61
0
  default:
62
0
    errno = EPFNOSUPPORT;
63
0
    return (-1);
64
0
  }
65
66
0
  return (0);
67
0
}
68
69
in_port_t
70
socket_getport(struct sockaddr *sa)
71
14.2k
{
72
14.2k
  switch (sa->sa_family) {
73
11.9k
  case AF_INET:
74
11.9k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
2.27k
  case AF_INET6:
76
2.27k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
14.2k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
14.2k
}
84
85
int
86
socket_setport(struct sockaddr *sa, in_port_t port)
87
0
{
88
0
  switch (sa->sa_family) {
89
0
  case AF_INET:
90
0
    ((struct sockaddr_in *)sa)->sin_port = htons(port);
91
0
    break;
92
0
  case AF_INET6:
93
0
    ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
94
0
    break;
95
0
  default:
96
0
    return (-1);
97
0
  }
98
0
  return (0);
99
0
}
100
101
int
102
socket_getaddr(int s, struct sockaddr_storage *ss)
103
0
{
104
0
  socklen_t sslen = sizeof(*ss);
105
106
0
  return (getsockname(s, (struct sockaddr *)ss, &sslen));
107
0
}
108
109
int
110
socket_bypass(int s, struct sockaddr *sa)
111
0
{
112
#if defined(__OpenBSD__)
113
  int  v, *a;
114
  int  a4[] = {
115
        IPPROTO_IP,
116
        IP_AUTH_LEVEL,
117
        IP_ESP_TRANS_LEVEL,
118
        IP_ESP_NETWORK_LEVEL,
119
#ifdef IPV6_IPCOMP_LEVEL
120
        IP_IPCOMP_LEVEL
121
#endif
122
  };
123
  int  a6[] = {
124
        IPPROTO_IPV6,
125
        IPV6_AUTH_LEVEL,
126
        IPV6_ESP_TRANS_LEVEL,
127
        IPV6_ESP_NETWORK_LEVEL,
128
#ifdef IPV6_IPCOMP_LEVEL
129
        IPV6_IPCOMP_LEVEL
130
#endif
131
  };
132
133
  switch (sa->sa_family) {
134
  case AF_INET:
135
    a = a4;
136
    break;
137
  case AF_INET6:
138
    a = a6;
139
    break;
140
  default:
141
    log_warn("%s: invalid address family", __func__);
142
    return (-1);
143
  }
144
145
  v = IPSEC_LEVEL_BYPASS;
146
  if (setsockopt(s, a[0], a[1], &v, sizeof(v)) == -1) {
147
    log_warn("%s: AUTH_LEVEL", __func__);
148
    return (-1);
149
  }
150
  if (setsockopt(s, a[0], a[2], &v, sizeof(v)) == -1) {
151
    log_warn("%s: ESP_TRANS_LEVEL", __func__);
152
    return (-1);
153
  }
154
  if (setsockopt(s, a[0], a[3], &v, sizeof(v)) == -1) {
155
    log_warn("%s: ESP_NETWORK_LEVEL", __func__);
156
    return (-1);
157
  }
158
#ifdef IP_IPCOMP_LEVEL
159
  if (setsockopt(s, a[0], a[4], &v, sizeof(v)) == -1) {
160
    log_warn("%s: IPCOMP_LEVEL", __func__);
161
    return (-1);
162
  }
163
#endif
164
#else /* __OpenBSD__ */
165
0
  int *a;
166
0
  int  a4[] = {
167
0
        IPPROTO_IP,
168
0
        IP_IPSEC_POLICY
169
0
  };
170
0
  int  a6[] = {
171
0
        IPPROTO_IPV6,
172
0
        IPV6_IPSEC_POLICY,
173
0
  };
174
0
  struct sadb_x_policy pol = {
175
0
        SADB_UPDATE,
176
0
        SADB_EXT_SENSITIVITY,
177
0
        IPSEC_POLICY_BYPASS,
178
0
        0, 0, 0, 0
179
0
  };
180
181
0
  switch (sa->sa_family) {
182
0
  case AF_INET:
183
0
    a = a4;
184
0
    break;
185
0
  case AF_INET6:
186
0
    a = a6;
187
0
    break;
188
0
  default:
189
0
    log_warn("%s: invalid address family", __func__);
190
0
    return (-1);
191
0
  }
192
193
0
  pol.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
194
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
195
0
    log_warn("%s: IPSEC_DIR_INBOUND", __func__);
196
0
    return (-1);
197
0
  }
198
0
  pol.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
199
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
200
0
    log_warn("%s: IPSEC_DIR_OUTBOUND", __func__);
201
0
    return (-1);
202
0
  }
203
0
#endif /* !__OpenBSD__ */
204
205
0
  return (0);
206
0
}
207
208
int
209
udp_bind(struct sockaddr *sa, in_port_t port)
210
0
{
211
0
  int  s, val;
212
213
0
  if (socket_af(sa, port) == -1) {
214
0
    log_warn("%s: failed to set UDP port", __func__);
215
0
    return (-1);
216
0
  }
217
218
0
  if ((s = socket(sa->sa_family,
219
0
      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1) {
220
0
    log_warn("%s: failed to get UDP socket", __func__);
221
0
    return (-1);
222
0
  }
223
224
  /* Skip IPsec processing (don't encrypt) for IKE messages */
225
0
  if (socket_bypass(s, sa) == -1) {
226
0
    log_warn("%s: failed to bypass IPsec on IKE socket",
227
0
        __func__);
228
0
    goto bad;
229
0
  }
230
231
0
  val = 1;
232
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) {
233
0
    log_warn("%s: failed to set reuseport", __func__);
234
0
    goto bad;
235
0
  }
236
0
  val = 1;
237
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) {
238
0
    log_warn("%s: failed to set reuseaddr", __func__);
239
0
    goto bad;
240
0
  }
241
242
0
  if (sa->sa_family == AF_INET) {
243
0
#if defined(IP_RECVORIGDSTADDR)
244
0
    val = 1;
245
0
    if (setsockopt(s, IPPROTO_IP, IP_RECVORIGDSTADDR,
246
0
        &val, sizeof(int)) == -1) {
247
0
      log_warn("%s: failed to set IPv4 packet info",
248
0
          __func__);
249
0
      goto bad;
250
0
    }
251
#elif defined(IP_RECVDSTADDR)
252
    val = 1;
253
    if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
254
        &val, sizeof(int)) == -1) {
255
      log_warn("%s: failed to set IPv4 packet info",
256
          __func__);
257
      goto bad;
258
    }
259
#endif
260
0
  } else {
261
0
#ifdef IPV6_RECVPKTINFO
262
0
    val = 1;
263
0
    if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO,
264
0
        &val, sizeof(int)) == -1) {
265
0
      log_warn("%s: failed to set IPv6 packet info",
266
0
          __func__);
267
0
      goto bad;
268
0
    }
269
0
#endif
270
0
  }
271
272
0
  if (bind(s, sa, SA_LEN(sa)) == -1) {
273
0
    log_warn("%s: failed to bind UDP socket", __func__);
274
0
    goto bad;
275
0
  }
276
277
0
  return (s);
278
0
 bad:
279
0
  close(s);
280
0
  return (-1);
281
0
}
282
283
int
284
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
285
0
{
286
0
  struct sockaddr_in  *a4, *b4;
287
0
  struct sockaddr_in6 *a6, *b6;
288
0
  uint32_t     av[4], bv[4], mv[4];
289
290
0
  if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
291
0
    return (0);
292
0
  else if (a->sa_family > b->sa_family)
293
0
    return (1);
294
0
  else if (a->sa_family < b->sa_family)
295
0
    return (-1);
296
297
0
  if (prefixlen == -1)
298
0
    memset(&mv, 0xff, sizeof(mv));
299
300
0
  switch (a->sa_family) {
301
0
  case AF_INET:
302
0
    a4 = (struct sockaddr_in *)a;
303
0
    b4 = (struct sockaddr_in *)b;
304
305
0
    av[0] = a4->sin_addr.s_addr;
306
0
    bv[0] = b4->sin_addr.s_addr;
307
0
    if (prefixlen != -1)
308
0
      mv[0] = prefixlen2mask(prefixlen);
309
310
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
311
0
      return (1);
312
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
313
0
      return (-1);
314
0
    break;
315
0
  case AF_INET6:
316
0
    a6 = (struct sockaddr_in6 *)a;
317
0
    b6 = (struct sockaddr_in6 *)b;
318
319
0
    memcpy(&av, &a6->sin6_addr.s6_addr, 16);
320
0
    memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
321
0
    if (prefixlen != -1)
322
0
      prefixlen2mask6(prefixlen, mv);
323
324
0
    if ((av[3] & mv[3]) > (bv[3] & mv[3]))
325
0
      return (1);
326
0
    if ((av[3] & mv[3]) < (bv[3] & mv[3]))
327
0
      return (-1);
328
0
    if ((av[2] & mv[2]) > (bv[2] & mv[2]))
329
0
      return (1);
330
0
    if ((av[2] & mv[2]) < (bv[2] & mv[2]))
331
0
      return (-1);
332
0
    if ((av[1] & mv[1]) > (bv[1] & mv[1]))
333
0
      return (1);
334
0
    if ((av[1] & mv[1]) < (bv[1] & mv[1]))
335
0
      return (-1);
336
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
337
0
      return (1);
338
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
339
0
      return (-1);
340
0
    break;
341
0
  }
342
343
0
  return (0);
344
0
}
345
346
ssize_t
347
sendtofrom(int s, void *buf, size_t len, int flags, struct sockaddr *to,
348
    socklen_t tolen, struct sockaddr *from, socklen_t fromlen)
349
0
{
350
0
  struct iovec     iov;
351
0
  struct msghdr    msg;
352
0
  struct cmsghdr    *cmsg;
353
#ifdef IP_SENDSRCADDR
354
  struct sockaddr_in  *in;
355
#endif
356
0
#ifdef IPV6_PKTINFO
357
0
  struct in6_pktinfo  *pkt6;
358
0
  struct sockaddr_in6 *in6;
359
0
#endif
360
0
  union {
361
0
    struct cmsghdr  hdr;
362
0
    char    inbuf[CMSG_SPACE(sizeof(struct in_addr))];
363
0
    char    in6buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
364
0
  } cmsgbuf;
365
366
0
  bzero(&msg, sizeof(msg));
367
0
  bzero(&cmsgbuf, sizeof(cmsgbuf));
368
369
0
  iov.iov_base = buf;
370
0
  iov.iov_len = len;
371
0
  msg.msg_iov = &iov;
372
0
  msg.msg_iovlen = 1;
373
0
  msg.msg_name = to;
374
0
  msg.msg_namelen = tolen;
375
0
  msg.msg_controllen = 0;
376
377
0
  switch (to->sa_family) {
378
0
  case AF_INET:
379
#ifdef IP_SENDSRCADDR
380
    in = (struct sockaddr_in *)from;
381
    if (in->sin_addr.s_addr == INADDR_ANY)
382
      break;
383
    msg.msg_control = &cmsgbuf;
384
    msg.msg_controllen += sizeof(cmsgbuf.inbuf);
385
    cmsg = CMSG_FIRSTHDR(&msg);
386
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
387
    cmsg->cmsg_level = IPPROTO_IP;
388
    cmsg->cmsg_type = IP_SENDSRCADDR;
389
    memcpy(CMSG_DATA(cmsg), &in->sin_addr, sizeof(struct in_addr));
390
#endif
391
0
    break;
392
0
  case AF_INET6:
393
0
#ifdef IPV6_PKTINFO
394
0
    msg.msg_control = &cmsgbuf;
395
0
    msg.msg_controllen += sizeof(cmsgbuf.in6buf);
396
0
    cmsg = CMSG_FIRSTHDR(&msg);
397
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
398
0
    cmsg->cmsg_level = IPPROTO_IPV6;
399
0
    cmsg->cmsg_type = IPV6_PKTINFO;
400
0
    in6 = (struct sockaddr_in6 *)from;
401
0
    pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
402
0
    pkt6->ipi6_addr = in6->sin6_addr;
403
0
#endif
404
0
    break;
405
0
  }
406
407
0
  return sendmsg(s, &msg, flags);
408
0
}
409
410
ssize_t
411
recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
412
    socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen)
413
0
{
414
0
  struct iovec     iov;
415
0
  struct msghdr    msg;
416
0
  struct cmsghdr    *cmsg;
417
#if !defined(IP_RECVORIGDSTADDR) && defined(IP_RECVDSTADDR)
418
  struct sockaddr_in  *in;
419
#endif
420
0
#ifdef IPV6_PKTINFO
421
0
  struct in6_pktinfo  *pkt6;
422
0
  struct sockaddr_in6 *in6;
423
0
#endif
424
0
  ssize_t      ret;
425
0
  union {
426
0
    struct cmsghdr hdr;
427
0
    char  buf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
428
0
  } cmsgbuf;
429
430
0
  bzero(&msg, sizeof(msg));
431
0
  bzero(&cmsgbuf.buf, sizeof(cmsgbuf.buf));
432
433
0
  iov.iov_base = buf;
434
0
  iov.iov_len = len;
435
0
  msg.msg_iov = &iov;
436
0
  msg.msg_iovlen = 1;
437
0
  msg.msg_name = from;
438
0
  msg.msg_namelen = *fromlen;
439
0
  msg.msg_control = &cmsgbuf.buf;
440
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
441
442
0
  if ((ret = recvmsg(s, &msg, flags)) == -1)
443
0
    return (-1);
444
445
0
  *fromlen = SA_LEN(from);
446
447
0
  if (getsockname(s, to, tolen) != 0)
448
0
    *tolen = 0;
449
450
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
451
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
452
0
    switch (from->sa_family) {
453
0
    case AF_INET:
454
0
#if defined(IP_RECVORIGDSTADDR)
455
0
      if (cmsg->cmsg_level == IPPROTO_IP &&
456
0
          cmsg->cmsg_type == IP_RECVORIGDSTADDR) {
457
0
        memcpy(to, CMSG_DATA(cmsg),
458
0
            sizeof(struct sockaddr_in));
459
0
      }
460
#elif defined(IP_RECVDSTADDR)
461
      if (cmsg->cmsg_level == IPPROTO_IP &&
462
          cmsg->cmsg_type == IP_RECVDSTADDR) {
463
        in = (struct sockaddr_in *)to;
464
        in->sin_family = AF_INET;
465
#ifdef HAVE_SOCKADDR_SA_LEN
466
        in->sin_len = *tolen = sizeof(*in);
467
#endif
468
        memcpy(&in->sin_addr, CMSG_DATA(cmsg),
469
            sizeof(struct in_addr));
470
      }
471
#endif /* defined(IP_RECVDSTADDR) */
472
0
      break;
473
0
    case AF_INET6:
474
0
#ifdef IPV6_PKTINFO
475
0
      if (cmsg->cmsg_level == IPPROTO_IPV6 &&
476
0
          cmsg->cmsg_type == IPV6_PKTINFO) {
477
0
        in6 = (struct sockaddr_in6 *)to;
478
0
        in6->sin6_family = AF_INET6;
479
#ifdef HAVE_SOCKADDR_SA_LEN
480
        in6->sin6_len = *tolen = sizeof(*in6);
481
#endif
482
0
        pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
483
0
        memcpy(&in6->sin6_addr, &pkt6->ipi6_addr,
484
0
            sizeof(struct in6_addr));
485
0
        if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
486
0
          in6->sin6_scope_id =
487
0
              pkt6->ipi6_ifindex;
488
0
      }
489
0
#endif
490
0
      break;
491
0
    }
492
0
  }
493
494
0
  return (ret);
495
0
}
496
497
const char *
498
print_spi(uint64_t spi, int size)
499
36.0k
{
500
36.0k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
36.0k
  static int     i = 0;
502
36.0k
  char      *ptr;
503
504
36.0k
  ptr = buf[i];
505
506
36.0k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
349
  case 4:
511
349
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
349
    break;
513
26.5k
  case 8:
514
26.5k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
26.5k
    break;
516
9.11k
  default:
517
9.11k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
9.11k
    break;
519
36.0k
  }
520
521
36.0k
  if (++i >= IKED_CYCLE_BUFFERS)
522
4.50k
    i = 0;
523
524
36.0k
  return (ptr);
525
36.0k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
672k
{
530
672k
  unsigned int     i;
531
672k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
672k
  static int     idx = 0;
533
672k
  const char    *name = NULL;
534
535
672k
  if (idx >= IKED_CYCLE_BUFFERS)
536
84.0k
    idx = 0;
537
672k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
14.2M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
13.5M
    if (map[i].cm_type == type)
541
467k
      name = map[i].cm_name;
542
13.5M
  }
543
544
672k
  if (name == NULL)
545
205k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
467k
  else
547
467k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
672k
  return (buf[idx++]);
550
672k
}
551
552
void
553
lc_idtype(char *str)
554
0
{
555
0
  for (; *str != '\0' && *str != '/'; str++)
556
0
    *str = tolower((unsigned char)*str);
557
0
}
558
559
void
560
print_hex(const uint8_t *buf, off_t offset, size_t length)
561
148k
{
562
148k
  unsigned int   i;
563
564
148k
  if (log_getverbose() < 3 || !length)
565
148k
    return;
566
567
0
  for (i = 0; i < length; i++) {
568
0
    if (i && (i % 4) == 0) {
569
0
      if ((i % 32) == 0)
570
0
        print_debug("\n");
571
0
      else
572
0
        print_debug(" ");
573
0
    }
574
0
    print_debug("%02x", buf[offset + i]);
575
0
  }
576
0
  print_debug("\n");
577
0
}
578
579
void
580
print_hexval(const uint8_t *buf, off_t offset, size_t length)
581
0
{
582
0
  unsigned int   i;
583
584
0
  if (log_getverbose() < 2 || !length)
585
0
    return;
586
587
0
  print_debug("0x");
588
0
  for (i = 0; i < length; i++)
589
0
    print_debug("%02x", buf[offset + i]);
590
0
  print_debug("\n");
591
0
}
592
593
void
594
print_hexbuf(struct ibuf *ibuf)
595
0
{
596
0
  print_hex(ibuf_data(ibuf), 0, ibuf_size(ibuf));
597
0
}
598
599
const char *
600
print_bits(unsigned short v, unsigned char *bits)
601
0
{
602
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
603
0
  static int   idx = 0;
604
0
  unsigned int   i, any = 0, j = 0;
605
0
  unsigned char  c;
606
607
0
  if (!bits)
608
0
    return ("");
609
610
0
  if (++idx >= IKED_CYCLE_BUFFERS)
611
0
    idx = 0;
612
613
0
  bzero(buf[idx], sizeof(buf[idx]));
614
615
0
  bits++;
616
0
  while ((i = *bits++)) {
617
0
    if (v & (1 << (i-1))) {
618
0
      if (any) {
619
0
        buf[idx][j++] = ',';
620
0
        if (j >= sizeof(buf[idx]))
621
0
          return (buf[idx]);
622
0
      }
623
0
      any = 1;
624
0
      for (; (c = *bits) > 32; bits++) {
625
0
        buf[idx][j++] = tolower((unsigned char)c);
626
0
        if (j >= sizeof(buf[idx]))
627
0
          return (buf[idx]);
628
0
      }
629
0
    } else
630
0
      for (; *bits > 32; bits++)
631
0
        ;
632
0
  }
633
634
0
  return (buf[idx]);
635
0
}
636
637
uint8_t
638
mask2prefixlen(struct sockaddr *sa)
639
0
{
640
0
  struct sockaddr_in  *sa_in = (struct sockaddr_in *)sa;
641
0
  in_addr_t    ina = sa_in->sin_addr.s_addr;
642
643
0
  if (ina == 0)
644
0
    return (0);
645
0
  else
646
0
    return (33 - ffs(ntohl(ina)));
647
0
}
648
649
uint8_t
650
mask2prefixlen6(struct sockaddr *sa)
651
0
{
652
0
  struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
653
0
  uint8_t     *ap, *ep;
654
0
  unsigned int     l = 0;
655
656
  /*
657
   * sin6_len is the size of the sockaddr so substract the offset of
658
   * the possibly truncated sin6_addr struct.
659
   */
660
0
  ap = (uint8_t *)&sa_in6->sin6_addr;
661
0
  ep = (uint8_t *)sa_in6 + SA_LEN(sa);
662
0
  for (; ap < ep; ap++) {
663
    /* this "beauty" is adopted from sbin/route/show.c ... */
664
0
    switch (*ap) {
665
0
    case 0xff:
666
0
      l += 8;
667
0
      break;
668
0
    case 0xfe:
669
0
      l += 7;
670
0
      goto done;
671
0
    case 0xfc:
672
0
      l += 6;
673
0
      goto done;
674
0
    case 0xf8:
675
0
      l += 5;
676
0
      goto done;
677
0
    case 0xf0:
678
0
      l += 4;
679
0
      goto done;
680
0
    case 0xe0:
681
0
      l += 3;
682
0
      goto done;
683
0
    case 0xc0:
684
0
      l += 2;
685
0
      goto done;
686
0
    case 0x80:
687
0
      l += 1;
688
0
      goto done;
689
0
    case 0x00:
690
0
      goto done;
691
0
    default:
692
0
      fatalx("non contiguous inet6 netmask");
693
0
    }
694
0
  }
695
696
0
done:
697
0
  if (l > sizeof(struct in6_addr) * 8)
698
0
    fatalx("%s: prefixlen %d out of bound", __func__, l);
699
0
  return (l);
700
0
}
701
702
uint32_t
703
prefixlen2mask(uint8_t prefixlen)
704
0
{
705
0
  if (prefixlen == 0)
706
0
    return (0);
707
708
0
  if (prefixlen > 32)
709
0
    prefixlen = 32;
710
711
0
  return (htonl(0xffffffff << (32 - prefixlen)));
712
0
}
713
714
struct in6_addr *
715
prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
716
0
{
717
0
  static struct in6_addr  s6;
718
0
  int     i;
719
720
0
  if (prefixlen > 128)
721
0
    prefixlen = 128;
722
723
0
  bzero(&s6, sizeof(s6));
724
0
  for (i = 0; i < prefixlen / 8; i++)
725
0
    s6.s6_addr[i] = 0xff;
726
0
  i = prefixlen % 8;
727
0
  if (i)
728
0
    s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
729
730
0
  memcpy(mask, &s6, sizeof(s6));
731
732
0
  return (&s6);
733
0
}
734
735
const char *
736
print_addr(void *addr)
737
14.2k
{
738
14.2k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
14.2k
  static int   idx;
740
14.2k
  struct sockaddr *sa = addr;
741
14.2k
  char    *buf;
742
14.2k
  size_t     len;
743
14.2k
  char     pbuf[7];
744
14.2k
  in_port_t  port;
745
746
14.2k
  buf = sbuf[idx];
747
14.2k
  len = sizeof(sbuf[idx]);
748
14.2k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.78k
    idx = 0;
750
751
14.2k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
14.2k
  if (getnameinfo(sa, SA_LEN(sa),
757
14.2k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
14.2k
  if ((port = socket_getport(sa)) != 0) {
763
0
    snprintf(pbuf, sizeof(pbuf), ":%d", port);
764
0
    (void)strlcat(buf, pbuf, len);
765
0
  }
766
767
14.2k
  return (buf);
768
14.2k
}
769
770
char *
771
get_string(uint8_t *ptr, size_t len)
772
0
{
773
0
  size_t   i;
774
775
0
  for (i = 0; i < len; i++)
776
0
    if (!isprint(ptr[i]))
777
0
      break;
778
779
0
  return strndup(ptr, i);
780
0
}
781
782
const char *
783
print_proto(uint8_t proto)
784
0
{
785
0
  struct protoent *p;
786
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
787
0
  static int   idx = 0;
788
789
0
  if (idx >= IKED_CYCLE_BUFFERS)
790
0
    idx = 0;
791
792
0
  if ((p = getprotobynumber(proto)) != NULL)
793
0
    strlcpy(buf[idx], p->p_name, sizeof(buf[idx]));
794
0
  else
795
0
    snprintf(buf[idx], sizeof(buf), "%u", proto);
796
797
798
0
  return (buf[idx++]);
799
0
}
800
801
int
802
expand_string(char *label, size_t len, const char *srch, const char *repl)
803
0
{
804
0
  char *tmp;
805
0
  char *p, *q;
806
807
0
  if ((tmp = calloc(1, len)) == NULL) {
808
0
    log_debug("%s: calloc", __func__);
809
0
    return (-1);
810
0
  }
811
0
  p = label;
812
0
  while ((q = strstr(p, srch)) != NULL) {
813
0
    *q = '\0';
814
0
    if ((strlcat(tmp, p, len) >= len) ||
815
0
        (strlcat(tmp, repl, len) >= len)) {
816
0
      log_debug("%s: string too long", __func__);
817
0
      free(tmp);
818
0
      return (-1);
819
0
    }
820
0
    q += strlen(srch);
821
0
    p = q;
822
0
  }
823
0
  if (strlcat(tmp, p, len) >= len) {
824
0
    log_debug("%s: string too long", __func__);
825
0
    free(tmp);
826
0
    return (-1);
827
0
  }
828
0
  strlcpy(label, tmp, len); /* always fits */
829
0
  free(tmp);
830
831
0
  return (0);
832
0
}
833
834
uint8_t *
835
string2unicode(const char *ascii, size_t *outlen)
836
0
{
837
0
  uint8_t   *uc = NULL;
838
0
  size_t     i, len = strlen(ascii);
839
840
0
  if ((uc = calloc(1, (len * 2) + 2)) == NULL)
841
0
    return (NULL);
842
843
0
  for (i = 0; i < len; i++) {
844
    /* XXX what about the byte order? */
845
0
    uc[i * 2] = ascii[i];
846
0
  }
847
0
  *outlen = len * 2;
848
849
0
  return (uc);
850
0
}
851
852
void
853
print_debug(const char *emsg, ...)
854
0
{
855
0
  va_list  ap;
856
857
0
  if (log_getverbose() > 2) {
858
0
    va_start(ap, emsg);
859
0
    vfprintf(stderr, emsg, ap);
860
0
    va_end(ap);
861
0
  }
862
0
}
863
864
void
865
print_verbose(const char *emsg, ...)
866
0
{
867
0
  va_list  ap;
868
869
0
  if (log_getverbose()) {
870
0
    va_start(ap, emsg);
871
0
    vfprintf(stderr, emsg, ap);
872
0
    va_end(ap);
873
0
  }
874
0
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html b/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html index 3fdd8218f..29b24d4ee 100644 --- a/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/regress/parser-libfuzzer/common.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: common.c,v 1.9 2020/11/26 22:29:32 tobhe Exp $ */
2
/*
3
 * A bunch of stub functions so we can compile and link ikev2_pld.c
4
 * in a standalone program for testing purposes.
5
 *
6
 * Placed in the public domain
7
 */
8
9
#include <sys/socket.h>
10
#include <sys/time.h>
11
#include <sys/uio.h>
12
13
#include <event.h>
14
#include <limits.h>
15
16
#include "iked.h"
17
#include "types.h"
18
19
197k
#define IKEV2_FLAG_INITIATOR            0x08    /* Sent by the initiator */
20
21
int  eap_parse(struct iked *, const struct iked_sa *,
22
      struct iked_message *, void *, int);
23
int  ikev2_msg_frompeer(struct iked_message *);
24
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
25
      u_int8_t, u_int8_t, int);
26
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
27
struct iked_childsa *
28
   childsa_lookup(struct iked_sa *, u_int64_t, u_int8_t);
29
int   ikev2_childsa_delete(struct iked *, struct iked_sa *,
30
      u_int8_t, u_int64_t, u_int64_t *, int);
31
int  sa_stateok(const struct iked_sa *, int);
32
void   sa_state(struct iked *, struct iked_sa *, int);
33
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
34
void   ikev2_init_ike_sa(struct iked *, void *);
35
struct dh_group *
36
   group_get(u_int32_t);
37
void   timer_set(struct iked *, struct iked_timer *,
38
       void (*)(struct iked *, void *), void *);
39
void   timer_add(struct iked *, struct iked_timer *, int);
40
void   timer_del(struct iked *, struct iked_timer *);
41
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
42
       void *, size_t, u_int, int);
43
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
44
       u_int8_t, u_int8_t, u_int8_t *, size_t, enum privsep_procid);
45
int  ikev2_print_id(struct iked_id *, char *, size_t);
46
int  config_add_transform(struct iked_proposal *, u_int, u_int, u_int,
47
       u_int);
48
struct iked_proposal *
49
   config_add_proposal(struct iked_proposals *, u_int, u_int);
50
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
51
int  ikev2_send_informational(struct iked *, struct iked_message *);
52
struct ibuf *
53
   ikev2_msg_decrypt(struct iked *, struct iked_sa *, struct ibuf *,
54
       struct ibuf *);
55
void ikev2_msg_cleanup(struct iked *, struct iked_message *);
56
57
int
58
eap_parse(struct iked *env, const struct iked_sa *sa, struct iked_message *msg,
59
    void *data, int response)
60
3.20k
{
61
3.20k
  return (0);
62
3.20k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
197k
{
68
197k
  struct iked_sa    *sa = msg->msg_sa;
69
197k
  struct ike_header *hdr;
70
71
197k
  msg = msg->msg_parent;
72
73
197k
  if (sa == NULL ||
74
197k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
197k
  if (!sa->sa_hdr.sh_initiator &&
78
197k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
55.2k
    return (1);
80
142k
  else if (sa->sa_hdr.sh_initiator &&
81
142k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
142k
  return (0);
85
197k
}
86
87
int
88
ikev2_send_ike_e(struct iked *env, struct iked_sa *sa, struct ibuf *buf,
89
    u_int8_t firstpayload, u_int8_t exchange, int response)
90
0
{
91
0
  return (0);
92
0
}
93
94
void
95
ikev2_ikesa_recv_delete(struct iked *env, struct iked_sa *sa)
96
0
{
97
0
}
98
99
const char *
100
ikev2_ikesa_info(uint64_t spi, const char *msg)
101
7.69k
{
102
7.69k
  return "";
103
7.69k
}
104
105
struct iked_childsa *
106
childsa_lookup(struct iked_sa *a, u_int64_t b, u_int8_t c)
107
0
{
108
0
  return (NULL);
109
0
}
110
111
int
112
ikev2_childsa_delete(struct iked *a, struct iked_sa *b, u_int8_t c,
113
    u_int64_t d, u_int64_t *e , int f)
114
0
{
115
0
  return (0);
116
0
}
117
118
int
119
sa_stateok(const struct iked_sa *a, int b)
120
141
{
121
141
  return (0);
122
141
}
123
124
void
125
sa_state(struct iked * a, struct iked_sa *b, int c)
126
0
{
127
0
}
128
129
void
130
ikev2_disable_rekeying(struct iked *a, struct iked_sa *b)
131
0
{
132
0
}
133
134
void
135
ikev2_init_ike_sa(struct iked *a, void *b)
136
0
{
137
0
}
138
139
const struct group_id *
140
group_getid(u_int32_t id)
141
0
{
142
0
  return (NULL);
143
0
}
144
145
void
146
timer_set(struct iked *env, struct iked_timer *tmr,
147
    void (*cb)(struct iked *, void *), void *arg)
148
0
{
149
0
}
150
151
void
152
timer_add(struct iked *env, struct iked_timer *tmr, int timeout)
153
0
{
154
0
}
155
156
void
157
timer_del(struct iked *env, struct iked_timer *tmr)
158
0
{
159
0
}
160
161
ssize_t
162
ikev2_nat_detection(struct iked *env, struct iked_message *msg,
163
    void *ptr, size_t len, u_int type, int frompeer)
164
22.6k
{
165
22.6k
  return (0);
166
22.6k
}
167
168
int
169
ca_setreq(struct iked *env, struct iked_sa *sh, struct iked_static_id *localid,
170
    u_int8_t type, u_int8_t more, u_int8_t *data, size_t len,
171
    enum privsep_procid procid)
172
0
{
173
0
  return (0);
174
0
}
175
176
int
177
ikev2_print_id(struct iked_id *id, char *idstr, size_t idstrlen)
178
5.38k
{
179
5.38k
  return (0);
180
5.38k
}
181
182
int
183
config_add_transform(struct iked_proposal *prop, u_int type,
184
    u_int id, u_int length, u_int keylength)
185
0
{
186
0
  return (0);
187
0
}
188
189
struct iked_proposal *
190
config_add_proposal(struct iked_proposals *head, u_int id, u_int proto)
191
69
{
192
69
  return (NULL);
193
69
}
194
195
void
196
config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
197
0
{
198
0
  return;
199
0
}
200
201
void config_free_fragments(struct iked_frag *frag)
202
0
{
203
0
  return;
204
0
}
205
206
int
207
ikev2_send_informational(struct iked *env, struct iked_message *msg)
208
722
{
209
722
  return (0);
210
722
}
211
212
struct ibuf *
213
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
214
    struct ibuf *msg, struct ibuf *src)
215
0
{
216
0
  if (src == NULL){
217
0
                fprintf(stderr, "%s\n", "msg_decrypt: src == NULL!");
218
0
                exit(-1);
219
0
        }
220
221
  /*
222
   * Free src as caller uses ikev2_msg_decrypt() like this:
223
   * src = ikev2_msg_decrypt(..., src);
224
   */
225
0
  ibuf_free(src); 
226
0
  return (NULL);
227
0
}
228
229
void
230
ikev2_ike_sa_setreason(struct iked_sa *sa, char *r)
231
0
{
232
0
}
233
234
void
235
ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue,
236
    struct iked_msg_retransmit *mr)
237
0
{
238
0
}
239
240
struct iked_msg_retransmit *
241
ikev2_msg_lookup(struct iked *env, struct iked_msgqueue *queue,
242
    struct iked_message *msg, uint8_t exchange)
243
0
{
244
0
  return NULL;
245
0
}
246
247
/* copied from ikev2_msg.c */
248
void
249
ikev2_msg_cleanup(struct iked *env, struct iked_message *msg)
250
13.0k
{
251
13.0k
  struct iked_certreq *cr;
252
13.0k
  struct iked_proposal *prop, *proptmp;
253
13.0k
  int      i;
254
255
13.0k
  if (msg == msg->msg_parent) {
256
13.0k
    ibuf_free(msg->msg_nonce);
257
13.0k
    ibuf_free(msg->msg_ke);
258
13.0k
    ibuf_free(msg->msg_auth.id_buf);
259
13.0k
    ibuf_free(msg->msg_peerid.id_buf);
260
13.0k
    ibuf_free(msg->msg_localid.id_buf);
261
13.0k
    ibuf_free(msg->msg_cert.id_buf);
262
52.1k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
39.1k
      ibuf_free(msg->msg_scert[i].id_buf);
264
13.0k
    ibuf_free(msg->msg_cookie);
265
13.0k
    ibuf_free(msg->msg_cookie2);
266
13.0k
    ibuf_free(msg->msg_del_buf);
267
13.0k
    free(msg->msg_eap.eam_user);
268
13.0k
    free(msg->msg_cp_addr);
269
13.0k
    free(msg->msg_cp_addr6);
270
13.0k
    free(msg->msg_cp_dns);
271
272
13.0k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
13.0k
        proptmp) {
274
0
      TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry);
275
0
      if (prop->prop_nxforms)
276
0
        free(prop->prop_xforms);
277
0
      free(prop);
278
0
    }
279
280
13.0k
    msg->msg_nonce = NULL;
281
13.0k
    msg->msg_ke = NULL;
282
13.0k
    msg->msg_auth.id_buf = NULL;
283
13.0k
    msg->msg_peerid.id_buf = NULL;
284
13.0k
    msg->msg_localid.id_buf = NULL;
285
13.0k
    msg->msg_cert.id_buf = NULL;
286
52.1k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
39.1k
      msg->msg_scert[i].id_buf = NULL;
288
13.0k
    msg->msg_cookie = NULL;
289
13.0k
    msg->msg_cookie2 = NULL;
290
13.0k
    msg->msg_del_buf = NULL;
291
13.0k
    msg->msg_eap.eam_user = NULL;
292
13.0k
    msg->msg_cp_addr = NULL;
293
13.0k
    msg->msg_cp_addr6 = NULL;
294
13.0k
    msg->msg_cp_dns = NULL;
295
296
13.9k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
897
      ibuf_free(cr->cr_data);
298
897
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
897
      free(cr);
300
897
    }
301
13.0k
  }
302
303
13.0k
  if (msg->msg_data != NULL) {
304
13.0k
    ibuf_free(msg->msg_data);
305
13.0k
    msg->msg_data = NULL;
306
13.0k
  }
307
13.0k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/regress/parser-libfuzzer/common.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: common.c,v 1.9 2020/11/26 22:29:32 tobhe Exp $ */
2
/*
3
 * A bunch of stub functions so we can compile and link ikev2_pld.c
4
 * in a standalone program for testing purposes.
5
 *
6
 * Placed in the public domain
7
 */
8
9
#include <sys/socket.h>
10
#include <sys/time.h>
11
#include <sys/uio.h>
12
13
#include <event.h>
14
#include <limits.h>
15
16
#include "iked.h"
17
#include "types.h"
18
19
198k
#define IKEV2_FLAG_INITIATOR            0x08    /* Sent by the initiator */
20
21
int  eap_parse(struct iked *, const struct iked_sa *,
22
      struct iked_message *, void *, int);
23
int  ikev2_msg_frompeer(struct iked_message *);
24
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
25
      u_int8_t, u_int8_t, int);
26
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
27
struct iked_childsa *
28
   childsa_lookup(struct iked_sa *, u_int64_t, u_int8_t);
29
int   ikev2_childsa_delete(struct iked *, struct iked_sa *,
30
      u_int8_t, u_int64_t, u_int64_t *, int);
31
int  sa_stateok(const struct iked_sa *, int);
32
void   sa_state(struct iked *, struct iked_sa *, int);
33
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
34
void   ikev2_init_ike_sa(struct iked *, void *);
35
struct dh_group *
36
   group_get(u_int32_t);
37
void   timer_set(struct iked *, struct iked_timer *,
38
       void (*)(struct iked *, void *), void *);
39
void   timer_add(struct iked *, struct iked_timer *, int);
40
void   timer_del(struct iked *, struct iked_timer *);
41
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
42
       void *, size_t, u_int, int);
43
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
44
       u_int8_t, u_int8_t, u_int8_t *, size_t, enum privsep_procid);
45
int  ikev2_print_id(struct iked_id *, char *, size_t);
46
int  config_add_transform(struct iked_proposal *, u_int, u_int, u_int,
47
       u_int);
48
struct iked_proposal *
49
   config_add_proposal(struct iked_proposals *, u_int, u_int);
50
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
51
int  ikev2_send_informational(struct iked *, struct iked_message *);
52
struct ibuf *
53
   ikev2_msg_decrypt(struct iked *, struct iked_sa *, struct ibuf *,
54
       struct ibuf *);
55
void ikev2_msg_cleanup(struct iked *, struct iked_message *);
56
57
int
58
eap_parse(struct iked *env, const struct iked_sa *sa, struct iked_message *msg,
59
    void *data, int response)
60
3.20k
{
61
3.20k
  return (0);
62
3.20k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
198k
{
68
198k
  struct iked_sa    *sa = msg->msg_sa;
69
198k
  struct ike_header *hdr;
70
71
198k
  msg = msg->msg_parent;
72
73
198k
  if (sa == NULL ||
74
198k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
198k
  if (!sa->sa_hdr.sh_initiator &&
78
198k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
55.9k
    return (1);
80
142k
  else if (sa->sa_hdr.sh_initiator &&
81
142k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
142k
  return (0);
85
198k
}
86
87
int
88
ikev2_send_ike_e(struct iked *env, struct iked_sa *sa, struct ibuf *buf,
89
    u_int8_t firstpayload, u_int8_t exchange, int response)
90
0
{
91
0
  return (0);
92
0
}
93
94
void
95
ikev2_ikesa_recv_delete(struct iked *env, struct iked_sa *sa)
96
0
{
97
0
}
98
99
const char *
100
ikev2_ikesa_info(uint64_t spi, const char *msg)
101
7.69k
{
102
7.69k
  return "";
103
7.69k
}
104
105
struct iked_childsa *
106
childsa_lookup(struct iked_sa *a, u_int64_t b, u_int8_t c)
107
0
{
108
0
  return (NULL);
109
0
}
110
111
int
112
ikev2_childsa_delete(struct iked *a, struct iked_sa *b, u_int8_t c,
113
    u_int64_t d, u_int64_t *e , int f)
114
0
{
115
0
  return (0);
116
0
}
117
118
int
119
sa_stateok(const struct iked_sa *a, int b)
120
141
{
121
141
  return (0);
122
141
}
123
124
void
125
sa_state(struct iked * a, struct iked_sa *b, int c)
126
0
{
127
0
}
128
129
void
130
ikev2_disable_rekeying(struct iked *a, struct iked_sa *b)
131
0
{
132
0
}
133
134
void
135
ikev2_init_ike_sa(struct iked *a, void *b)
136
0
{
137
0
}
138
139
const struct group_id *
140
group_getid(u_int32_t id)
141
0
{
142
0
  return (NULL);
143
0
}
144
145
void
146
timer_set(struct iked *env, struct iked_timer *tmr,
147
    void (*cb)(struct iked *, void *), void *arg)
148
0
{
149
0
}
150
151
void
152
timer_add(struct iked *env, struct iked_timer *tmr, int timeout)
153
0
{
154
0
}
155
156
void
157
timer_del(struct iked *env, struct iked_timer *tmr)
158
0
{
159
0
}
160
161
ssize_t
162
ikev2_nat_detection(struct iked *env, struct iked_message *msg,
163
    void *ptr, size_t len, u_int type, int frompeer)
164
22.9k
{
165
22.9k
  return (0);
166
22.9k
}
167
168
int
169
ca_setreq(struct iked *env, struct iked_sa *sh, struct iked_static_id *localid,
170
    u_int8_t type, u_int8_t more, u_int8_t *data, size_t len,
171
    enum privsep_procid procid)
172
0
{
173
0
  return (0);
174
0
}
175
176
int
177
ikev2_print_id(struct iked_id *id, char *idstr, size_t idstrlen)
178
5.38k
{
179
5.38k
  return (0);
180
5.38k
}
181
182
int
183
config_add_transform(struct iked_proposal *prop, u_int type,
184
    u_int id, u_int length, u_int keylength)
185
0
{
186
0
  return (0);
187
0
}
188
189
struct iked_proposal *
190
config_add_proposal(struct iked_proposals *head, u_int id, u_int proto)
191
69
{
192
69
  return (NULL);
193
69
}
194
195
void
196
config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
197
0
{
198
0
  return;
199
0
}
200
201
void config_free_fragments(struct iked_frag *frag)
202
0
{
203
0
  return;
204
0
}
205
206
int
207
ikev2_send_informational(struct iked *env, struct iked_message *msg)
208
723
{
209
723
  return (0);
210
723
}
211
212
struct ibuf *
213
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
214
    struct ibuf *msg, struct ibuf *src)
215
0
{
216
0
  if (src == NULL){
217
0
                fprintf(stderr, "%s\n", "msg_decrypt: src == NULL!");
218
0
                exit(-1);
219
0
        }
220
221
  /*
222
   * Free src as caller uses ikev2_msg_decrypt() like this:
223
   * src = ikev2_msg_decrypt(..., src);
224
   */
225
0
  ibuf_free(src); 
226
0
  return (NULL);
227
0
}
228
229
void
230
ikev2_ike_sa_setreason(struct iked_sa *sa, char *r)
231
0
{
232
0
}
233
234
void
235
ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue,
236
    struct iked_msg_retransmit *mr)
237
0
{
238
0
}
239
240
struct iked_msg_retransmit *
241
ikev2_msg_lookup(struct iked *env, struct iked_msgqueue *queue,
242
    struct iked_message *msg, uint8_t exchange)
243
0
{
244
0
  return NULL;
245
0
}
246
247
/* copied from ikev2_msg.c */
248
void
249
ikev2_msg_cleanup(struct iked *env, struct iked_message *msg)
250
13.1k
{
251
13.1k
  struct iked_certreq *cr;
252
13.1k
  struct iked_proposal *prop, *proptmp;
253
13.1k
  int      i;
254
255
13.1k
  if (msg == msg->msg_parent) {
256
13.1k
    ibuf_free(msg->msg_nonce);
257
13.1k
    ibuf_free(msg->msg_ke);
258
13.1k
    ibuf_free(msg->msg_auth.id_buf);
259
13.1k
    ibuf_free(msg->msg_peerid.id_buf);
260
13.1k
    ibuf_free(msg->msg_localid.id_buf);
261
13.1k
    ibuf_free(msg->msg_cert.id_buf);
262
52.7k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
39.5k
      ibuf_free(msg->msg_scert[i].id_buf);
264
13.1k
    ibuf_free(msg->msg_cookie);
265
13.1k
    ibuf_free(msg->msg_cookie2);
266
13.1k
    ibuf_free(msg->msg_del_buf);
267
13.1k
    free(msg->msg_eap.eam_user);
268
13.1k
    free(msg->msg_cp_addr);
269
13.1k
    free(msg->msg_cp_addr6);
270
13.1k
    free(msg->msg_cp_dns);
271
272
13.1k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
13.1k
        proptmp) {
274
0
      TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry);
275
0
      if (prop->prop_nxforms)
276
0
        free(prop->prop_xforms);
277
0
      free(prop);
278
0
    }
279
280
13.1k
    msg->msg_nonce = NULL;
281
13.1k
    msg->msg_ke = NULL;
282
13.1k
    msg->msg_auth.id_buf = NULL;
283
13.1k
    msg->msg_peerid.id_buf = NULL;
284
13.1k
    msg->msg_localid.id_buf = NULL;
285
13.1k
    msg->msg_cert.id_buf = NULL;
286
52.7k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
39.5k
      msg->msg_scert[i].id_buf = NULL;
288
13.1k
    msg->msg_cookie = NULL;
289
13.1k
    msg->msg_cookie2 = NULL;
290
13.1k
    msg->msg_del_buf = NULL;
291
13.1k
    msg->msg_eap.eam_user = NULL;
292
13.1k
    msg->msg_cp_addr = NULL;
293
13.1k
    msg->msg_cp_addr6 = NULL;
294
13.1k
    msg->msg_cp_dns = NULL;
295
296
14.0k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
897
      ibuf_free(cr->cr_data);
298
897
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
897
      free(cr);
300
897
    }
301
13.1k
  }
302
303
13.1k
  if (msg->msg_data != NULL) {
304
13.1k
    ibuf_free(msg->msg_data);
305
13.1k
    msg->msg_data = NULL;
306
13.1k
  }
307
13.1k
}
\ No newline at end of file diff --git a/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html b/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html index 2eae6ac97..4ac711c5d 100644 --- a/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html +++ b/coverage/latest/report/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD$ */
2
/*
3
 * Fuzz tests for payload parsing
4
 *
5
 * Placed in the public domain
6
 */
7
8
#include <sys/socket.h>
9
#include <sys/queue.h>
10
#include <sys/uio.h>
11
12
#include <event.h>
13
#include <imsg.h>
14
#include <string.h>
15
16
#include "iked.h"
17
#include "ikev2.h"
18
19
u_int8_t cookies[] = {
20
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x01, /* initator cookie */
21
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* responder cookie */
22
};
23
24
u_int8_t genhdr[] = {
25
  0x00, 0x20, 0x22, 0x08, /* next, major/minor, exchange type, flags */
26
  0x00, 0x00, 0x00, 0x00, /* message ID */
27
  0x00, 0x00, 0x00, 0x00  /* total length */
28
};
29
30
13.0k
#define OFFSET_ICOOKIE    0
31
13.0k
#define OFFSET_RCOOKIE    8
32
13.0k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
13.0k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
13.0k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
13.0k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
13.0k
{
40
13.0k
  return &data[OFFSET_ICOOKIE];
41
13.0k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
13.0k
{
46
13.0k
  return &data[OFFSET_RCOOKIE];
47
13.0k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
13.0k
{
52
13.0k
  return data[OFFSET_NEXTPAYLOAD];
53
13.0k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
13.0k
{
58
13.0k
  return data[OFFSET_VERSION];
59
13.0k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
13.0k
{
64
13.0k
  return data[OFFSET_EXCHANGE];
65
13.0k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
13.0k
{
70
13.0k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
13.0k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
13.0k
{
76
13.0k
  bzero(hdr, sizeof(*hdr));
77
13.0k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
13.0k
      sizeof(hdr->ike_ispi));
79
13.0k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
13.0k
      sizeof(hdr->ike_rspi));
81
13.0k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
13.0k
  hdr->ike_version = get_version(ibuf_data(data));
83
13.0k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
13.0k
  hdr->ike_length = get_length(ibuf_data(data));
85
13.0k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
13.0k
{
90
13.0k
  static struct iked_sa sa;
91
92
13.0k
  bzero(&sa, sizeof(sa));
93
13.0k
  bzero(msg, sizeof(*msg));
94
95
13.0k
  msg->msg_sa = &sa;
96
13.0k
  msg->msg_data = data;
97
13.0k
  msg->msg_e = 1;
98
13.0k
  msg->msg_parent = msg;
99
100
13.0k
  TAILQ_INIT(&msg->msg_proposals);
101
13.0k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
13.0k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
13.0k
{
108
13.0k
  struct ibuf   *fuzzed;
109
13.0k
  struct ike_header  hdr;
110
13.0k
  struct iked_message  msg;
111
112
13.0k
  bzero(&hdr, sizeof(hdr));
113
13.0k
  bzero(&msg, sizeof(msg));
114
115
13.0k
  fuzzed = ibuf_new(data, size);
116
13.0k
  if (fuzzed == NULL){
117
0
    fprintf(stderr, "%s\n", "ERROR: fuzzed == NULL! "
118
0
        "(hint: fuzz-input too long?)");
119
0
    return -1;
120
0
  }  
121
  
122
  /* size too small? */
123
13.0k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
13.0k
  prepare_header(&hdr, fuzzed);
129
13.0k
  prepare_message(&msg, fuzzed);
130
131
13.0k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
13.0k
  ikev2_msg_cleanup(NULL, &msg);
134
135
13.0k
  return 0;
136
13.0k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD$ */
2
/*
3
 * Fuzz tests for payload parsing
4
 *
5
 * Placed in the public domain
6
 */
7
8
#include <sys/socket.h>
9
#include <sys/queue.h>
10
#include <sys/uio.h>
11
12
#include <event.h>
13
#include <imsg.h>
14
#include <string.h>
15
16
#include "iked.h"
17
#include "ikev2.h"
18
19
u_int8_t cookies[] = {
20
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x01, /* initator cookie */
21
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* responder cookie */
22
};
23
24
u_int8_t genhdr[] = {
25
  0x00, 0x20, 0x22, 0x08, /* next, major/minor, exchange type, flags */
26
  0x00, 0x00, 0x00, 0x00, /* message ID */
27
  0x00, 0x00, 0x00, 0x00  /* total length */
28
};
29
30
13.1k
#define OFFSET_ICOOKIE    0
31
13.1k
#define OFFSET_RCOOKIE    8
32
13.1k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
13.1k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
13.1k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
13.1k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
13.1k
{
40
13.1k
  return &data[OFFSET_ICOOKIE];
41
13.1k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
13.1k
{
46
13.1k
  return &data[OFFSET_RCOOKIE];
47
13.1k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
13.1k
{
52
13.1k
  return data[OFFSET_NEXTPAYLOAD];
53
13.1k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
13.1k
{
58
13.1k
  return data[OFFSET_VERSION];
59
13.1k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
13.1k
{
64
13.1k
  return data[OFFSET_EXCHANGE];
65
13.1k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
13.1k
{
70
13.1k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
13.1k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
13.1k
{
76
13.1k
  bzero(hdr, sizeof(*hdr));
77
13.1k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
13.1k
      sizeof(hdr->ike_ispi));
79
13.1k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
13.1k
      sizeof(hdr->ike_rspi));
81
13.1k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
13.1k
  hdr->ike_version = get_version(ibuf_data(data));
83
13.1k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
13.1k
  hdr->ike_length = get_length(ibuf_data(data));
85
13.1k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
13.1k
{
90
13.1k
  static struct iked_sa sa;
91
92
13.1k
  bzero(&sa, sizeof(sa));
93
13.1k
  bzero(msg, sizeof(*msg));
94
95
13.1k
  msg->msg_sa = &sa;
96
13.1k
  msg->msg_data = data;
97
13.1k
  msg->msg_e = 1;
98
13.1k
  msg->msg_parent = msg;
99
100
13.1k
  TAILQ_INIT(&msg->msg_proposals);
101
13.1k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
13.1k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
13.1k
{
108
13.1k
  struct ibuf   *fuzzed;
109
13.1k
  struct ike_header  hdr;
110
13.1k
  struct iked_message  msg;
111
112
13.1k
  bzero(&hdr, sizeof(hdr));
113
13.1k
  bzero(&msg, sizeof(msg));
114
115
13.1k
  fuzzed = ibuf_new(data, size);
116
13.1k
  if (fuzzed == NULL){
117
0
    fprintf(stderr, "%s\n", "ERROR: fuzzed == NULL! "
118
0
        "(hint: fuzz-input too long?)");
119
0
    return -1;
120
0
  }  
121
  
122
  /* size too small? */
123
13.1k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
13.1k
  prepare_header(&hdr, fuzzed);
129
13.1k
  prepare_message(&msg, fuzzed);
130
131
13.1k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
13.1k
  ikev2_msg_cleanup(NULL, &msg);
134
135
13.1k
  return 0;
136
13.1k
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random.c.html index ceee6fda5..4b868881e 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * ChaCha based random number generator for OpenBSD.
24
 */
25
26
#include <fcntl.h>
27
#include <limits.h>
28
#include <signal.h>
29
#include <stdint.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
#include <sys/types.h>
34
#include <sys/time.h>
35
36
#define KEYSTREAM_ONLY
37
#include "chacha_private.h"
38
39
0
#define minimum(a, b) ((a) < (b) ? (a) : (b))
40
41
#if defined(__GNUC__) || defined(_MSC_VER)
42
#define inline __inline
43
#else       /* __GNUC__ || _MSC_VER */
44
#define inline
45
#endif        /* !__GNUC__ && !_MSC_VER */
46
47
0
#define KEYSZ 32
48
0
#define IVSZ  8
49
#define BLOCKSZ 64
50
#define RSBUFSZ (16*BLOCKSZ)
51
52
0
#define REKEY_BASE  (1024*1024) /* NB. should be a power of 2 */
53
54
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
55
static struct _rs {
56
  size_t    rs_have;  /* valid bytes at end of rs_buf */
57
  size_t    rs_count; /* bytes till reseed */
58
} *rs;
59
60
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
61
static struct _rsx {
62
  chacha_ctx  rs_chacha;  /* chacha context for random keystream */
63
  u_char    rs_buf[RSBUFSZ];  /* keystream blocks */
64
} *rsx;
65
66
static inline int _rs_allocate(struct _rs **, struct _rsx **);
67
static inline void _rs_forkdetect(void);
68
#include "arc4random.h"
69
70
static inline void _rs_rekey(u_char *dat, size_t datlen);
71
72
static inline void
73
_rs_init(u_char *buf, size_t n)
74
0
{
75
0
  if (n < KEYSZ + IVSZ)
76
0
    return;
77
78
0
  if (rs == NULL) {
79
0
    if (_rs_allocate(&rs, &rsx) == -1)
80
0
      _exit(1);
81
0
  }
82
83
0
  chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
84
0
  chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
85
0
}
86
87
static void
88
_rs_stir(void)
89
0
{
90
0
  u_char rnd[KEYSZ + IVSZ];
91
0
  uint32_t rekey_fuzz = 0;
92
93
0
  if (getentropy(rnd, sizeof rnd) == -1)
94
0
    _getentropy_fail();
95
96
0
  if (!rs)
97
0
    _rs_init(rnd, sizeof(rnd));
98
0
  else
99
0
    _rs_rekey(rnd, sizeof(rnd));
100
0
  explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
101
102
  /* invalidate rs_buf */
103
0
  rs->rs_have = 0;
104
0
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
105
106
  /* rekey interval should not be predictable */
107
0
  chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
108
0
      (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
109
0
  rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
110
0
}
111
112
static inline void
113
_rs_stir_if_needed(size_t len)
114
0
{
115
0
  _rs_forkdetect();
116
0
  if (!rs || rs->rs_count <= len)
117
0
    _rs_stir();
118
0
  if (rs->rs_count <= len)
119
0
    rs->rs_count = 0;
120
0
  else
121
0
    rs->rs_count -= len;
122
0
}
123
124
static inline void
125
_rs_rekey(u_char *dat, size_t datlen)
126
0
{
127
#ifndef KEYSTREAM_ONLY
128
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
129
#endif
130
  /* fill rs_buf with the keystream */
131
0
  chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
132
0
      rsx->rs_buf, sizeof(rsx->rs_buf));
133
  /* mix in optional user provided data */
134
0
  if (dat) {
135
0
    size_t i, m;
136
137
0
    m = minimum(datlen, KEYSZ + IVSZ);
138
0
    for (i = 0; i < m; i++)
139
0
      rsx->rs_buf[i] ^= dat[i];
140
0
  }
141
  /* immediately reinit for backtracking resistance */
142
0
  _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
143
0
  memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
144
0
  rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
145
0
}
146
147
static inline void
148
_rs_random_buf(void *_buf, size_t n)
149
0
{
150
0
  u_char *buf = (u_char *)_buf;
151
0
  u_char *keystream;
152
0
  size_t m;
153
154
0
  _rs_stir_if_needed(n);
155
0
  while (n > 0) {
156
0
    if (rs->rs_have > 0) {
157
0
      m = minimum(n, rs->rs_have);
158
0
      keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
159
0
          - rs->rs_have;
160
0
      memcpy(buf, keystream, m);
161
0
      memset(keystream, 0, m);
162
0
      buf += m;
163
0
      n -= m;
164
0
      rs->rs_have -= m;
165
0
    }
166
0
    if (rs->rs_have == 0)
167
0
      _rs_rekey(NULL, 0);
168
0
  }
169
0
}
170
171
static inline void
172
_rs_random_u32(uint32_t *val)
173
0
{
174
0
  u_char *keystream;
175
176
0
  _rs_stir_if_needed(sizeof(*val));
177
0
  if (rs->rs_have < sizeof(*val))
178
0
    _rs_rekey(NULL, 0);
179
0
  keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
180
0
  memcpy(val, keystream, sizeof(*val));
181
0
  memset(keystream, 0, sizeof(*val));
182
0
  rs->rs_have -= sizeof(*val);
183
0
}
184
185
uint32_t
186
arc4random(void)
187
0
{
188
0
  uint32_t val;
189
190
0
  _ARC4_LOCK();
191
0
  _rs_random_u32(&val);
192
0
  _ARC4_UNLOCK();
193
0
  return val;
194
0
}
195
196
void
197
arc4random_buf(void *buf, size_t n)
198
0
{
199
0
  _ARC4_LOCK();
200
0
  _rs_random_buf(buf, n);
201
0
  _ARC4_UNLOCK();
202
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * ChaCha based random number generator for OpenBSD.
24
 */
25
26
#include <fcntl.h>
27
#include <limits.h>
28
#include <signal.h>
29
#include <stdint.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include <unistd.h>
33
#include <sys/types.h>
34
#include <sys/time.h>
35
36
#define KEYSTREAM_ONLY
37
#include "chacha_private.h"
38
39
0
#define minimum(a, b) ((a) < (b) ? (a) : (b))
40
41
#if defined(__GNUC__) || defined(_MSC_VER)
42
#define inline __inline
43
#else       /* __GNUC__ || _MSC_VER */
44
#define inline
45
#endif        /* !__GNUC__ && !_MSC_VER */
46
47
0
#define KEYSZ 32
48
0
#define IVSZ  8
49
#define BLOCKSZ 64
50
#define RSBUFSZ (16*BLOCKSZ)
51
52
0
#define REKEY_BASE  (1024*1024) /* NB. should be a power of 2 */
53
54
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
55
static struct _rs {
56
  size_t    rs_have;  /* valid bytes at end of rs_buf */
57
  size_t    rs_count; /* bytes till reseed */
58
} *rs;
59
60
/* Maybe be preserved in fork children, if _rs_allocate() decides. */
61
static struct _rsx {
62
  chacha_ctx  rs_chacha;  /* chacha context for random keystream */
63
  u_char    rs_buf[RSBUFSZ];  /* keystream blocks */
64
} *rsx;
65
66
static inline int _rs_allocate(struct _rs **, struct _rsx **);
67
static inline void _rs_forkdetect(void);
68
#include "arc4random.h"
69
70
static inline void _rs_rekey(u_char *dat, size_t datlen);
71
72
static inline void
73
_rs_init(u_char *buf, size_t n)
74
0
{
75
0
  if (n < KEYSZ + IVSZ)
76
0
    return;
77
78
0
  if (rs == NULL) {
79
0
    if (_rs_allocate(&rs, &rsx) == -1)
80
0
      _exit(1);
81
0
  }
82
83
0
  chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
84
0
  chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
85
0
}
86
87
static void
88
_rs_stir(void)
89
0
{
90
0
  u_char rnd[KEYSZ + IVSZ];
91
0
  uint32_t rekey_fuzz = 0;
92
93
0
  if (getentropy(rnd, sizeof rnd) == -1)
94
0
    _getentropy_fail();
95
96
0
  if (!rs)
97
0
    _rs_init(rnd, sizeof(rnd));
98
0
  else
99
0
    _rs_rekey(rnd, sizeof(rnd));
100
0
  explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
101
102
  /* invalidate rs_buf */
103
0
  rs->rs_have = 0;
104
0
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
105
106
  /* rekey interval should not be predictable */
107
0
  chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
108
0
      (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
109
0
  rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
110
0
}
111
112
static inline void
113
_rs_stir_if_needed(size_t len)
114
0
{
115
0
  _rs_forkdetect();
116
0
  if (!rs || rs->rs_count <= len)
117
0
    _rs_stir();
118
0
  if (rs->rs_count <= len)
119
0
    rs->rs_count = 0;
120
0
  else
121
0
    rs->rs_count -= len;
122
0
}
123
124
static inline void
125
_rs_rekey(u_char *dat, size_t datlen)
126
0
{
127
#ifndef KEYSTREAM_ONLY
128
  memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
129
#endif
130
  /* fill rs_buf with the keystream */
131
0
  chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
132
0
      rsx->rs_buf, sizeof(rsx->rs_buf));
133
  /* mix in optional user provided data */
134
0
  if (dat) {
135
0
    size_t i, m;
136
137
0
    m = minimum(datlen, KEYSZ + IVSZ);
138
0
    for (i = 0; i < m; i++)
139
0
      rsx->rs_buf[i] ^= dat[i];
140
0
  }
141
  /* immediately reinit for backtracking resistance */
142
0
  _rs_init(rsx->rs_buf, KEYSZ + IVSZ);
143
0
  memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
144
0
  rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
145
0
}
146
147
static inline void
148
_rs_random_buf(void *_buf, size_t n)
149
0
{
150
0
  u_char *buf = (u_char *)_buf;
151
0
  u_char *keystream;
152
0
  size_t m;
153
154
0
  _rs_stir_if_needed(n);
155
0
  while (n > 0) {
156
0
    if (rs->rs_have > 0) {
157
0
      m = minimum(n, rs->rs_have);
158
0
      keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
159
0
          - rs->rs_have;
160
0
      memcpy(buf, keystream, m);
161
0
      memset(keystream, 0, m);
162
0
      buf += m;
163
0
      n -= m;
164
0
      rs->rs_have -= m;
165
0
    }
166
0
    if (rs->rs_have == 0)
167
0
      _rs_rekey(NULL, 0);
168
0
  }
169
0
}
170
171
static inline void
172
_rs_random_u32(uint32_t *val)
173
0
{
174
0
  u_char *keystream;
175
176
0
  _rs_stir_if_needed(sizeof(*val));
177
0
  if (rs->rs_have < sizeof(*val))
178
0
    _rs_rekey(NULL, 0);
179
0
  keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
180
0
  memcpy(val, keystream, sizeof(*val));
181
0
  memset(keystream, 0, sizeof(*val));
182
0
  rs->rs_have -= sizeof(*val);
183
0
}
184
185
uint32_t
186
arc4random(void)
187
0
{
188
0
  uint32_t val;
189
190
0
  _ARC4_LOCK();
191
0
  _rs_random_u32(&val);
192
0
  _ARC4_UNLOCK();
193
0
  return val;
194
0
}
195
196
void
197
arc4random_buf(void *buf, size_t n)
198
0
{
199
0
  _ARC4_LOCK();
200
0
  _rs_random_buf(buf, n);
201
0
  _ARC4_UNLOCK();
202
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_linux.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_linux.h.html index 43600e64f..4b322683b 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_linux.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_linux.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random_linux.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * Stub functions for portability.
24
 */
25
26
#include <sys/mman.h>
27
28
#include <pthread.h>
29
#include <signal.h>
30
31
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
32
0
#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
33
0
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
34
35
#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__))
36
extern void *__dso_handle;
37
extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
38
0
#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
39
#else
40
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
41
#endif
42
43
static inline void
44
_getentropy_fail(void)
45
0
{
46
0
  raise(SIGKILL);
47
0
}
48
49
static volatile sig_atomic_t _rs_forked;
50
51
static inline void
52
_rs_forkhandler(void)
53
0
{
54
0
  _rs_forked = 1;
55
0
}
56
57
static inline void
58
_rs_forkdetect(void)
59
0
{
60
0
  static pid_t _rs_pid = 0;
61
0
  pid_t pid = getpid();
62
63
        /* XXX unusual calls to clone() can bypass checks */
64
0
  if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
65
0
    _rs_pid = pid;
66
0
    _rs_forked = 0;
67
0
    if (rs)
68
0
      memset(rs, 0, sizeof(*rs));
69
0
  }
70
0
}
71
72
static inline int
73
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
74
0
{
75
0
  if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
76
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
77
0
    return (-1);
78
79
0
  if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
80
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
81
0
    munmap(*rsp, sizeof(**rsp));
82
0
    *rsp = NULL;
83
0
    return (-1);
84
0
  }
85
86
0
  _ARC4_ATFORK(_rs_forkhandler);
87
0
  return (0);
88
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random_linux.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $  */
2
3
/*
4
 * Copyright (c) 1996, David Mazieres <dm@uun.org>
5
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
6
 * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
7
 * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
8
 *
9
 * Permission to use, copy, modify, and distribute this software for any
10
 * purpose with or without fee is hereby granted, provided that the above
11
 * copyright notice and this permission notice appear in all copies.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
 */
21
22
/*
23
 * Stub functions for portability.
24
 */
25
26
#include <sys/mman.h>
27
28
#include <pthread.h>
29
#include <signal.h>
30
31
static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
32
0
#define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
33
0
#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
34
35
#if defined(__GLIBC__) && !(defined(__UCLIBC__) && !defined(__ARCH_USE_MMU__))
36
extern void *__dso_handle;
37
extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
38
0
#define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
39
#else
40
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
41
#endif
42
43
static inline void
44
_getentropy_fail(void)
45
0
{
46
0
  raise(SIGKILL);
47
0
}
48
49
static volatile sig_atomic_t _rs_forked;
50
51
static inline void
52
_rs_forkhandler(void)
53
0
{
54
0
  _rs_forked = 1;
55
0
}
56
57
static inline void
58
_rs_forkdetect(void)
59
0
{
60
0
  static pid_t _rs_pid = 0;
61
0
  pid_t pid = getpid();
62
63
        /* XXX unusual calls to clone() can bypass checks */
64
0
  if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) {
65
0
    _rs_pid = pid;
66
0
    _rs_forked = 0;
67
0
    if (rs)
68
0
      memset(rs, 0, sizeof(*rs));
69
0
  }
70
0
}
71
72
static inline int
73
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
74
0
{
75
0
  if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE,
76
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
77
0
    return (-1);
78
79
0
  if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE,
80
0
      MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
81
0
    munmap(*rsp, sizeof(**rsp));
82
0
    *rsp = NULL;
83
0
    return (-1);
84
0
  }
85
86
0
  _ARC4_ATFORK(_rs_forkhandler);
87
0
  return (0);
88
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_uniform.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_uniform.c.html index f9faf3081..56708c160 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_uniform.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/arc4random_uniform.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/arc4random_uniform.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $  */
2
3
/*
4
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdint.h>
20
#include <stdlib.h>
21
22
/*
23
 * Calculate a uniformly distributed random number less than upper_bound
24
 * avoiding "modulo bias".
25
 *
26
 * Uniformity is achieved by generating new random numbers until the one
27
 * returned is outside the range [0, 2**32 % upper_bound).  This
28
 * guarantees the selected random number will be inside
29
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
30
 * after reduction modulo upper_bound.
31
 */
32
uint32_t
33
arc4random_uniform(uint32_t upper_bound)
34
0
{
35
0
  uint32_t r, min;
36
37
0
  if (upper_bound < 2)
38
0
    return 0;
39
40
  /* 2**32 % x == (2**32 - x) % x */
41
0
  min = -upper_bound % upper_bound;
42
43
  /*
44
   * This could theoretically loop forever but each retry has
45
   * p > 0.5 (worst case, usually far better) of selecting a
46
   * number inside the range we need, so it should rarely need
47
   * to re-roll.
48
   */
49
0
  for (;;) {
50
0
    r = arc4random();
51
0
    if (r >= min)
52
0
      break;
53
0
  }
54
55
0
  return r % upper_bound;
56
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/arc4random_uniform.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $  */
2
3
/*
4
 * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdint.h>
20
#include <stdlib.h>
21
22
/*
23
 * Calculate a uniformly distributed random number less than upper_bound
24
 * avoiding "modulo bias".
25
 *
26
 * Uniformity is achieved by generating new random numbers until the one
27
 * returned is outside the range [0, 2**32 % upper_bound).  This
28
 * guarantees the selected random number will be inside
29
 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
30
 * after reduction modulo upper_bound.
31
 */
32
uint32_t
33
arc4random_uniform(uint32_t upper_bound)
34
0
{
35
0
  uint32_t r, min;
36
37
0
  if (upper_bound < 2)
38
0
    return 0;
39
40
  /* 2**32 % x == (2**32 - x) % x */
41
0
  min = -upper_bound % upper_bound;
42
43
  /*
44
   * This could theoretically loop forever but each retry has
45
   * p > 0.5 (worst case, usually far better) of selecting a
46
   * number inside the range we need, so it should rarely need
47
   * to re-roll.
48
   */
49
0
  for (;;) {
50
0
    r = arc4random();
51
0
    if (r >= min)
52
0
      break;
53
0
  }
54
55
0
  return r % upper_bound;
56
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/chacha_private.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/chacha_private.h.html index c9c7d20a3..44c0e7a32 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/chacha_private.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/chacha_private.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/chacha_private.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
  u32 input[16]; /* could be compressed */
15
} chacha_ctx;
16
17
0
#define U8C(v) (v##U)
18
0
#define U32C(v) (v##U)
19
20
0
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
0
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
0
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
0
  (((u32)((p)[0])      ) | \
28
0
   ((u32)((p)[1]) <<  8) | \
29
0
   ((u32)((p)[2]) << 16) | \
30
0
   ((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
0
  do { \
34
0
    (p)[0] = U8V((v)      ); \
35
0
    (p)[1] = U8V((v) >>  8); \
36
0
    (p)[2] = U8V((v) >> 16); \
37
0
    (p)[3] = U8V((v) >> 24); \
38
0
  } while (0)
39
40
0
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
0
#define PLUS(v,w) (U32V((v) + (w)))
43
0
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
56
0
{
57
0
  const char *constants;
58
59
0
  x->input[4] = U8TO32_LITTLE(k + 0);
60
0
  x->input[5] = U8TO32_LITTLE(k + 4);
61
0
  x->input[6] = U8TO32_LITTLE(k + 8);
62
0
  x->input[7] = U8TO32_LITTLE(k + 12);
63
0
  if (kbits == 256) { /* recommended */
64
0
    k += 16;
65
0
    constants = sigma;
66
0
  } else { /* kbits == 128 */
67
0
    constants = tau;
68
0
  }
69
0
  x->input[8] = U8TO32_LITTLE(k + 0);
70
0
  x->input[9] = U8TO32_LITTLE(k + 4);
71
0
  x->input[10] = U8TO32_LITTLE(k + 8);
72
0
  x->input[11] = U8TO32_LITTLE(k + 12);
73
0
  x->input[0] = U8TO32_LITTLE(constants + 0);
74
0
  x->input[1] = U8TO32_LITTLE(constants + 4);
75
0
  x->input[2] = U8TO32_LITTLE(constants + 8);
76
0
  x->input[3] = U8TO32_LITTLE(constants + 12);
77
0
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
0
{
82
0
  x->input[12] = 0;
83
0
  x->input[13] = 0;
84
0
  x->input[14] = U8TO32_LITTLE(iv + 0);
85
0
  x->input[15] = U8TO32_LITTLE(iv + 4);
86
0
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
0
{
91
0
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
0
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
0
  u8 *ctarget = NULL;
94
0
  u8 tmp[64];
95
0
  u_int i;
96
97
0
  if (!bytes) return;
98
99
0
  j0 = x->input[0];
100
0
  j1 = x->input[1];
101
0
  j2 = x->input[2];
102
0
  j3 = x->input[3];
103
0
  j4 = x->input[4];
104
0
  j5 = x->input[5];
105
0
  j6 = x->input[6];
106
0
  j7 = x->input[7];
107
0
  j8 = x->input[8];
108
0
  j9 = x->input[9];
109
0
  j10 = x->input[10];
110
0
  j11 = x->input[11];
111
0
  j12 = x->input[12];
112
0
  j13 = x->input[13];
113
0
  j14 = x->input[14];
114
0
  j15 = x->input[15];
115
116
0
  for (;;) {
117
0
    if (bytes < 64) {
118
0
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
0
      m = tmp;
120
0
      ctarget = c;
121
0
      c = tmp;
122
0
    }
123
0
    x0 = j0;
124
0
    x1 = j1;
125
0
    x2 = j2;
126
0
    x3 = j3;
127
0
    x4 = j4;
128
0
    x5 = j5;
129
0
    x6 = j6;
130
0
    x7 = j7;
131
0
    x8 = j8;
132
0
    x9 = j9;
133
0
    x10 = j10;
134
0
    x11 = j11;
135
0
    x12 = j12;
136
0
    x13 = j13;
137
0
    x14 = j14;
138
0
    x15 = j15;
139
0
    for (i = 20;i > 0;i -= 2) {
140
0
      QUARTERROUND( x0, x4, x8,x12)
141
0
      QUARTERROUND( x1, x5, x9,x13)
142
0
      QUARTERROUND( x2, x6,x10,x14)
143
0
      QUARTERROUND( x3, x7,x11,x15)
144
0
      QUARTERROUND( x0, x5,x10,x15)
145
0
      QUARTERROUND( x1, x6,x11,x12)
146
0
      QUARTERROUND( x2, x7, x8,x13)
147
0
      QUARTERROUND( x3, x4, x9,x14)
148
0
    }
149
0
    x0 = PLUS(x0,j0);
150
0
    x1 = PLUS(x1,j1);
151
0
    x2 = PLUS(x2,j2);
152
0
    x3 = PLUS(x3,j3);
153
0
    x4 = PLUS(x4,j4);
154
0
    x5 = PLUS(x5,j5);
155
0
    x6 = PLUS(x6,j6);
156
0
    x7 = PLUS(x7,j7);
157
0
    x8 = PLUS(x8,j8);
158
0
    x9 = PLUS(x9,j9);
159
0
    x10 = PLUS(x10,j10);
160
0
    x11 = PLUS(x11,j11);
161
0
    x12 = PLUS(x12,j12);
162
0
    x13 = PLUS(x13,j13);
163
0
    x14 = PLUS(x14,j14);
164
0
    x15 = PLUS(x15,j15);
165
166
#ifndef KEYSTREAM_ONLY
167
    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168
    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169
    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170
    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171
    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172
    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173
    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174
    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175
    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176
    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177
    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178
    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179
    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180
    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181
    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182
    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
#endif
184
185
0
    j12 = PLUSONE(j12);
186
0
    if (!j12) {
187
0
      j13 = PLUSONE(j13);
188
      /* stopping at 2^70 bytes per nonce is user's responsibility */
189
0
    }
190
191
0
    U32TO8_LITTLE(c + 0,x0);
192
0
    U32TO8_LITTLE(c + 4,x1);
193
0
    U32TO8_LITTLE(c + 8,x2);
194
0
    U32TO8_LITTLE(c + 12,x3);
195
0
    U32TO8_LITTLE(c + 16,x4);
196
0
    U32TO8_LITTLE(c + 20,x5);
197
0
    U32TO8_LITTLE(c + 24,x6);
198
0
    U32TO8_LITTLE(c + 28,x7);
199
0
    U32TO8_LITTLE(c + 32,x8);
200
0
    U32TO8_LITTLE(c + 36,x9);
201
0
    U32TO8_LITTLE(c + 40,x10);
202
0
    U32TO8_LITTLE(c + 44,x11);
203
0
    U32TO8_LITTLE(c + 48,x12);
204
0
    U32TO8_LITTLE(c + 52,x13);
205
0
    U32TO8_LITTLE(c + 56,x14);
206
0
    U32TO8_LITTLE(c + 60,x15);
207
208
0
    if (bytes <= 64) {
209
0
      if (bytes < 64) {
210
0
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
0
      }
212
0
      x->input[12] = j12;
213
0
      x->input[13] = j13;
214
0
      return;
215
0
    }
216
0
    bytes -= 64;
217
0
    c += 64;
218
#ifndef KEYSTREAM_ONLY
219
    m += 64;
220
#endif
221
0
  }
222
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/chacha_private.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
chacha-merged.c version 20080118
3
D. J. Bernstein
4
Public domain.
5
*/
6
7
/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
8
9
typedef unsigned char u8;
10
typedef unsigned int u32;
11
12
typedef struct
13
{
14
  u32 input[16]; /* could be compressed */
15
} chacha_ctx;
16
17
0
#define U8C(v) (v##U)
18
0
#define U32C(v) (v##U)
19
20
0
#define U8V(v) ((u8)(v) & U8C(0xFF))
21
0
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
22
23
#define ROTL32(v, n) \
24
0
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
25
26
#define U8TO32_LITTLE(p) \
27
0
  (((u32)((p)[0])      ) | \
28
0
   ((u32)((p)[1]) <<  8) | \
29
0
   ((u32)((p)[2]) << 16) | \
30
0
   ((u32)((p)[3]) << 24))
31
32
#define U32TO8_LITTLE(p, v) \
33
0
  do { \
34
0
    (p)[0] = U8V((v)      ); \
35
0
    (p)[1] = U8V((v) >>  8); \
36
0
    (p)[2] = U8V((v) >> 16); \
37
0
    (p)[3] = U8V((v) >> 24); \
38
0
  } while (0)
39
40
0
#define ROTATE(v,c) (ROTL32(v,c))
41
#define XOR(v,w) ((v) ^ (w))
42
0
#define PLUS(v,w) (U32V((v) + (w)))
43
0
#define PLUSONE(v) (PLUS((v),1))
44
45
#define QUARTERROUND(a,b,c,d) \
46
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
47
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
48
0
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
49
0
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
50
51
static const char sigma[16] = "expand 32-byte k";
52
static const char tau[16] = "expand 16-byte k";
53
54
static void
55
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
56
0
{
57
0
  const char *constants;
58
59
0
  x->input[4] = U8TO32_LITTLE(k + 0);
60
0
  x->input[5] = U8TO32_LITTLE(k + 4);
61
0
  x->input[6] = U8TO32_LITTLE(k + 8);
62
0
  x->input[7] = U8TO32_LITTLE(k + 12);
63
0
  if (kbits == 256) { /* recommended */
64
0
    k += 16;
65
0
    constants = sigma;
66
0
  } else { /* kbits == 128 */
67
0
    constants = tau;
68
0
  }
69
0
  x->input[8] = U8TO32_LITTLE(k + 0);
70
0
  x->input[9] = U8TO32_LITTLE(k + 4);
71
0
  x->input[10] = U8TO32_LITTLE(k + 8);
72
0
  x->input[11] = U8TO32_LITTLE(k + 12);
73
0
  x->input[0] = U8TO32_LITTLE(constants + 0);
74
0
  x->input[1] = U8TO32_LITTLE(constants + 4);
75
0
  x->input[2] = U8TO32_LITTLE(constants + 8);
76
0
  x->input[3] = U8TO32_LITTLE(constants + 12);
77
0
}
78
79
static void
80
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
81
0
{
82
0
  x->input[12] = 0;
83
0
  x->input[13] = 0;
84
0
  x->input[14] = U8TO32_LITTLE(iv + 0);
85
0
  x->input[15] = U8TO32_LITTLE(iv + 4);
86
0
}
87
88
static void
89
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
90
0
{
91
0
  u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
92
0
  u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
93
0
  u8 *ctarget = NULL;
94
0
  u8 tmp[64];
95
0
  u_int i;
96
97
0
  if (!bytes) return;
98
99
0
  j0 = x->input[0];
100
0
  j1 = x->input[1];
101
0
  j2 = x->input[2];
102
0
  j3 = x->input[3];
103
0
  j4 = x->input[4];
104
0
  j5 = x->input[5];
105
0
  j6 = x->input[6];
106
0
  j7 = x->input[7];
107
0
  j8 = x->input[8];
108
0
  j9 = x->input[9];
109
0
  j10 = x->input[10];
110
0
  j11 = x->input[11];
111
0
  j12 = x->input[12];
112
0
  j13 = x->input[13];
113
0
  j14 = x->input[14];
114
0
  j15 = x->input[15];
115
116
0
  for (;;) {
117
0
    if (bytes < 64) {
118
0
      for (i = 0;i < bytes;++i) tmp[i] = m[i];
119
0
      m = tmp;
120
0
      ctarget = c;
121
0
      c = tmp;
122
0
    }
123
0
    x0 = j0;
124
0
    x1 = j1;
125
0
    x2 = j2;
126
0
    x3 = j3;
127
0
    x4 = j4;
128
0
    x5 = j5;
129
0
    x6 = j6;
130
0
    x7 = j7;
131
0
    x8 = j8;
132
0
    x9 = j9;
133
0
    x10 = j10;
134
0
    x11 = j11;
135
0
    x12 = j12;
136
0
    x13 = j13;
137
0
    x14 = j14;
138
0
    x15 = j15;
139
0
    for (i = 20;i > 0;i -= 2) {
140
0
      QUARTERROUND( x0, x4, x8,x12)
141
0
      QUARTERROUND( x1, x5, x9,x13)
142
0
      QUARTERROUND( x2, x6,x10,x14)
143
0
      QUARTERROUND( x3, x7,x11,x15)
144
0
      QUARTERROUND( x0, x5,x10,x15)
145
0
      QUARTERROUND( x1, x6,x11,x12)
146
0
      QUARTERROUND( x2, x7, x8,x13)
147
0
      QUARTERROUND( x3, x4, x9,x14)
148
0
    }
149
0
    x0 = PLUS(x0,j0);
150
0
    x1 = PLUS(x1,j1);
151
0
    x2 = PLUS(x2,j2);
152
0
    x3 = PLUS(x3,j3);
153
0
    x4 = PLUS(x4,j4);
154
0
    x5 = PLUS(x5,j5);
155
0
    x6 = PLUS(x6,j6);
156
0
    x7 = PLUS(x7,j7);
157
0
    x8 = PLUS(x8,j8);
158
0
    x9 = PLUS(x9,j9);
159
0
    x10 = PLUS(x10,j10);
160
0
    x11 = PLUS(x11,j11);
161
0
    x12 = PLUS(x12,j12);
162
0
    x13 = PLUS(x13,j13);
163
0
    x14 = PLUS(x14,j14);
164
0
    x15 = PLUS(x15,j15);
165
166
#ifndef KEYSTREAM_ONLY
167
    x0 = XOR(x0,U8TO32_LITTLE(m + 0));
168
    x1 = XOR(x1,U8TO32_LITTLE(m + 4));
169
    x2 = XOR(x2,U8TO32_LITTLE(m + 8));
170
    x3 = XOR(x3,U8TO32_LITTLE(m + 12));
171
    x4 = XOR(x4,U8TO32_LITTLE(m + 16));
172
    x5 = XOR(x5,U8TO32_LITTLE(m + 20));
173
    x6 = XOR(x6,U8TO32_LITTLE(m + 24));
174
    x7 = XOR(x7,U8TO32_LITTLE(m + 28));
175
    x8 = XOR(x8,U8TO32_LITTLE(m + 32));
176
    x9 = XOR(x9,U8TO32_LITTLE(m + 36));
177
    x10 = XOR(x10,U8TO32_LITTLE(m + 40));
178
    x11 = XOR(x11,U8TO32_LITTLE(m + 44));
179
    x12 = XOR(x12,U8TO32_LITTLE(m + 48));
180
    x13 = XOR(x13,U8TO32_LITTLE(m + 52));
181
    x14 = XOR(x14,U8TO32_LITTLE(m + 56));
182
    x15 = XOR(x15,U8TO32_LITTLE(m + 60));
183
#endif
184
185
0
    j12 = PLUSONE(j12);
186
0
    if (!j12) {
187
0
      j13 = PLUSONE(j13);
188
      /* stopping at 2^70 bytes per nonce is user's responsibility */
189
0
    }
190
191
0
    U32TO8_LITTLE(c + 0,x0);
192
0
    U32TO8_LITTLE(c + 4,x1);
193
0
    U32TO8_LITTLE(c + 8,x2);
194
0
    U32TO8_LITTLE(c + 12,x3);
195
0
    U32TO8_LITTLE(c + 16,x4);
196
0
    U32TO8_LITTLE(c + 20,x5);
197
0
    U32TO8_LITTLE(c + 24,x6);
198
0
    U32TO8_LITTLE(c + 28,x7);
199
0
    U32TO8_LITTLE(c + 32,x8);
200
0
    U32TO8_LITTLE(c + 36,x9);
201
0
    U32TO8_LITTLE(c + 40,x10);
202
0
    U32TO8_LITTLE(c + 44,x11);
203
0
    U32TO8_LITTLE(c + 48,x12);
204
0
    U32TO8_LITTLE(c + 52,x13);
205
0
    U32TO8_LITTLE(c + 56,x14);
206
0
    U32TO8_LITTLE(c + 60,x15);
207
208
0
    if (bytes <= 64) {
209
0
      if (bytes < 64) {
210
0
        for (i = 0;i < bytes;++i) ctarget[i] = c[i];
211
0
      }
212
0
      x->input[12] = j12;
213
0
      x->input[13] = j13;
214
0
      return;
215
0
    }
216
0
    bytes -= 64;
217
0
    c += 64;
218
#ifndef KEYSTREAM_ONLY
219
    m += 64;
220
#endif
221
0
  }
222
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/freezero.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/freezero.c.html index 12fb77b8c..4f2fd0053 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/freezero.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/freezero.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/freezero.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
3
 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
4
 * Copyright (c) 2008 Damien Miller <djm@openbsd.org>
5
 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <string.h>
21
#include <stdlib.h>
22
23
void
24
freezero(void *ptr, size_t sz)
25
20.3k
{
26
  /* This is legal. */
27
20.3k
  if (ptr == NULL)
28
1.41k
    return;
29
30
18.9k
  explicit_bzero(ptr, sz);
31
18.9k
  free(ptr);
32
18.9k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/freezero.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
3
 * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
4
 * Copyright (c) 2008 Damien Miller <djm@openbsd.org>
5
 * Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <string.h>
21
#include <stdlib.h>
22
23
void
24
freezero(void *ptr, size_t sz)
25
20.4k
{
26
  /* This is legal. */
27
20.4k
  if (ptr == NULL)
28
1.41k
    return;
29
30
19.0k
  explicit_bzero(ptr, sz);
31
19.0k
  free(ptr);
32
19.0k
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getdtablecount.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getdtablecount.c.html index 6e18c48fc..5cd4a3b0a 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getdtablecount.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getdtablecount.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/getdtablecount.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETDTABLECOUNT)
6
int
7
getdtablecount(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/getdtablecount.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETDTABLECOUNT)
6
int
7
getdtablecount(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getrtable.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getrtable.c.html index dce343949..49372bac9 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getrtable.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/getrtable.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/getrtable.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETRTABLE)
6
int
7
getrtable(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
12
13
#if !defined(HAVE_SETRTABLE)
14
int
15
setrtable(int rtableid)
16
0
{
17
0
  if (rtableid == 0)
18
0
    return (0);
19
0
  return (-1);
20
0
}
21
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/getrtable.c
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#include "openbsd-compat.h"
4
5
#if !defined(HAVE_GETRTABLE)
6
int
7
getrtable(void)
8
0
{
9
0
  return (0);
10
0
}
11
#endif
12
13
#if !defined(HAVE_SETRTABLE)
14
int
15
setrtable(int rtableid)
16
0
{
17
0
  if (rtableid == 0)
18
0
    return (0);
19
0
  return (-1);
20
0
}
21
#endif
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg-buffer.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg-buffer.c.html index a6b7d70d3..37407254b 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg-buffer.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg-buffer.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg-buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <limits.h>
25
#include <errno.h>
26
#include <endian.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#include "openbsd-compat.h"
32
#include "imsg.h"
33
34
static int  ibuf_realloc(struct ibuf *, size_t);
35
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
36
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
37
static void msgbuf_drain(struct msgbuf *, size_t);
38
39
struct ibuf *
40
ibuf_open(size_t len)
41
0
{
42
0
  struct ibuf *buf;
43
44
0
  if (len == 0) {
45
0
    errno = EINVAL;
46
0
    return (NULL);
47
0
  }
48
0
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
49
0
    return (NULL);
50
0
  if ((buf->buf = calloc(len, 1)) == NULL) {
51
0
    free(buf);
52
0
    return (NULL);
53
0
  }
54
0
  buf->size = buf->max = len;
55
0
  buf->fd = -1;
56
57
0
  return (buf);
58
0
}
59
60
struct ibuf *
61
ibuf_dynamic(size_t len, size_t max)
62
20.3k
{
63
20.3k
  struct ibuf *buf;
64
65
20.3k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
20.3k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
20.3k
  if (len > 0) {
73
18.9k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
18.9k
  }
78
20.3k
  buf->size = len;
79
20.3k
  buf->max = max;
80
20.3k
  buf->fd = -1;
81
82
20.3k
  return (buf);
83
20.3k
}
84
85
static int
86
ibuf_realloc(struct ibuf *buf, size_t len)
87
0
{
88
0
  unsigned char *b;
89
90
  /* on static buffers max is eq size and so the following fails */
91
0
  if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
92
0
    errno = ERANGE;
93
0
    return (-1);
94
0
  }
95
96
0
  b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
97
0
  if (b == NULL)
98
0
    return (-1);
99
0
  buf->buf = b;
100
0
  buf->size = buf->wpos + len;
101
102
0
  return (0);
103
0
}
104
105
void *
106
ibuf_reserve(struct ibuf *buf, size_t len)
107
18.9k
{
108
18.9k
  void  *b;
109
110
18.9k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
18.9k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
18.9k
  b = buf->buf + buf->wpos;
120
18.9k
  buf->wpos += len;
121
18.9k
  memset(b, 0, len);
122
18.9k
  return (b);
123
18.9k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
18.9k
{
128
18.9k
  void *b;
129
130
18.9k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
18.9k
  memcpy(b, data, len);
134
18.9k
  return (0);
135
18.9k
}
136
137
138
int
139
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
140
0
{
141
0
  return ibuf_add(buf, from->buf, from->wpos);
142
0
}
143
144
int
145
ibuf_add_n8(struct ibuf *buf, uint64_t value)
146
0
{
147
0
  uint8_t v;
148
149
0
  if (value > UINT8_MAX) {
150
0
    errno = EINVAL;
151
0
    return (-1);
152
0
  }
153
0
  v = value;
154
0
  return ibuf_add(buf, &v, sizeof(v));
155
0
}
156
157
int
158
ibuf_add_n16(struct ibuf *buf, uint64_t value)
159
0
{
160
0
  uint16_t v;
161
162
0
  if (value > UINT16_MAX) {
163
0
    errno = EINVAL;
164
0
    return (-1);
165
0
  }
166
0
  v = htobe16(value);
167
0
  return ibuf_add(buf, &v, sizeof(v));
168
0
}
169
170
int
171
ibuf_add_n32(struct ibuf *buf, uint64_t value)
172
0
{
173
0
  uint32_t v;
174
175
0
  if (value > UINT32_MAX) {
176
0
    errno = EINVAL;
177
0
    return (-1);
178
0
  }
179
0
  v = htobe32(value);
180
0
  return ibuf_add(buf, &v, sizeof(v));
181
0
}
182
183
int
184
ibuf_add_n64(struct ibuf *buf, uint64_t value)
185
0
{
186
0
  value = htobe64(value);
187
0
  return ibuf_add(buf, &value, sizeof(value));
188
0
}
189
190
int
191
ibuf_add_zero(struct ibuf *buf, size_t len)
192
0
{
193
0
  void *b;
194
195
0
  if ((b = ibuf_reserve(buf, len)) == NULL)
196
0
    return (-1);
197
0
  return (0);
198
0
}
199
200
void *
201
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
202
232k
{
203
  /* only allowed to seek in already written parts */
204
232k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
3.28k
    errno = ERANGE;
206
3.28k
    return (NULL);
207
3.28k
  }
208
209
229k
  return (buf->buf + pos);
210
232k
}
211
212
int
213
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
214
0
{
215
0
  void *b;
216
217
0
  if ((b = ibuf_seek(buf, pos, len)) == NULL)
218
0
    return (-1);
219
220
0
  memcpy(b, data, len);
221
0
  return (0);
222
0
}
223
224
int
225
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
226
0
{
227
0
  uint8_t v;
228
229
0
  if (value > UINT8_MAX) {
230
0
    errno = EINVAL;
231
0
    return (-1);
232
0
  }
233
0
  v = value;
234
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
235
0
}
236
237
int
238
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
239
0
{
240
0
  uint16_t v;
241
242
0
  if (value > UINT16_MAX) {
243
0
    errno = EINVAL;
244
0
    return (-1);
245
0
  }
246
0
  v = htobe16(value);
247
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
248
0
}
249
250
int
251
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
252
0
{
253
0
  uint32_t v;
254
255
0
  if (value > UINT32_MAX) {
256
0
    errno = EINVAL;
257
0
    return (-1);
258
0
  }
259
0
  v = htobe32(value);
260
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
261
0
}
262
263
int
264
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
265
0
{
266
0
  value = htobe64(value);
267
0
  return (ibuf_set(buf, pos, &value, sizeof(value)));
268
0
}
269
270
void *
271
ibuf_data(struct ibuf *buf)
272
707k
{
273
707k
  return (buf->buf);
274
707k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
13.0k
{
279
13.0k
  return (buf->wpos);
280
13.0k
}
281
282
size_t
283
ibuf_left(struct ibuf *buf)
284
0
{
285
0
  return (buf->max - buf->wpos);
286
0
}
287
288
void
289
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
290
0
{
291
0
  ibuf_enqueue(msgbuf, buf);
292
0
}
293
294
void
295
ibuf_free(struct ibuf *buf)
296
175k
{
297
175k
  if (buf == NULL)
298
155k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
20.3k
  freezero(buf->buf, buf->size);
304
20.3k
  free(buf);
305
20.3k
}
306
307
int
308
ibuf_fd_avail(struct ibuf *buf)
309
0
{
310
0
  return (buf->fd != -1);
311
0
}
312
313
int
314
ibuf_fd_get(struct ibuf *buf)
315
0
{
316
0
  int fd;
317
318
0
  fd = buf->fd;
319
#ifdef NOTYET
320
  buf->fd = -1;
321
#endif
322
0
  return (fd);
323
0
}
324
325
void
326
ibuf_fd_set(struct ibuf *buf, int fd)
327
0
{
328
0
  if (buf->fd != -1)
329
0
    close(buf->fd);
330
0
  buf->fd = fd;
331
0
}
332
333
#ifdef _WIN32
334
#define IBUF_WSABUF_WRITE_MAX 16
335
int
336
ibuf_write(struct msgbuf *msgbuf)
337
{
338
  DWORD    bytesSent;
339
  WSABUF     iov[IBUF_WSABUF_WRITE_MAX];
340
  struct ibuf *buf;
341
  unsigned int   i = 0;
342
  ssize_t n;
343
344
  memset(&iov, 0, sizeof(iov));
345
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
346
    if (i >= IBUF_WSABUF_WRITE_MAX)
347
      break;
348
    iov[i].buf = buf->buf + buf->rpos;
349
    iov[i].len = buf->wpos - buf->rpos;
350
    i++;
351
  }
352
353
  if (WSASend(msgbuf->fd, iov, i, &bytesSent, 0, NULL, NULL))
354
    return (-1);
355
  n = bytesSent;
356
357
  if (n == 0) {     /* connection closed */
358
    errno = 0;
359
    return (0);
360
  }
361
362
  msgbuf_drain(msgbuf, n);
363
364
  return (1);
365
}
366
#else
367
int
368
ibuf_write(struct msgbuf *msgbuf)
369
0
{
370
0
  struct iovec   iov[IOV_MAX];
371
0
  struct ibuf *buf;
372
0
  unsigned int   i = 0;
373
0
  ssize_t n;
374
375
0
  memset(&iov, 0, sizeof(iov));
376
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
377
0
    if (i >= IOV_MAX)
378
0
      break;
379
0
    iov[i].iov_base = buf->buf + buf->rpos;
380
0
    iov[i].iov_len = buf->wpos - buf->rpos;
381
0
    i++;
382
0
  }
383
384
0
again:
385
0
  if ((n = writev(msgbuf->fd, iov, i)) == -1) {
386
0
    if (errno == EINTR)
387
0
      goto again;
388
0
    if (errno == ENOBUFS)
389
0
      errno = EAGAIN;
390
0
    return (-1);
391
0
  }
392
393
0
  if (n == 0) {     /* connection closed */
394
0
    errno = 0;
395
0
    return (0);
396
0
  }
397
398
0
  msgbuf_drain(msgbuf, n);
399
400
0
  return (1);
401
0
}
402
#endif /* !_WIN32 */
403
404
void
405
msgbuf_init(struct msgbuf *msgbuf)
406
0
{
407
0
  msgbuf->queued = 0;
408
0
  msgbuf->fd = -1;
409
0
  TAILQ_INIT(&msgbuf->bufs);
410
0
}
411
412
static void
413
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
414
0
{
415
0
  struct ibuf *buf, *next;
416
417
0
  for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
418
0
      buf = next) {
419
0
    next = TAILQ_NEXT(buf, entry);
420
0
    if (n >= buf->wpos - buf->rpos) {
421
0
      n -= buf->wpos - buf->rpos;
422
0
      ibuf_dequeue(msgbuf, buf);
423
0
    } else {
424
0
      buf->rpos += n;
425
0
      n = 0;
426
0
    }
427
0
  }
428
0
}
429
430
void
431
msgbuf_clear(struct msgbuf *msgbuf)
432
0
{
433
0
  struct ibuf *buf;
434
435
0
  while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
436
0
    ibuf_dequeue(msgbuf, buf);
437
0
}
438
439
#ifdef _WIN32
440
int
441
msgbuf_write(struct msgbuf *msgbuf)
442
{
443
  struct ibuf *buf;
444
445
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
446
    if (buf->fd != -1)
447
      return (-1);
448
  return ibuf_write(msgbuf);
449
}
450
#else
451
int
452
msgbuf_write(struct msgbuf *msgbuf)
453
0
{
454
0
  struct iovec   iov[IOV_MAX];
455
0
  struct ibuf *buf, *buf0 = NULL;
456
0
  unsigned int   i = 0;
457
0
  ssize_t    n;
458
0
  struct msghdr  msg;
459
0
  struct cmsghdr  *cmsg;
460
0
  union {
461
0
    struct cmsghdr  hdr;
462
0
    char    buf[CMSG_SPACE(sizeof(int))];
463
0
  } cmsgbuf;
464
465
0
  memset(&iov, 0, sizeof(iov));
466
0
  memset(&msg, 0, sizeof(msg));
467
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
468
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
469
0
    if (i >= IOV_MAX)
470
0
      break;
471
0
    if (i > 0 && buf->fd != -1)
472
0
      break;
473
0
    iov[i].iov_base = buf->buf + buf->rpos;
474
0
    iov[i].iov_len = buf->wpos - buf->rpos;
475
0
    i++;
476
0
    if (buf->fd != -1)
477
0
      buf0 = buf;
478
0
  }
479
480
0
  msg.msg_iov = iov;
481
0
  msg.msg_iovlen = i;
482
483
0
  if (buf0 != NULL) {
484
0
    msg.msg_control = (caddr_t)&cmsgbuf.buf;
485
0
    msg.msg_controllen = sizeof(cmsgbuf.buf);
486
0
    cmsg = CMSG_FIRSTHDR(&msg);
487
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
488
0
    cmsg->cmsg_level = SOL_SOCKET;
489
0
    cmsg->cmsg_type = SCM_RIGHTS;
490
0
    *(int *)CMSG_DATA(cmsg) = buf0->fd;
491
0
  }
492
493
0
again:
494
0
  if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
495
0
    if (errno == EINTR)
496
0
      goto again;
497
0
    if (errno == ENOBUFS)
498
0
      errno = EAGAIN;
499
0
    return (-1);
500
0
  }
501
502
0
  if (n == 0) {     /* connection closed */
503
0
    errno = 0;
504
0
    return (0);
505
0
  }
506
507
  /*
508
   * assumption: fd got sent if sendmsg sent anything
509
   * this works because fds are passed one at a time
510
   */
511
0
  if (buf0 != NULL) {
512
0
    close(buf0->fd);
513
0
    buf0->fd = -1;
514
0
  }
515
516
0
  msgbuf_drain(msgbuf, n);
517
518
0
  return (1);
519
0
}
520
#endif /* !_WIN32 */
521
522
static void
523
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
524
0
{
525
0
  TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
526
0
  msgbuf->queued++;
527
0
}
528
529
static void
530
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
531
0
{
532
0
  TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
533
534
0
  if (buf->fd != -1) {
535
0
    close(buf->fd);
536
0
    buf->fd = -1;
537
0
  }
538
539
0
  msgbuf->queued--;
540
0
  ibuf_free(buf);
541
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg-buffer.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg-buffer.c,v 1.16 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <limits.h>
25
#include <errno.h>
26
#include <endian.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
31
#include "openbsd-compat.h"
32
#include "imsg.h"
33
34
static int  ibuf_realloc(struct ibuf *, size_t);
35
static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
36
static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
37
static void msgbuf_drain(struct msgbuf *, size_t);
38
39
struct ibuf *
40
ibuf_open(size_t len)
41
0
{
42
0
  struct ibuf *buf;
43
44
0
  if (len == 0) {
45
0
    errno = EINVAL;
46
0
    return (NULL);
47
0
  }
48
0
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
49
0
    return (NULL);
50
0
  if ((buf->buf = calloc(len, 1)) == NULL) {
51
0
    free(buf);
52
0
    return (NULL);
53
0
  }
54
0
  buf->size = buf->max = len;
55
0
  buf->fd = -1;
56
57
0
  return (buf);
58
0
}
59
60
struct ibuf *
61
ibuf_dynamic(size_t len, size_t max)
62
20.4k
{
63
20.4k
  struct ibuf *buf;
64
65
20.4k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
20.4k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
20.4k
  if (len > 0) {
73
19.0k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
19.0k
  }
78
20.4k
  buf->size = len;
79
20.4k
  buf->max = max;
80
20.4k
  buf->fd = -1;
81
82
20.4k
  return (buf);
83
20.4k
}
84
85
static int
86
ibuf_realloc(struct ibuf *buf, size_t len)
87
0
{
88
0
  unsigned char *b;
89
90
  /* on static buffers max is eq size and so the following fails */
91
0
  if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
92
0
    errno = ERANGE;
93
0
    return (-1);
94
0
  }
95
96
0
  b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
97
0
  if (b == NULL)
98
0
    return (-1);
99
0
  buf->buf = b;
100
0
  buf->size = buf->wpos + len;
101
102
0
  return (0);
103
0
}
104
105
void *
106
ibuf_reserve(struct ibuf *buf, size_t len)
107
19.0k
{
108
19.0k
  void  *b;
109
110
19.0k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
19.0k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
19.0k
  b = buf->buf + buf->wpos;
120
19.0k
  buf->wpos += len;
121
19.0k
  memset(b, 0, len);
122
19.0k
  return (b);
123
19.0k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
19.0k
{
128
19.0k
  void *b;
129
130
19.0k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
19.0k
  memcpy(b, data, len);
134
19.0k
  return (0);
135
19.0k
}
136
137
138
int
139
ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
140
0
{
141
0
  return ibuf_add(buf, from->buf, from->wpos);
142
0
}
143
144
int
145
ibuf_add_n8(struct ibuf *buf, uint64_t value)
146
0
{
147
0
  uint8_t v;
148
149
0
  if (value > UINT8_MAX) {
150
0
    errno = EINVAL;
151
0
    return (-1);
152
0
  }
153
0
  v = value;
154
0
  return ibuf_add(buf, &v, sizeof(v));
155
0
}
156
157
int
158
ibuf_add_n16(struct ibuf *buf, uint64_t value)
159
0
{
160
0
  uint16_t v;
161
162
0
  if (value > UINT16_MAX) {
163
0
    errno = EINVAL;
164
0
    return (-1);
165
0
  }
166
0
  v = htobe16(value);
167
0
  return ibuf_add(buf, &v, sizeof(v));
168
0
}
169
170
int
171
ibuf_add_n32(struct ibuf *buf, uint64_t value)
172
0
{
173
0
  uint32_t v;
174
175
0
  if (value > UINT32_MAX) {
176
0
    errno = EINVAL;
177
0
    return (-1);
178
0
  }
179
0
  v = htobe32(value);
180
0
  return ibuf_add(buf, &v, sizeof(v));
181
0
}
182
183
int
184
ibuf_add_n64(struct ibuf *buf, uint64_t value)
185
0
{
186
0
  value = htobe64(value);
187
0
  return ibuf_add(buf, &value, sizeof(value));
188
0
}
189
190
int
191
ibuf_add_zero(struct ibuf *buf, size_t len)
192
0
{
193
0
  void *b;
194
195
0
  if ((b = ibuf_reserve(buf, len)) == NULL)
196
0
    return (-1);
197
0
  return (0);
198
0
}
199
200
void *
201
ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
202
233k
{
203
  /* only allowed to seek in already written parts */
204
233k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
3.28k
    errno = ERANGE;
206
3.28k
    return (NULL);
207
3.28k
  }
208
209
230k
  return (buf->buf + pos);
210
233k
}
211
212
int
213
ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
214
0
{
215
0
  void *b;
216
217
0
  if ((b = ibuf_seek(buf, pos, len)) == NULL)
218
0
    return (-1);
219
220
0
  memcpy(b, data, len);
221
0
  return (0);
222
0
}
223
224
int
225
ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
226
0
{
227
0
  uint8_t v;
228
229
0
  if (value > UINT8_MAX) {
230
0
    errno = EINVAL;
231
0
    return (-1);
232
0
  }
233
0
  v = value;
234
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
235
0
}
236
237
int
238
ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
239
0
{
240
0
  uint16_t v;
241
242
0
  if (value > UINT16_MAX) {
243
0
    errno = EINVAL;
244
0
    return (-1);
245
0
  }
246
0
  v = htobe16(value);
247
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
248
0
}
249
250
int
251
ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
252
0
{
253
0
  uint32_t v;
254
255
0
  if (value > UINT32_MAX) {
256
0
    errno = EINVAL;
257
0
    return (-1);
258
0
  }
259
0
  v = htobe32(value);
260
0
  return (ibuf_set(buf, pos, &v, sizeof(v)));
261
0
}
262
263
int
264
ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
265
0
{
266
0
  value = htobe64(value);
267
0
  return (ibuf_set(buf, pos, &value, sizeof(value)));
268
0
}
269
270
void *
271
ibuf_data(struct ibuf *buf)
272
711k
{
273
711k
  return (buf->buf);
274
711k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
13.1k
{
279
13.1k
  return (buf->wpos);
280
13.1k
}
281
282
size_t
283
ibuf_left(struct ibuf *buf)
284
0
{
285
0
  return (buf->max - buf->wpos);
286
0
}
287
288
void
289
ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
290
0
{
291
0
  ibuf_enqueue(msgbuf, buf);
292
0
}
293
294
void
295
ibuf_free(struct ibuf *buf)
296
177k
{
297
177k
  if (buf == NULL)
298
157k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
20.4k
  freezero(buf->buf, buf->size);
304
20.4k
  free(buf);
305
20.4k
}
306
307
int
308
ibuf_fd_avail(struct ibuf *buf)
309
0
{
310
0
  return (buf->fd != -1);
311
0
}
312
313
int
314
ibuf_fd_get(struct ibuf *buf)
315
0
{
316
0
  int fd;
317
318
0
  fd = buf->fd;
319
#ifdef NOTYET
320
  buf->fd = -1;
321
#endif
322
0
  return (fd);
323
0
}
324
325
void
326
ibuf_fd_set(struct ibuf *buf, int fd)
327
0
{
328
0
  if (buf->fd != -1)
329
0
    close(buf->fd);
330
0
  buf->fd = fd;
331
0
}
332
333
#ifdef _WIN32
334
#define IBUF_WSABUF_WRITE_MAX 16
335
int
336
ibuf_write(struct msgbuf *msgbuf)
337
{
338
  DWORD    bytesSent;
339
  WSABUF     iov[IBUF_WSABUF_WRITE_MAX];
340
  struct ibuf *buf;
341
  unsigned int   i = 0;
342
  ssize_t n;
343
344
  memset(&iov, 0, sizeof(iov));
345
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
346
    if (i >= IBUF_WSABUF_WRITE_MAX)
347
      break;
348
    iov[i].buf = buf->buf + buf->rpos;
349
    iov[i].len = buf->wpos - buf->rpos;
350
    i++;
351
  }
352
353
  if (WSASend(msgbuf->fd, iov, i, &bytesSent, 0, NULL, NULL))
354
    return (-1);
355
  n = bytesSent;
356
357
  if (n == 0) {     /* connection closed */
358
    errno = 0;
359
    return (0);
360
  }
361
362
  msgbuf_drain(msgbuf, n);
363
364
  return (1);
365
}
366
#else
367
int
368
ibuf_write(struct msgbuf *msgbuf)
369
0
{
370
0
  struct iovec   iov[IOV_MAX];
371
0
  struct ibuf *buf;
372
0
  unsigned int   i = 0;
373
0
  ssize_t n;
374
375
0
  memset(&iov, 0, sizeof(iov));
376
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
377
0
    if (i >= IOV_MAX)
378
0
      break;
379
0
    iov[i].iov_base = buf->buf + buf->rpos;
380
0
    iov[i].iov_len = buf->wpos - buf->rpos;
381
0
    i++;
382
0
  }
383
384
0
again:
385
0
  if ((n = writev(msgbuf->fd, iov, i)) == -1) {
386
0
    if (errno == EINTR)
387
0
      goto again;
388
0
    if (errno == ENOBUFS)
389
0
      errno = EAGAIN;
390
0
    return (-1);
391
0
  }
392
393
0
  if (n == 0) {     /* connection closed */
394
0
    errno = 0;
395
0
    return (0);
396
0
  }
397
398
0
  msgbuf_drain(msgbuf, n);
399
400
0
  return (1);
401
0
}
402
#endif /* !_WIN32 */
403
404
void
405
msgbuf_init(struct msgbuf *msgbuf)
406
0
{
407
0
  msgbuf->queued = 0;
408
0
  msgbuf->fd = -1;
409
0
  TAILQ_INIT(&msgbuf->bufs);
410
0
}
411
412
static void
413
msgbuf_drain(struct msgbuf *msgbuf, size_t n)
414
0
{
415
0
  struct ibuf *buf, *next;
416
417
0
  for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
418
0
      buf = next) {
419
0
    next = TAILQ_NEXT(buf, entry);
420
0
    if (n >= buf->wpos - buf->rpos) {
421
0
      n -= buf->wpos - buf->rpos;
422
0
      ibuf_dequeue(msgbuf, buf);
423
0
    } else {
424
0
      buf->rpos += n;
425
0
      n = 0;
426
0
    }
427
0
  }
428
0
}
429
430
void
431
msgbuf_clear(struct msgbuf *msgbuf)
432
0
{
433
0
  struct ibuf *buf;
434
435
0
  while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
436
0
    ibuf_dequeue(msgbuf, buf);
437
0
}
438
439
#ifdef _WIN32
440
int
441
msgbuf_write(struct msgbuf *msgbuf)
442
{
443
  struct ibuf *buf;
444
445
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry)
446
    if (buf->fd != -1)
447
      return (-1);
448
  return ibuf_write(msgbuf);
449
}
450
#else
451
int
452
msgbuf_write(struct msgbuf *msgbuf)
453
0
{
454
0
  struct iovec   iov[IOV_MAX];
455
0
  struct ibuf *buf, *buf0 = NULL;
456
0
  unsigned int   i = 0;
457
0
  ssize_t    n;
458
0
  struct msghdr  msg;
459
0
  struct cmsghdr  *cmsg;
460
0
  union {
461
0
    struct cmsghdr  hdr;
462
0
    char    buf[CMSG_SPACE(sizeof(int))];
463
0
  } cmsgbuf;
464
465
0
  memset(&iov, 0, sizeof(iov));
466
0
  memset(&msg, 0, sizeof(msg));
467
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
468
0
  TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
469
0
    if (i >= IOV_MAX)
470
0
      break;
471
0
    if (i > 0 && buf->fd != -1)
472
0
      break;
473
0
    iov[i].iov_base = buf->buf + buf->rpos;
474
0
    iov[i].iov_len = buf->wpos - buf->rpos;
475
0
    i++;
476
0
    if (buf->fd != -1)
477
0
      buf0 = buf;
478
0
  }
479
480
0
  msg.msg_iov = iov;
481
0
  msg.msg_iovlen = i;
482
483
0
  if (buf0 != NULL) {
484
0
    msg.msg_control = (caddr_t)&cmsgbuf.buf;
485
0
    msg.msg_controllen = sizeof(cmsgbuf.buf);
486
0
    cmsg = CMSG_FIRSTHDR(&msg);
487
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
488
0
    cmsg->cmsg_level = SOL_SOCKET;
489
0
    cmsg->cmsg_type = SCM_RIGHTS;
490
0
    *(int *)CMSG_DATA(cmsg) = buf0->fd;
491
0
  }
492
493
0
again:
494
0
  if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
495
0
    if (errno == EINTR)
496
0
      goto again;
497
0
    if (errno == ENOBUFS)
498
0
      errno = EAGAIN;
499
0
    return (-1);
500
0
  }
501
502
0
  if (n == 0) {     /* connection closed */
503
0
    errno = 0;
504
0
    return (0);
505
0
  }
506
507
  /*
508
   * assumption: fd got sent if sendmsg sent anything
509
   * this works because fds are passed one at a time
510
   */
511
0
  if (buf0 != NULL) {
512
0
    close(buf0->fd);
513
0
    buf0->fd = -1;
514
0
  }
515
516
0
  msgbuf_drain(msgbuf, n);
517
518
0
  return (1);
519
0
}
520
#endif /* !_WIN32 */
521
522
static void
523
ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
524
0
{
525
0
  TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
526
0
  msgbuf->queued++;
527
0
}
528
529
static void
530
ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
531
0
{
532
0
  TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
533
534
0
  if (buf->fd != -1) {
535
0
    close(buf->fd);
536
0
    buf->fd = -1;
537
0
  }
538
539
0
  msgbuf->queued--;
540
0
  ibuf_free(buf);
541
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.c.html index 8aa9b3cd1..43e32700f 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <unistd.h>
28
29
#include "openbsd-compat.h"
30
#include "imsg.h"
31
32
int  imsg_fd_overhead = 0;
33
34
static int   imsg_get_fd(struct imsgbuf *);
35
36
void
37
imsg_init(struct imsgbuf *ibuf, int fd)
38
0
{
39
0
  msgbuf_init(&ibuf->w);
40
0
  memset(&ibuf->r, 0, sizeof(ibuf->r));
41
0
  ibuf->fd = fd;
42
0
  ibuf->w.fd = fd;
43
0
  ibuf->pid = getpid();
44
0
  TAILQ_INIT(&ibuf->fds);
45
0
}
46
47
#ifdef _WIN32
48
ssize_t
49
imsg_read(struct imsgbuf *ibuf)
50
{
51
  ssize_t      n;
52
  uint8_t     *base;
53
  size_t       len;
54
55
  base = ibuf->r.buf + ibuf->r.wpos;
56
  len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
57
58
  while ((n = recv(ibuf->fd, base, len, 0)) == -1) {
59
    if (errno != EINTR)
60
      return (-1);
61
  }
62
  ibuf->r.wpos += n;
63
  return (n);
64
}
65
#else
66
ssize_t
67
imsg_read(struct imsgbuf *ibuf)
68
0
{
69
0
  struct msghdr    msg;
70
0
  struct cmsghdr    *cmsg;
71
0
  union {
72
0
    struct cmsghdr hdr;
73
0
    char  buf[CMSG_SPACE(sizeof(int) * 1)];
74
0
  } cmsgbuf;
75
0
  struct iovec     iov;
76
0
  ssize_t      n = -1;
77
0
  int      fd;
78
0
  struct imsg_fd    *ifd;
79
80
0
  memset(&msg, 0, sizeof(msg));
81
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
82
83
0
  iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
84
0
  iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
85
0
  msg.msg_iov = &iov;
86
0
  msg.msg_iovlen = 1;
87
0
  msg.msg_control = &cmsgbuf.buf;
88
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
89
90
0
  if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
91
0
    return (-1);
92
93
0
again:
94
0
  if (getdtablecount() + imsg_fd_overhead +
95
0
      (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
96
0
      >= getdtablesize()) {
97
0
    errno = EAGAIN;
98
0
    free(ifd);
99
0
    return (-1);
100
0
  }
101
102
0
  if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
103
0
    if (errno == EINTR)
104
0
      goto again;
105
0
    goto fail;
106
0
  }
107
108
0
  ibuf->r.wpos += n;
109
110
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
111
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
112
0
    if (cmsg->cmsg_level == SOL_SOCKET &&
113
0
        cmsg->cmsg_type == SCM_RIGHTS) {
114
0
      int i;
115
0
      int j;
116
117
      /*
118
       * We only accept one file descriptor.  Due to C
119
       * padding rules, our control buffer might contain
120
       * more than one fd, and we must close them.
121
       */
122
0
      j = ((char *)cmsg + cmsg->cmsg_len -
123
0
          (char *)CMSG_DATA(cmsg)) / sizeof(int);
124
0
      for (i = 0; i < j; i++) {
125
0
        fd = ((int *)CMSG_DATA(cmsg))[i];
126
0
        if (ifd != NULL) {
127
0
          ifd->fd = fd;
128
0
          TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
129
0
              entry);
130
0
          ifd = NULL;
131
0
        } else
132
0
          close(fd);
133
0
      }
134
0
    }
135
    /* we do not handle other ctl data level */
136
0
  }
137
138
0
fail:
139
0
  free(ifd);
140
0
  return (n);
141
0
}
142
#endif
143
144
ssize_t
145
imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
146
0
{
147
0
  size_t       av, left, datalen;
148
149
0
  av = ibuf->r.wpos;
150
151
0
  if (IMSG_HEADER_SIZE > av)
152
0
    return (0);
153
154
0
  memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
155
0
  if (imsg->hdr.len < IMSG_HEADER_SIZE ||
156
0
      imsg->hdr.len > MAX_IMSGSIZE) {
157
0
    errno = ERANGE;
158
0
    return (-1);
159
0
  }
160
0
  if (imsg->hdr.len > av)
161
0
    return (0);
162
0
  datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
163
0
  ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
164
0
  if (datalen == 0)
165
0
    imsg->data = NULL;
166
0
  else if ((imsg->data = malloc(datalen)) == NULL)
167
0
    return (-1);
168
169
0
  if (imsg->hdr.flags & IMSGF_HASFD)
170
0
    imsg->fd = imsg_get_fd(ibuf);
171
0
  else
172
0
    imsg->fd = -1;
173
174
0
  if (datalen != 0)
175
0
    memcpy(imsg->data, ibuf->r.rptr, datalen);
176
177
0
  if (imsg->hdr.len < av) {
178
0
    left = av - imsg->hdr.len;
179
0
    memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
180
0
    ibuf->r.wpos = left;
181
0
  } else
182
0
    ibuf->r.wpos = 0;
183
184
0
  return (datalen + IMSG_HEADER_SIZE);
185
0
}
186
187
int
188
imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
189
    int fd, const void *data, uint16_t datalen)
190
0
{
191
0
  struct ibuf *wbuf;
192
193
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
194
0
    return (-1);
195
196
0
  if (imsg_add(wbuf, data, datalen) == -1)
197
0
    return (-1);
198
199
0
  ibuf_fd_set(wbuf, fd);
200
201
0
  imsg_close(ibuf, wbuf);
202
203
0
  return (1);
204
0
}
205
206
int
207
imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
208
    int fd, const struct iovec *iov, int iovcnt)
209
0
{
210
0
  struct ibuf *wbuf;
211
0
  int    i, datalen = 0;
212
213
0
  for (i = 0; i < iovcnt; i++)
214
0
    datalen += iov[i].iov_len;
215
216
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
217
0
    return (-1);
218
219
0
  for (i = 0; i < iovcnt; i++)
220
0
    if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
221
0
      return (-1);
222
223
0
  ibuf_fd_set(wbuf, fd);
224
225
0
  imsg_close(ibuf, wbuf);
226
227
0
  return (1);
228
0
}
229
230
int
231
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
232
    pid_t pid, struct ibuf *buf)
233
0
{
234
0
  struct ibuf *wbuf = NULL;
235
0
  struct imsg_hdr  hdr;
236
0
  int save_errno;
237
238
0
  if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
239
0
    errno = ERANGE;
240
0
    goto fail;
241
0
  }
242
243
0
  hdr.type = type;
244
0
  hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
245
0
  hdr.flags = 0;
246
0
  hdr.peerid = peerid;
247
0
  if ((hdr.pid = pid) == 0)
248
0
    hdr.pid = ibuf->pid;
249
250
0
  if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
251
0
    goto fail;
252
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
253
0
    goto fail;
254
255
0
  ibuf_close(&ibuf->w, wbuf);
256
0
  ibuf_close(&ibuf->w, buf);
257
0
  return (1);
258
259
0
 fail:
260
0
  save_errno = errno;
261
0
  ibuf_free(buf);
262
0
  ibuf_free(wbuf);
263
0
  errno = save_errno;
264
0
  return (-1);
265
0
}
266
267
struct ibuf *
268
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
269
    uint16_t datalen)
270
0
{
271
0
  struct ibuf *wbuf;
272
0
  struct imsg_hdr  hdr;
273
274
0
  datalen += IMSG_HEADER_SIZE;
275
0
  if (datalen > MAX_IMSGSIZE) {
276
0
    errno = ERANGE;
277
0
    return (NULL);
278
0
  }
279
280
0
  hdr.type = type;
281
0
  hdr.flags = 0;
282
0
  hdr.peerid = peerid;
283
0
  if ((hdr.pid = pid) == 0)
284
0
    hdr.pid = ibuf->pid;
285
0
  if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
286
0
    return (NULL);
287
0
  }
288
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
289
0
    return (NULL);
290
291
0
  return (wbuf);
292
0
}
293
294
int
295
imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
296
0
{
297
0
  if (datalen)
298
0
    if (ibuf_add(msg, data, datalen) == -1) {
299
0
      ibuf_free(msg);
300
0
      return (-1);
301
0
    }
302
0
  return (datalen);
303
0
}
304
305
void
306
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
307
0
{
308
0
  struct imsg_hdr *hdr;
309
310
0
  hdr = (struct imsg_hdr *)msg->buf;
311
312
0
  hdr->flags &= ~IMSGF_HASFD;
313
0
  if (ibuf_fd_avail(msg))
314
0
    hdr->flags |= IMSGF_HASFD;
315
0
  hdr->len = ibuf_size(msg);
316
317
0
  ibuf_close(&ibuf->w, msg);
318
0
}
319
320
void
321
imsg_free(struct imsg *imsg)
322
0
{
323
0
  freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
324
0
}
325
326
static int
327
imsg_get_fd(struct imsgbuf *ibuf)
328
0
{
329
0
  int    fd;
330
0
  struct imsg_fd  *ifd;
331
332
0
  if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
333
0
    return (-1);
334
335
0
  fd = ifd->fd;
336
0
  TAILQ_REMOVE(&ibuf->fds, ifd, entry);
337
0
  free(ifd);
338
339
0
  return (fd);
340
0
}
341
342
int
343
imsg_flush(struct imsgbuf *ibuf)
344
0
{
345
0
  while (ibuf->w.queued)
346
0
    if (msgbuf_write(&ibuf->w) <= 0)
347
0
      return (-1);
348
0
  return (0);
349
0
}
350
351
void
352
imsg_clear(struct imsgbuf *ibuf)
353
0
{
354
0
  int fd;
355
356
0
  msgbuf_clear(&ibuf->w);
357
0
  while ((fd = imsg_get_fd(ibuf)) != -1)
358
0
    close(fd);
359
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.c,v 1.19 2023/06/19 17:19:50 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/queue.h>
21
#include <sys/socket.h>
22
#include <sys/uio.h>
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <unistd.h>
28
29
#include "openbsd-compat.h"
30
#include "imsg.h"
31
32
int  imsg_fd_overhead = 0;
33
34
static int   imsg_get_fd(struct imsgbuf *);
35
36
void
37
imsg_init(struct imsgbuf *ibuf, int fd)
38
0
{
39
0
  msgbuf_init(&ibuf->w);
40
0
  memset(&ibuf->r, 0, sizeof(ibuf->r));
41
0
  ibuf->fd = fd;
42
0
  ibuf->w.fd = fd;
43
0
  ibuf->pid = getpid();
44
0
  TAILQ_INIT(&ibuf->fds);
45
0
}
46
47
#ifdef _WIN32
48
ssize_t
49
imsg_read(struct imsgbuf *ibuf)
50
{
51
  ssize_t      n;
52
  uint8_t     *base;
53
  size_t       len;
54
55
  base = ibuf->r.buf + ibuf->r.wpos;
56
  len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
57
58
  while ((n = recv(ibuf->fd, base, len, 0)) == -1) {
59
    if (errno != EINTR)
60
      return (-1);
61
  }
62
  ibuf->r.wpos += n;
63
  return (n);
64
}
65
#else
66
ssize_t
67
imsg_read(struct imsgbuf *ibuf)
68
0
{
69
0
  struct msghdr    msg;
70
0
  struct cmsghdr    *cmsg;
71
0
  union {
72
0
    struct cmsghdr hdr;
73
0
    char  buf[CMSG_SPACE(sizeof(int) * 1)];
74
0
  } cmsgbuf;
75
0
  struct iovec     iov;
76
0
  ssize_t      n = -1;
77
0
  int      fd;
78
0
  struct imsg_fd    *ifd;
79
80
0
  memset(&msg, 0, sizeof(msg));
81
0
  memset(&cmsgbuf, 0, sizeof(cmsgbuf));
82
83
0
  iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
84
0
  iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
85
0
  msg.msg_iov = &iov;
86
0
  msg.msg_iovlen = 1;
87
0
  msg.msg_control = &cmsgbuf.buf;
88
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
89
90
0
  if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
91
0
    return (-1);
92
93
0
again:
94
0
  if (getdtablecount() + imsg_fd_overhead +
95
0
      (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
96
0
      >= getdtablesize()) {
97
0
    errno = EAGAIN;
98
0
    free(ifd);
99
0
    return (-1);
100
0
  }
101
102
0
  if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
103
0
    if (errno == EINTR)
104
0
      goto again;
105
0
    goto fail;
106
0
  }
107
108
0
  ibuf->r.wpos += n;
109
110
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
111
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
112
0
    if (cmsg->cmsg_level == SOL_SOCKET &&
113
0
        cmsg->cmsg_type == SCM_RIGHTS) {
114
0
      int i;
115
0
      int j;
116
117
      /*
118
       * We only accept one file descriptor.  Due to C
119
       * padding rules, our control buffer might contain
120
       * more than one fd, and we must close them.
121
       */
122
0
      j = ((char *)cmsg + cmsg->cmsg_len -
123
0
          (char *)CMSG_DATA(cmsg)) / sizeof(int);
124
0
      for (i = 0; i < j; i++) {
125
0
        fd = ((int *)CMSG_DATA(cmsg))[i];
126
0
        if (ifd != NULL) {
127
0
          ifd->fd = fd;
128
0
          TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
129
0
              entry);
130
0
          ifd = NULL;
131
0
        } else
132
0
          close(fd);
133
0
      }
134
0
    }
135
    /* we do not handle other ctl data level */
136
0
  }
137
138
0
fail:
139
0
  free(ifd);
140
0
  return (n);
141
0
}
142
#endif
143
144
ssize_t
145
imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
146
0
{
147
0
  size_t       av, left, datalen;
148
149
0
  av = ibuf->r.wpos;
150
151
0
  if (IMSG_HEADER_SIZE > av)
152
0
    return (0);
153
154
0
  memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
155
0
  if (imsg->hdr.len < IMSG_HEADER_SIZE ||
156
0
      imsg->hdr.len > MAX_IMSGSIZE) {
157
0
    errno = ERANGE;
158
0
    return (-1);
159
0
  }
160
0
  if (imsg->hdr.len > av)
161
0
    return (0);
162
0
  datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
163
0
  ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
164
0
  if (datalen == 0)
165
0
    imsg->data = NULL;
166
0
  else if ((imsg->data = malloc(datalen)) == NULL)
167
0
    return (-1);
168
169
0
  if (imsg->hdr.flags & IMSGF_HASFD)
170
0
    imsg->fd = imsg_get_fd(ibuf);
171
0
  else
172
0
    imsg->fd = -1;
173
174
0
  if (datalen != 0)
175
0
    memcpy(imsg->data, ibuf->r.rptr, datalen);
176
177
0
  if (imsg->hdr.len < av) {
178
0
    left = av - imsg->hdr.len;
179
0
    memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
180
0
    ibuf->r.wpos = left;
181
0
  } else
182
0
    ibuf->r.wpos = 0;
183
184
0
  return (datalen + IMSG_HEADER_SIZE);
185
0
}
186
187
int
188
imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
189
    int fd, const void *data, uint16_t datalen)
190
0
{
191
0
  struct ibuf *wbuf;
192
193
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
194
0
    return (-1);
195
196
0
  if (imsg_add(wbuf, data, datalen) == -1)
197
0
    return (-1);
198
199
0
  ibuf_fd_set(wbuf, fd);
200
201
0
  imsg_close(ibuf, wbuf);
202
203
0
  return (1);
204
0
}
205
206
int
207
imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
208
    int fd, const struct iovec *iov, int iovcnt)
209
0
{
210
0
  struct ibuf *wbuf;
211
0
  int    i, datalen = 0;
212
213
0
  for (i = 0; i < iovcnt; i++)
214
0
    datalen += iov[i].iov_len;
215
216
0
  if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
217
0
    return (-1);
218
219
0
  for (i = 0; i < iovcnt; i++)
220
0
    if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
221
0
      return (-1);
222
223
0
  ibuf_fd_set(wbuf, fd);
224
225
0
  imsg_close(ibuf, wbuf);
226
227
0
  return (1);
228
0
}
229
230
int
231
imsg_compose_ibuf(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid,
232
    pid_t pid, struct ibuf *buf)
233
0
{
234
0
  struct ibuf *wbuf = NULL;
235
0
  struct imsg_hdr  hdr;
236
0
  int save_errno;
237
238
0
  if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
239
0
    errno = ERANGE;
240
0
    goto fail;
241
0
  }
242
243
0
  hdr.type = type;
244
0
  hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
245
0
  hdr.flags = 0;
246
0
  hdr.peerid = peerid;
247
0
  if ((hdr.pid = pid) == 0)
248
0
    hdr.pid = ibuf->pid;
249
250
0
  if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
251
0
    goto fail;
252
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
253
0
    goto fail;
254
255
0
  ibuf_close(&ibuf->w, wbuf);
256
0
  ibuf_close(&ibuf->w, buf);
257
0
  return (1);
258
259
0
 fail:
260
0
  save_errno = errno;
261
0
  ibuf_free(buf);
262
0
  ibuf_free(wbuf);
263
0
  errno = save_errno;
264
0
  return (-1);
265
0
}
266
267
struct ibuf *
268
imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
269
    uint16_t datalen)
270
0
{
271
0
  struct ibuf *wbuf;
272
0
  struct imsg_hdr  hdr;
273
274
0
  datalen += IMSG_HEADER_SIZE;
275
0
  if (datalen > MAX_IMSGSIZE) {
276
0
    errno = ERANGE;
277
0
    return (NULL);
278
0
  }
279
280
0
  hdr.type = type;
281
0
  hdr.flags = 0;
282
0
  hdr.peerid = peerid;
283
0
  if ((hdr.pid = pid) == 0)
284
0
    hdr.pid = ibuf->pid;
285
0
  if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
286
0
    return (NULL);
287
0
  }
288
0
  if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
289
0
    return (NULL);
290
291
0
  return (wbuf);
292
0
}
293
294
int
295
imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
296
0
{
297
0
  if (datalen)
298
0
    if (ibuf_add(msg, data, datalen) == -1) {
299
0
      ibuf_free(msg);
300
0
      return (-1);
301
0
    }
302
0
  return (datalen);
303
0
}
304
305
void
306
imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
307
0
{
308
0
  struct imsg_hdr *hdr;
309
310
0
  hdr = (struct imsg_hdr *)msg->buf;
311
312
0
  hdr->flags &= ~IMSGF_HASFD;
313
0
  if (ibuf_fd_avail(msg))
314
0
    hdr->flags |= IMSGF_HASFD;
315
0
  hdr->len = ibuf_size(msg);
316
317
0
  ibuf_close(&ibuf->w, msg);
318
0
}
319
320
void
321
imsg_free(struct imsg *imsg)
322
0
{
323
0
  freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
324
0
}
325
326
static int
327
imsg_get_fd(struct imsgbuf *ibuf)
328
0
{
329
0
  int    fd;
330
0
  struct imsg_fd  *ifd;
331
332
0
  if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
333
0
    return (-1);
334
335
0
  fd = ifd->fd;
336
0
  TAILQ_REMOVE(&ibuf->fds, ifd, entry);
337
0
  free(ifd);
338
339
0
  return (fd);
340
0
}
341
342
int
343
imsg_flush(struct imsgbuf *ibuf)
344
0
{
345
0
  while (ibuf->w.queued)
346
0
    if (msgbuf_write(&ibuf->w) <= 0)
347
0
      return (-1);
348
0
  return (0);
349
0
}
350
351
void
352
imsg_clear(struct imsgbuf *ibuf)
353
0
{
354
0
  int fd;
355
356
0
  msgbuf_clear(&ibuf->w);
357
0
  while ((fd = imsg_get_fd(ibuf)) != -1)
358
0
    close(fd);
359
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.h.html index 729f4879a..b8e4e4302 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/imsg.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/imsg.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
5
 * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#ifndef _IMSG_H_
22
#define _IMSG_H_
23
24
#include <stdint.h>
25
26
#define IBUF_READ_SIZE    65535
27
0
#define IMSG_HEADER_SIZE  sizeof(struct imsg_hdr)
28
0
#define MAX_IMSGSIZE    16384
29
30
struct ibuf {
31
  TAILQ_ENTRY(ibuf)  entry;
32
  unsigned char   *buf;
33
  size_t       size;
34
  size_t       max;
35
  size_t       wpos;
36
  size_t       rpos;
37
  int      fd;
38
};
39
40
struct msgbuf {
41
  TAILQ_HEAD(, ibuf)   bufs;
42
  uint32_t     queued;
43
  int      fd;
44
};
45
46
struct ibuf_read {
47
  unsigned char    buf[IBUF_READ_SIZE];
48
  unsigned char   *rptr;
49
  size_t       wpos;
50
};
51
52
struct imsg_fd {
53
  TAILQ_ENTRY(imsg_fd)  entry;
54
  int     fd;
55
};
56
57
struct imsgbuf {
58
  TAILQ_HEAD(, imsg_fd)  fds;
59
  struct ibuf_read   r;
60
  struct msgbuf    w;
61
  int      fd;
62
  pid_t      pid;
63
};
64
65
0
#define IMSGF_HASFD 1
66
67
struct imsg_hdr {
68
  uint32_t   type;
69
  uint16_t   len;
70
  uint16_t   flags;
71
  uint32_t   peerid;
72
  uint32_t   pid;
73
};
74
75
struct imsg {
76
  struct imsg_hdr  hdr;
77
  int    fd;
78
  void    *data;
79
};
80
81
struct iovec;
82
83
/* imsg-buffer.c */
84
struct ibuf *ibuf_open(size_t);
85
struct ibuf *ibuf_dynamic(size_t, size_t);
86
int    ibuf_add(struct ibuf *, const void *, size_t);
87
int    ibuf_add_buf(struct ibuf *, const struct ibuf *);
88
int    ibuf_add_zero(struct ibuf *, size_t);
89
int    ibuf_add_n8(struct ibuf *, uint64_t);
90
int    ibuf_add_n16(struct ibuf *, uint64_t);
91
int    ibuf_add_n32(struct ibuf *, uint64_t);
92
int    ibuf_add_n64(struct ibuf *, uint64_t);
93
void    *ibuf_reserve(struct ibuf *, size_t);
94
void    *ibuf_seek(struct ibuf *, size_t, size_t);
95
int    ibuf_set(struct ibuf *, size_t, const void *, size_t);
96
int    ibuf_set_n8(struct ibuf *, size_t, uint64_t);
97
int    ibuf_set_n16(struct ibuf *, size_t, uint64_t);
98
int    ibuf_set_n32(struct ibuf *, size_t, uint64_t);
99
int    ibuf_set_n64(struct ibuf *, size_t, uint64_t);
100
void    *ibuf_data(struct ibuf *);
101
size_t     ibuf_size(struct ibuf *);
102
size_t     ibuf_left(struct ibuf *);
103
void     ibuf_close(struct msgbuf *, struct ibuf *);
104
void     ibuf_free(struct ibuf *);
105
int    ibuf_fd_avail(struct ibuf *);
106
int    ibuf_fd_get(struct ibuf *);
107
void     ibuf_fd_set(struct ibuf *, int);
108
int    ibuf_write(struct msgbuf *);
109
void     msgbuf_init(struct msgbuf *);
110
void     msgbuf_clear(struct msgbuf *);
111
int    msgbuf_write(struct msgbuf *);
112
113
/* imsg.c */
114
void   imsg_init(struct imsgbuf *, int);
115
ssize_t  imsg_read(struct imsgbuf *);
116
ssize_t  imsg_get(struct imsgbuf *, struct imsg *);
117
int  imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
118
      const void *, uint16_t);
119
int  imsg_composev(struct imsgbuf *, uint32_t, uint32_t,  pid_t, int,
120
      const struct iovec *, int);
121
int  imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
122
      struct ibuf *);
123
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
124
int  imsg_add(struct ibuf *, const void *, uint16_t);
125
void   imsg_close(struct imsgbuf *, struct ibuf *);
126
void   imsg_free(struct imsg *);
127
int  imsg_flush(struct imsgbuf *);
128
void   imsg_clear(struct imsgbuf *);
129
130
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/imsg.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
5
 * Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#ifndef _IMSG_H_
22
#define _IMSG_H_
23
24
#include <stdint.h>
25
26
#define IBUF_READ_SIZE    65535
27
0
#define IMSG_HEADER_SIZE  sizeof(struct imsg_hdr)
28
0
#define MAX_IMSGSIZE    16384
29
30
struct ibuf {
31
  TAILQ_ENTRY(ibuf)  entry;
32
  unsigned char   *buf;
33
  size_t       size;
34
  size_t       max;
35
  size_t       wpos;
36
  size_t       rpos;
37
  int      fd;
38
};
39
40
struct msgbuf {
41
  TAILQ_HEAD(, ibuf)   bufs;
42
  uint32_t     queued;
43
  int      fd;
44
};
45
46
struct ibuf_read {
47
  unsigned char    buf[IBUF_READ_SIZE];
48
  unsigned char   *rptr;
49
  size_t       wpos;
50
};
51
52
struct imsg_fd {
53
  TAILQ_ENTRY(imsg_fd)  entry;
54
  int     fd;
55
};
56
57
struct imsgbuf {
58
  TAILQ_HEAD(, imsg_fd)  fds;
59
  struct ibuf_read   r;
60
  struct msgbuf    w;
61
  int      fd;
62
  pid_t      pid;
63
};
64
65
0
#define IMSGF_HASFD 1
66
67
struct imsg_hdr {
68
  uint32_t   type;
69
  uint16_t   len;
70
  uint16_t   flags;
71
  uint32_t   peerid;
72
  uint32_t   pid;
73
};
74
75
struct imsg {
76
  struct imsg_hdr  hdr;
77
  int    fd;
78
  void    *data;
79
};
80
81
struct iovec;
82
83
/* imsg-buffer.c */
84
struct ibuf *ibuf_open(size_t);
85
struct ibuf *ibuf_dynamic(size_t, size_t);
86
int    ibuf_add(struct ibuf *, const void *, size_t);
87
int    ibuf_add_buf(struct ibuf *, const struct ibuf *);
88
int    ibuf_add_zero(struct ibuf *, size_t);
89
int    ibuf_add_n8(struct ibuf *, uint64_t);
90
int    ibuf_add_n16(struct ibuf *, uint64_t);
91
int    ibuf_add_n32(struct ibuf *, uint64_t);
92
int    ibuf_add_n64(struct ibuf *, uint64_t);
93
void    *ibuf_reserve(struct ibuf *, size_t);
94
void    *ibuf_seek(struct ibuf *, size_t, size_t);
95
int    ibuf_set(struct ibuf *, size_t, const void *, size_t);
96
int    ibuf_set_n8(struct ibuf *, size_t, uint64_t);
97
int    ibuf_set_n16(struct ibuf *, size_t, uint64_t);
98
int    ibuf_set_n32(struct ibuf *, size_t, uint64_t);
99
int    ibuf_set_n64(struct ibuf *, size_t, uint64_t);
100
void    *ibuf_data(struct ibuf *);
101
size_t     ibuf_size(struct ibuf *);
102
size_t     ibuf_left(struct ibuf *);
103
void     ibuf_close(struct msgbuf *, struct ibuf *);
104
void     ibuf_free(struct ibuf *);
105
int    ibuf_fd_avail(struct ibuf *);
106
int    ibuf_fd_get(struct ibuf *);
107
void     ibuf_fd_set(struct ibuf *, int);
108
int    ibuf_write(struct msgbuf *);
109
void     msgbuf_init(struct msgbuf *);
110
void     msgbuf_clear(struct msgbuf *);
111
int    msgbuf_write(struct msgbuf *);
112
113
/* imsg.c */
114
void   imsg_init(struct imsgbuf *, int);
115
ssize_t  imsg_read(struct imsgbuf *);
116
ssize_t  imsg_get(struct imsgbuf *, struct imsg *);
117
int  imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int,
118
      const void *, uint16_t);
119
int  imsg_composev(struct imsgbuf *, uint32_t, uint32_t,  pid_t, int,
120
      const struct iovec *, int);
121
int  imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t,
122
      struct ibuf *);
123
struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t);
124
int  imsg_add(struct ibuf *, const void *, uint16_t);
125
void   imsg_close(struct imsgbuf *, struct ibuf *);
126
void   imsg_free(struct imsg *);
127
int  imsg_flush(struct imsgbuf *);
128
void   imsg_clear(struct imsgbuf *);
129
130
#endif
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/openbsd-compat.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/openbsd-compat.h.html index 55a2c973d..e4824fc0a 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/openbsd-compat.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/openbsd-compat.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/openbsd-compat.h
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#ifndef _OPENBSD_COMPAT_H
4
#define _OPENBSD_COMPAT_H
5
6
#define YYSTYPE_IS_DECLARED 1 /* for bison */
7
8
#ifndef LOGIN_NAME_MAX
9
# define LOGIN_NAME_MAX 9
10
#endif
11
12
#include <stdlib.h>
13
14
#if !defined(HAVE_STRLCAT)
15
size_t strlcat(char *, const char *, size_t);
16
#endif
17
18
#if !defined(HAVE_STRLCPY)
19
size_t strlcpy(char *, const char *, size_t);
20
#endif
21
22
#if !defined(HAVE_REALLOCARRAY)
23
void *reallocarray(void *, size_t, size_t);
24
#endif
25
26
#if !defined(HAVE_RECALLOCARRAY)
27
void *recallocarray(void *, size_t, size_t, size_t);
28
#endif
29
30
#if !defined(HAVE_EXPLICIT_BZERO)
31
void explicit_bzero(void *, size_t);
32
#endif
33
34
#if !defined(HAVE_GETPAGESIZE)
35
int getpagesize(void);
36
#endif
37
38
#if !defined(HAVE_TIMINGSAFE_BCMP)
39
int timingsafe_bcmp(const void *, const void *, size_t);
40
#endif
41
42
#if !defined(HAVE_ACCEPT4)
43
#include <sys/socket.h>
44
#define accept4 bsd_accept4
45
int bsd_accept4(int, struct sockaddr *, socklen_t *, int flags);
46
#endif
47
48
#if !defined(HAVE_SOCK_NONBLOCK)
49
#define SOCK_NONBLOCK 0x4000  /* Set O_NONBLOCK */
50
#define SOCK_CLOEXEC  0x8000  /* Set FD_CLOEXEC */
51
#define SOCK_SETFLAGS 0xf000  /* Set flags as checked above */
52
#define socket bsd_socket
53
int bsd_socket(int domain, int type, int protocol);
54
#endif
55
56
#if !defined(HAVE_SETPROCTITLE)
57
void compat_init_setproctitle(int argc, char *argv[]);
58
void setproctitle(const char *fmt, ...);
59
#endif
60
61
#if !defined(HAVE_SETRESGID)
62
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
63
#endif
64
65
#if !defined(HAVE_SETRESUID)
66
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
67
#endif
68
69
#ifdef _WIN32
70
#include <direct.h>
71
uid_t geteuid(void);
72
#endif
73
74
#if !defined(HAVE_GETRTABLE)
75
int getrtable(void);
76
#endif
77
78
#if !defined(HAVE_SETRTABLE)
79
int setrtable(int rtableid);
80
#endif
81
82
#if !defined(HAVE_STRTONUM)
83
long long
84
strtonum(const char *nptr, long long minval, long long maxval,
85
    const char **errstr);
86
#endif
87
88
#if !defined(HAVE_FREEZERO)
89
void freezero(void *ptr, size_t size);
90
#endif
91
92
#if !defined(HAVE_GETDTABLECOUNT)
93
int getdtablecount(void);
94
#endif
95
96
#if !defined(HAVE_GETOPT)
97
#include "getopt.h"
98
#endif
99
100
#if !defined(HAVE_USLEEP)
101
int usleep(unsigned int x);
102
#endif
103
104
#ifdef HAVE_SOCKADDR_SA_LEN
105
#ifndef SA_LEN
106
#define SA_LEN(sa)      (sa)->sa_len
107
#endif
108
#ifndef SS_LEN
109
#define SS_LEN(ss)      (ss).ss_len
110
#endif
111
#else
112
#define SA_LEN(sa)                  \
113
14.0k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
14.0k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
2.24k
  sizeof(struct sockaddr))
116
#define SS_LEN(ss)              \
117
  ((ss.ss_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
118
  (ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
119
  sizeof(struct sockaddr_storage))
120
#endif
121
122
#ifndef HAVE_FFS
123
int ffs(int);
124
#endif
125
126
#ifdef __OpenBSD__
127
typedef int evutil_socket_t;
128
#endif
129
130
#ifndef _PASSWORD_LEN
131
#define _PASSWORD_LEN 120
132
#endif
133
134
#ifdef HAVE_DIRENT_H
135
# include <dirent.h>
136
# define NAMLEN(dirent) strlen((dirent)->d_name)
137
#else
138
# define dirent direct
139
# define NAMLEN(dirent) (dirent)->d_namlen
140
# ifdef HAVE_SYS_NDIR_H
141
#  include <sys/ndir.h>
142
# endif
143
# ifdef HAVE_SYS_DIR_H
144
#  include <sys/dir.h>
145
# endif
146
# ifdef HAVE_NDIR_H
147
#  include <ndir.h>
148
# endif
149
#endif
150
151
#if !defined(AF_LINK) && defined(AF_PACKET)
152
#define AF_LINK AF_PACKET /* XXX workaround on Linux */
153
#endif
154
155
#ifndef HOST_NAME_MAX
156
# include "netdb.h" /* for MAXHOSTNAMELEN */
157
# if defined(_POSIX_HOST_NAME_MAX)
158
#  define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
159
# elif defined(MAXHOSTNAMELEN)
160
#  define HOST_NAME_MAX MAXHOSTNAMELEN
161
# else
162
#  define HOST_NAME_MAX 255
163
# endif
164
#endif /* HOST_NAME_MAX */
165
166
/* FreeBSD */
167
#ifndef CPI_PRIVATE_MIN
168
#define CPI_PRIVATE_MIN   61440
169
#endif
170
#ifndef CPI_PRIVATE_MAX
171
#define CPI_PRIVATE_MAX   65535
172
#endif
173
174
#if !defined(SADB_X_ADDFLOW) && defined(SADB_X_SPDUPDATE)
175
#define SADB_X_ADDFLOW  SADB_X_SPDUPDATE
176
#endif
177
#if !defined(SADB_X_DELFLOW) && defined(SADB_X_SPDDELETE)
178
#define SADB_X_DELFLOW  SADB_X_SPDDELETE
179
#endif
180
#if !defined(SADB_X_FLOW_TYPE_DENY)
181
#define SADB_X_FLOW_TYPE_DENY 1
182
#endif
183
184
#if defined(HAVE_LINUX_PFKEY_H)
185
/* Encryption Algorithms */
186
#define SADB_X_EALG_AES   SADB_X_EALG_AESCBC
187
#define SADB_X_EALG_AESGCM16  SADB_X_EALG_AES_GCM_ICV16
188
#define SADB_X_EALG_AESGMAC SADB_X_EALG_NULL_AES_GMAC
189
190
/* Authentication Algorithms */
191
#define SADB_X_AALG_SHA2_256  SADB_X_AALG_SHA2_256HMAC
192
#define SADB_X_AALG_SHA2_384  SADB_X_AALG_SHA2_384HMAC
193
#define SADB_X_AALG_SHA2_512  SADB_X_AALG_SHA2_512HMAC
194
#endif
195
196
#if !defined(__packed)
197
#define __packed  __attribute__((__packed__))
198
#endif
199
200
#if defined(HAVE_APPLE_NATT) && !defined(SADB_X_EXT_NATT)
201
/*
202
 * These are hidden in Apple XNU's private pfkeyv2.h header
203
 */
204
#define SADB_X_EXT_NATT     0x0002  /* Enable UDP encapsulation */
205
#define SADB_X_EXT_NATT_KEEPALIVE 0x0004  /* Send NAT-T keepalives */
206
#define SADB_X_EXT_NATT_MULTIPLEUSERS 0x0008  /* Use for VPN gateways */
207
#define SADB_X_EXT_NATT_DETECTED_PEER 0x1000  /* Opposite of KEEPALIVE */
208
209
struct sadb_sa_natt {
210
  uint16_t   sadb_sa_natt_port;
211
  union {
212
    uint16_t   sadb_reserved0;
213
    uint16_t   sadb_sa_natt_interval;
214
  };
215
  uint16_t   sadb_sa_natt_offload_interval;
216
  uint16_t   sadb_sa_natt_src_port;
217
};
218
#endif
219
220
#endif /* !_OPENBSD_COMPAT_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/openbsd-compat.h
Line
Count
Source (jump to first uncovered line)
1
/* Placed in the public domain */
2
3
#ifndef _OPENBSD_COMPAT_H
4
#define _OPENBSD_COMPAT_H
5
6
#define YYSTYPE_IS_DECLARED 1 /* for bison */
7
8
#ifndef LOGIN_NAME_MAX
9
# define LOGIN_NAME_MAX 9
10
#endif
11
12
#include <stdlib.h>
13
14
#if !defined(HAVE_STRLCAT)
15
size_t strlcat(char *, const char *, size_t);
16
#endif
17
18
#if !defined(HAVE_STRLCPY)
19
size_t strlcpy(char *, const char *, size_t);
20
#endif
21
22
#if !defined(HAVE_REALLOCARRAY)
23
void *reallocarray(void *, size_t, size_t);
24
#endif
25
26
#if !defined(HAVE_RECALLOCARRAY)
27
void *recallocarray(void *, size_t, size_t, size_t);
28
#endif
29
30
#if !defined(HAVE_EXPLICIT_BZERO)
31
void explicit_bzero(void *, size_t);
32
#endif
33
34
#if !defined(HAVE_GETPAGESIZE)
35
int getpagesize(void);
36
#endif
37
38
#if !defined(HAVE_TIMINGSAFE_BCMP)
39
int timingsafe_bcmp(const void *, const void *, size_t);
40
#endif
41
42
#if !defined(HAVE_ACCEPT4)
43
#include <sys/socket.h>
44
#define accept4 bsd_accept4
45
int bsd_accept4(int, struct sockaddr *, socklen_t *, int flags);
46
#endif
47
48
#if !defined(HAVE_SOCK_NONBLOCK)
49
#define SOCK_NONBLOCK 0x4000  /* Set O_NONBLOCK */
50
#define SOCK_CLOEXEC  0x8000  /* Set FD_CLOEXEC */
51
#define SOCK_SETFLAGS 0xf000  /* Set flags as checked above */
52
#define socket bsd_socket
53
int bsd_socket(int domain, int type, int protocol);
54
#endif
55
56
#if !defined(HAVE_SETPROCTITLE)
57
void compat_init_setproctitle(int argc, char *argv[]);
58
void setproctitle(const char *fmt, ...);
59
#endif
60
61
#if !defined(HAVE_SETRESGID)
62
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
63
#endif
64
65
#if !defined(HAVE_SETRESUID)
66
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
67
#endif
68
69
#ifdef _WIN32
70
#include <direct.h>
71
uid_t geteuid(void);
72
#endif
73
74
#if !defined(HAVE_GETRTABLE)
75
int getrtable(void);
76
#endif
77
78
#if !defined(HAVE_SETRTABLE)
79
int setrtable(int rtableid);
80
#endif
81
82
#if !defined(HAVE_STRTONUM)
83
long long
84
strtonum(const char *nptr, long long minval, long long maxval,
85
    const char **errstr);
86
#endif
87
88
#if !defined(HAVE_FREEZERO)
89
void freezero(void *ptr, size_t size);
90
#endif
91
92
#if !defined(HAVE_GETDTABLECOUNT)
93
int getdtablecount(void);
94
#endif
95
96
#if !defined(HAVE_GETOPT)
97
#include "getopt.h"
98
#endif
99
100
#if !defined(HAVE_USLEEP)
101
int usleep(unsigned int x);
102
#endif
103
104
#ifdef HAVE_SOCKADDR_SA_LEN
105
#ifndef SA_LEN
106
#define SA_LEN(sa)      (sa)->sa_len
107
#endif
108
#ifndef SS_LEN
109
#define SS_LEN(ss)      (ss).ss_len
110
#endif
111
#else
112
#define SA_LEN(sa)                  \
113
14.2k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
14.2k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
2.27k
  sizeof(struct sockaddr))
116
#define SS_LEN(ss)              \
117
  ((ss.ss_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
118
  (ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
119
  sizeof(struct sockaddr_storage))
120
#endif
121
122
#ifndef HAVE_FFS
123
int ffs(int);
124
#endif
125
126
#ifdef __OpenBSD__
127
typedef int evutil_socket_t;
128
#endif
129
130
#ifndef _PASSWORD_LEN
131
#define _PASSWORD_LEN 120
132
#endif
133
134
#ifdef HAVE_DIRENT_H
135
# include <dirent.h>
136
# define NAMLEN(dirent) strlen((dirent)->d_name)
137
#else
138
# define dirent direct
139
# define NAMLEN(dirent) (dirent)->d_namlen
140
# ifdef HAVE_SYS_NDIR_H
141
#  include <sys/ndir.h>
142
# endif
143
# ifdef HAVE_SYS_DIR_H
144
#  include <sys/dir.h>
145
# endif
146
# ifdef HAVE_NDIR_H
147
#  include <ndir.h>
148
# endif
149
#endif
150
151
#if !defined(AF_LINK) && defined(AF_PACKET)
152
#define AF_LINK AF_PACKET /* XXX workaround on Linux */
153
#endif
154
155
#ifndef HOST_NAME_MAX
156
# include "netdb.h" /* for MAXHOSTNAMELEN */
157
# if defined(_POSIX_HOST_NAME_MAX)
158
#  define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
159
# elif defined(MAXHOSTNAMELEN)
160
#  define HOST_NAME_MAX MAXHOSTNAMELEN
161
# else
162
#  define HOST_NAME_MAX 255
163
# endif
164
#endif /* HOST_NAME_MAX */
165
166
/* FreeBSD */
167
#ifndef CPI_PRIVATE_MIN
168
#define CPI_PRIVATE_MIN   61440
169
#endif
170
#ifndef CPI_PRIVATE_MAX
171
#define CPI_PRIVATE_MAX   65535
172
#endif
173
174
#if !defined(SADB_X_ADDFLOW) && defined(SADB_X_SPDUPDATE)
175
#define SADB_X_ADDFLOW  SADB_X_SPDUPDATE
176
#endif
177
#if !defined(SADB_X_DELFLOW) && defined(SADB_X_SPDDELETE)
178
#define SADB_X_DELFLOW  SADB_X_SPDDELETE
179
#endif
180
#if !defined(SADB_X_FLOW_TYPE_DENY)
181
#define SADB_X_FLOW_TYPE_DENY 1
182
#endif
183
184
#if defined(HAVE_LINUX_PFKEY_H)
185
/* Encryption Algorithms */
186
#define SADB_X_EALG_AES   SADB_X_EALG_AESCBC
187
#define SADB_X_EALG_AESGCM16  SADB_X_EALG_AES_GCM_ICV16
188
#define SADB_X_EALG_AESGMAC SADB_X_EALG_NULL_AES_GMAC
189
190
/* Authentication Algorithms */
191
#define SADB_X_AALG_SHA2_256  SADB_X_AALG_SHA2_256HMAC
192
#define SADB_X_AALG_SHA2_384  SADB_X_AALG_SHA2_384HMAC
193
#define SADB_X_AALG_SHA2_512  SADB_X_AALG_SHA2_512HMAC
194
#endif
195
196
#if !defined(__packed)
197
#define __packed  __attribute__((__packed__))
198
#endif
199
200
#if defined(HAVE_APPLE_NATT) && !defined(SADB_X_EXT_NATT)
201
/*
202
 * These are hidden in Apple XNU's private pfkeyv2.h header
203
 */
204
#define SADB_X_EXT_NATT     0x0002  /* Enable UDP encapsulation */
205
#define SADB_X_EXT_NATT_KEEPALIVE 0x0004  /* Send NAT-T keepalives */
206
#define SADB_X_EXT_NATT_MULTIPLEUSERS 0x0008  /* Use for VPN gateways */
207
#define SADB_X_EXT_NATT_DETECTED_PEER 0x1000  /* Opposite of KEEPALIVE */
208
209
struct sadb_sa_natt {
210
  uint16_t   sadb_sa_natt_port;
211
  union {
212
    uint16_t   sadb_reserved0;
213
    uint16_t   sadb_sa_natt_interval;
214
  };
215
  uint16_t   sadb_sa_natt_offload_interval;
216
  uint16_t   sadb_sa_natt_src_port;
217
};
218
#endif
219
220
#endif /* !_OPENBSD_COMPAT_H */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/recallocarray.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/recallocarray.c.html index 6156c06a8..3b37b177b 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/recallocarray.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/recallocarray.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/recallocarray.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */
2
/*
3
 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <errno.h>
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <string.h>
22
#include <unistd.h>
23
24
/*
25
 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
26
 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
27
 */
28
0
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
29
30
void *
31
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
32
0
{
33
0
  size_t oldsize, newsize;
34
0
  void *newptr;
35
36
0
  if (ptr == NULL)
37
0
    return calloc(newnmemb, size);
38
39
0
  if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
40
0
      newnmemb > 0 && SIZE_MAX / newnmemb < size) {
41
0
    errno = ENOMEM;
42
0
    return NULL;
43
0
  }
44
0
  newsize = newnmemb * size;
45
46
0
  if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
47
0
      oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
48
0
    errno = EINVAL;
49
0
    return NULL;
50
0
  }
51
0
  oldsize = oldnmemb * size;
52
  
53
  /*
54
   * Don't bother too much if we're shrinking just a bit,
55
   * we do not shrink for series of small steps, oh well.
56
   */
57
0
  if (newsize <= oldsize) {
58
0
    size_t d = oldsize - newsize;
59
60
0
    if (d < oldsize / 2 && d < (size_t)getpagesize()) {
61
0
      memset((char *)ptr + newsize, 0, d);
62
0
      return ptr;
63
0
    }
64
0
  }
65
66
0
  newptr = malloc(newsize);
67
0
  if (newptr == NULL)
68
0
    return NULL;
69
70
0
  if (newsize > oldsize) {
71
0
    memcpy(newptr, ptr, oldsize);
72
0
    memset((char *)newptr + oldsize, 0, newsize - oldsize);
73
0
  } else
74
0
    memcpy(newptr, ptr, newsize);
75
76
0
  explicit_bzero(ptr, oldsize);
77
0
  free(ptr);
78
79
0
  return newptr;
80
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/recallocarray.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: recallocarray.c,v 1.2 2021/03/18 11:16:58 claudio Exp $ */
2
/*
3
 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <errno.h>
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <string.h>
22
#include <unistd.h>
23
24
/*
25
 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
26
 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
27
 */
28
0
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
29
30
void *
31
recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
32
0
{
33
0
  size_t oldsize, newsize;
34
0
  void *newptr;
35
36
0
  if (ptr == NULL)
37
0
    return calloc(newnmemb, size);
38
39
0
  if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
40
0
      newnmemb > 0 && SIZE_MAX / newnmemb < size) {
41
0
    errno = ENOMEM;
42
0
    return NULL;
43
0
  }
44
0
  newsize = newnmemb * size;
45
46
0
  if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
47
0
      oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
48
0
    errno = EINVAL;
49
0
    return NULL;
50
0
  }
51
0
  oldsize = oldnmemb * size;
52
  
53
  /*
54
   * Don't bother too much if we're shrinking just a bit,
55
   * we do not shrink for series of small steps, oh well.
56
   */
57
0
  if (newsize <= oldsize) {
58
0
    size_t d = oldsize - newsize;
59
60
0
    if (d < oldsize / 2 && d < (size_t)getpagesize()) {
61
0
      memset((char *)ptr + newsize, 0, d);
62
0
      return ptr;
63
0
    }
64
0
  }
65
66
0
  newptr = malloc(newsize);
67
0
  if (newptr == NULL)
68
0
    return NULL;
69
70
0
  if (newsize > oldsize) {
71
0
    memcpy(newptr, ptr, oldsize);
72
0
    memset((char *)newptr + oldsize, 0, newsize - oldsize);
73
0
  } else
74
0
    memcpy(newptr, ptr, newsize);
75
76
0
  explicit_bzero(ptr, oldsize);
77
0
  free(ptr);
78
79
0
  return newptr;
80
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/setproctitle.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/setproctitle.c.html index 94f1cbf82..8ba52d83b 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/setproctitle.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/setproctitle.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/setproctitle.c
Line
Count
Source (jump to first uncovered line)
1
/* Based on conf.c from UCB sendmail 8.8.8 */
2
3
/*
4
 * Copyright 2003 Damien Miller
5
 * Copyright (c) 1983, 1995-1997 Eric P. Allman
6
 * Copyright (c) 1988, 1993
7
 *  The Regents of the University of California.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 3. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include "openbsd-compat.h"
35
36
#ifndef HAVE_SETPROCTITLE
37
38
#include <stdarg.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
#ifdef HAVE_SYS_PSTAT_H
43
#include <sys/pstat.h>
44
#endif
45
#include <string.h>
46
47
#include <vis.h>
48
49
#define SPT_NONE  0 /* don't use it at all */
50
#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */
51
#define SPT_REUSEARGV 2 /* cover argv with title information */
52
53
#ifndef SPT_TYPE
54
# define SPT_TYPE SPT_NONE
55
#endif
56
57
#ifndef SPT_PADCHAR
58
0
# define SPT_PADCHAR  '\0'
59
#endif
60
61
#if SPT_TYPE == SPT_REUSEARGV
62
static char *argv_start = NULL;
63
static size_t argv_env_len = 0;
64
#endif
65
66
#endif /* HAVE_SETPROCTITLE */
67
68
void
69
compat_init_setproctitle(int argc, char *argv[])
70
0
{
71
0
#if !defined(HAVE_SETPROCTITLE) && \
72
0
    defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
73
0
  extern char **environ;
74
0
  char *lastargv = NULL;
75
0
  char **envp = environ;
76
0
  int i;
77
78
  /*
79
   * NB: This assumes that argv has already been copied out of the
80
   * way. This is true for sshd, but may not be true for other
81
   * programs. Beware.
82
   */
83
84
0
  if (argc == 0 || argv[0] == NULL)
85
0
    return;
86
87
  /* Fail if we can't allocate room for the new environment */
88
0
  for (i = 0; envp[i] != NULL; i++)
89
0
    ;
90
0
  if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
91
0
    environ = envp; /* put it back */
92
0
    return;
93
0
  }
94
95
  /*
96
   * Find the last argv string or environment variable within
97
   * our process memory area.
98
   */
99
0
  for (i = 0; i < argc; i++) {
100
0
    if (lastargv == NULL || lastargv + 1 == argv[i])
101
0
      lastargv = argv[i] + strlen(argv[i]);
102
0
  }
103
0
  for (i = 0; envp[i] != NULL; i++) {
104
0
    if (lastargv + 1 == envp[i])
105
0
      lastargv = envp[i] + strlen(envp[i]);
106
0
  }
107
108
0
  argv[1] = NULL;
109
0
  argv_start = argv[0];
110
0
  argv_env_len = lastargv - argv[0] - 1;
111
112
  /*
113
   * Copy environment
114
   * XXX - will truncate env on strdup fail
115
   */
116
0
  for (i = 0; envp[i] != NULL; i++)
117
0
    environ[i] = strdup(envp[i]);
118
0
  environ[i] = NULL;
119
0
#endif /* SPT_REUSEARGV */
120
0
}
121
122
#ifndef HAVE_SETPROCTITLE
123
void
124
setproctitle(const char *fmt, ...)
125
0
{
126
0
#if SPT_TYPE != SPT_NONE
127
0
  va_list ap;
128
0
  char buf[1024], ptitle[1024];
129
0
  size_t len = 0;
130
0
  int r;
131
0
  extern char *__progname;
132
#if SPT_TYPE == SPT_PSTAT
133
  union pstun pst;
134
#endif
135
136
0
#if SPT_TYPE == SPT_REUSEARGV
137
0
  if (argv_env_len <= 0)
138
0
    return;
139
0
#endif
140
141
0
  strlcpy(buf, __progname, sizeof(buf));
142
143
0
  r = -1;
144
0
  va_start(ap, fmt);
145
0
  if (fmt != NULL) {
146
0
    len = strlcat(buf, ": ", sizeof(buf));
147
0
    if (len < sizeof(buf))
148
0
      r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap);
149
0
  }
150
0
  va_end(ap);
151
0
  if (r == -1 || (size_t)r >= sizeof(buf) - len)
152
0
    return;
153
0
  strnvis(ptitle, buf, sizeof(ptitle),
154
0
      VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL);
155
156
#if SPT_TYPE == SPT_PSTAT
157
  pst.pst_command = ptitle;
158
  pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
159
#elif SPT_TYPE == SPT_REUSEARGV
160
/*  debug("setproctitle: copy \"%s\" into len %d",
161
      buf, argv_env_len); */
162
0
  len = strlcpy(argv_start, ptitle, argv_env_len);
163
0
  for(; len < argv_env_len; len++)
164
0
    argv_start[len] = SPT_PADCHAR;
165
0
#endif
166
167
0
#endif /* SPT_NONE */
168
0
}
169
170
#endif /* HAVE_SETPROCTITLE */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/setproctitle.c
Line
Count
Source (jump to first uncovered line)
1
/* Based on conf.c from UCB sendmail 8.8.8 */
2
3
/*
4
 * Copyright 2003 Damien Miller
5
 * Copyright (c) 1983, 1995-1997 Eric P. Allman
6
 * Copyright (c) 1988, 1993
7
 *  The Regents of the University of California.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 3. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 */
33
34
#include "openbsd-compat.h"
35
36
#ifndef HAVE_SETPROCTITLE
37
38
#include <stdarg.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
#ifdef HAVE_SYS_PSTAT_H
43
#include <sys/pstat.h>
44
#endif
45
#include <string.h>
46
47
#include <vis.h>
48
49
#define SPT_NONE  0 /* don't use it at all */
50
#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */
51
#define SPT_REUSEARGV 2 /* cover argv with title information */
52
53
#ifndef SPT_TYPE
54
# define SPT_TYPE SPT_NONE
55
#endif
56
57
#ifndef SPT_PADCHAR
58
0
# define SPT_PADCHAR  '\0'
59
#endif
60
61
#if SPT_TYPE == SPT_REUSEARGV
62
static char *argv_start = NULL;
63
static size_t argv_env_len = 0;
64
#endif
65
66
#endif /* HAVE_SETPROCTITLE */
67
68
void
69
compat_init_setproctitle(int argc, char *argv[])
70
0
{
71
0
#if !defined(HAVE_SETPROCTITLE) && \
72
0
    defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
73
0
  extern char **environ;
74
0
  char *lastargv = NULL;
75
0
  char **envp = environ;
76
0
  int i;
77
78
  /*
79
   * NB: This assumes that argv has already been copied out of the
80
   * way. This is true for sshd, but may not be true for other
81
   * programs. Beware.
82
   */
83
84
0
  if (argc == 0 || argv[0] == NULL)
85
0
    return;
86
87
  /* Fail if we can't allocate room for the new environment */
88
0
  for (i = 0; envp[i] != NULL; i++)
89
0
    ;
90
0
  if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) {
91
0
    environ = envp; /* put it back */
92
0
    return;
93
0
  }
94
95
  /*
96
   * Find the last argv string or environment variable within
97
   * our process memory area.
98
   */
99
0
  for (i = 0; i < argc; i++) {
100
0
    if (lastargv == NULL || lastargv + 1 == argv[i])
101
0
      lastargv = argv[i] + strlen(argv[i]);
102
0
  }
103
0
  for (i = 0; envp[i] != NULL; i++) {
104
0
    if (lastargv + 1 == envp[i])
105
0
      lastargv = envp[i] + strlen(envp[i]);
106
0
  }
107
108
0
  argv[1] = NULL;
109
0
  argv_start = argv[0];
110
0
  argv_env_len = lastargv - argv[0] - 1;
111
112
  /*
113
   * Copy environment
114
   * XXX - will truncate env on strdup fail
115
   */
116
0
  for (i = 0; envp[i] != NULL; i++)
117
0
    environ[i] = strdup(envp[i]);
118
0
  environ[i] = NULL;
119
0
#endif /* SPT_REUSEARGV */
120
0
}
121
122
#ifndef HAVE_SETPROCTITLE
123
void
124
setproctitle(const char *fmt, ...)
125
0
{
126
0
#if SPT_TYPE != SPT_NONE
127
0
  va_list ap;
128
0
  char buf[1024], ptitle[1024];
129
0
  size_t len = 0;
130
0
  int r;
131
0
  extern char *__progname;
132
#if SPT_TYPE == SPT_PSTAT
133
  union pstun pst;
134
#endif
135
136
0
#if SPT_TYPE == SPT_REUSEARGV
137
0
  if (argv_env_len <= 0)
138
0
    return;
139
0
#endif
140
141
0
  strlcpy(buf, __progname, sizeof(buf));
142
143
0
  r = -1;
144
0
  va_start(ap, fmt);
145
0
  if (fmt != NULL) {
146
0
    len = strlcat(buf, ": ", sizeof(buf));
147
0
    if (len < sizeof(buf))
148
0
      r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap);
149
0
  }
150
0
  va_end(ap);
151
0
  if (r == -1 || (size_t)r >= sizeof(buf) - len)
152
0
    return;
153
0
  strnvis(ptitle, buf, sizeof(ptitle),
154
0
      VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL);
155
156
#if SPT_TYPE == SPT_PSTAT
157
  pst.pst_command = ptitle;
158
  pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0);
159
#elif SPT_TYPE == SPT_REUSEARGV
160
/*  debug("setproctitle: copy \"%s\" into len %d",
161
      buf, argv_env_len); */
162
0
  len = strlcpy(argv_start, ptitle, argv_env_len);
163
0
  for(; len < argv_env_len; len++)
164
0
    argv_start[len] = SPT_PADCHAR;
165
0
#endif
166
167
0
#endif /* SPT_NONE */
168
0
}
169
170
#endif /* HAVE_SETPROCTITLE */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcat.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcat.c.html index a6208c7e0..f094f9bd1 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcat.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcat.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strlcat.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
20
21
#include "openbsd-compat.h"
22
23
#if !defined(HAVE_STRLCAT)
24
25
#include <sys/types.h>
26
#include <string.h>
27
28
/*
29
 * Appends src to string dst of size dsize (unlike strncat, dsize is the
30
 * full size of dst, not space left).  At most dsize-1 characters
31
 * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
32
 * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
33
 * If retval >= dsize, truncation occurred.
34
 */
35
size_t
36
strlcat(char *dst, const char *src, size_t dsize)
37
0
{
38
0
  const char *odst = dst;
39
0
  const char *osrc = src;
40
0
  size_t n = dsize;
41
0
  size_t dlen;
42
43
  /* Find the end of dst and adjust bytes left but don't go past end. */
44
0
  while (n-- != 0 && *dst != '\0')
45
0
    dst++;
46
0
  dlen = dst - odst;
47
0
  n = dsize - dlen;
48
49
0
  if (n-- == 0)
50
0
    return(dlen + strlen(src));
51
0
  while (*src != '\0') {
52
0
    if (n != 0) {
53
0
      *dst++ = *src;
54
0
      n--;
55
0
    }
56
0
    src++;
57
0
  }
58
0
  *dst = '\0';
59
60
0
  return(dlen + (src - osrc));  /* count does not include NUL */
61
0
}
62
63
#endif /* !defined(HAVE_STRLCAT) */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strlcat.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
20
21
#include "openbsd-compat.h"
22
23
#if !defined(HAVE_STRLCAT)
24
25
#include <sys/types.h>
26
#include <string.h>
27
28
/*
29
 * Appends src to string dst of size dsize (unlike strncat, dsize is the
30
 * full size of dst, not space left).  At most dsize-1 characters
31
 * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
32
 * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
33
 * If retval >= dsize, truncation occurred.
34
 */
35
size_t
36
strlcat(char *dst, const char *src, size_t dsize)
37
0
{
38
0
  const char *odst = dst;
39
0
  const char *osrc = src;
40
0
  size_t n = dsize;
41
0
  size_t dlen;
42
43
  /* Find the end of dst and adjust bytes left but don't go past end. */
44
0
  while (n-- != 0 && *dst != '\0')
45
0
    dst++;
46
0
  dlen = dst - odst;
47
0
  n = dsize - dlen;
48
49
0
  if (n-- == 0)
50
0
    return(dlen + strlen(src));
51
0
  while (*src != '\0') {
52
0
    if (n != 0) {
53
0
      *dst++ = *src;
54
0
      n--;
55
0
    }
56
0
    src++;
57
0
  }
58
0
  *dst = '\0';
59
60
0
  return(dlen + (src - osrc));  /* count does not include NUL */
61
0
}
62
63
#endif /* !defined(HAVE_STRLCAT) */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcpy.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcpy.c.html index 993c8b4ea..ccd031536 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcpy.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strlcpy.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strlcpy.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <string.h>
21
22
/*
23
 * Copy string src to buffer dst of size dsize.  At most dsize-1
24
 * chars will be copied.  Always NUL terminates (unless dsize == 0).
25
 * Returns strlen(src); if retval >= dsize, truncation occurred.
26
 */
27
size_t
28
strlcpy(char *dst, const char *src, size_t dsize)
29
468k
{
30
468k
  const char *osrc = src;
31
468k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
468k
  if (nleft != 0) {
35
3.67M
    while (--nleft != 0) {
36
3.67M
      if ((*dst++ = *src++) == '\0')
37
467k
        break;
38
3.67M
    }
39
468k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
468k
  if (nleft == 0) {
43
1.45k
    if (dsize != 0)
44
1.45k
      *dst = '\0';   /* NUL-terminate dst */
45
1.45k
    while (*src++)
46
0
      ;
47
1.45k
  }
48
49
468k
  return(src - osrc - 1); /* count does not include NUL */
50
468k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strlcpy.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $  */
2
3
/*
4
 * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <string.h>
21
22
/*
23
 * Copy string src to buffer dst of size dsize.  At most dsize-1
24
 * chars will be copied.  Always NUL terminates (unless dsize == 0).
25
 * Returns strlen(src); if retval >= dsize, truncation occurred.
26
 */
27
size_t
28
strlcpy(char *dst, const char *src, size_t dsize)
29
471k
{
30
471k
  const char *osrc = src;
31
471k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
471k
  if (nleft != 0) {
35
3.70M
    while (--nleft != 0) {
36
3.70M
      if ((*dst++ = *src++) == '\0')
37
469k
        break;
38
3.70M
    }
39
471k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
471k
  if (nleft == 0) {
43
1.45k
    if (dsize != 0)
44
1.45k
      *dst = '\0';   /* NUL-terminate dst */
45
1.45k
    while (*src++)
46
0
      ;
47
1.45k
  }
48
49
471k
  return(src - osrc - 1); /* count does not include NUL */
50
471k
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strtonum.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strtonum.c.html index 16961e932..2051985e8 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strtonum.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/strtonum.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/strtonum.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
2
3
/*
4
 * Copyright (c) 2004 Ted Unangst and Todd Miller
5
 * All rights reserved.
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <errno.h>
21
#include <limits.h>
22
#include <stdlib.h>
23
24
0
#define INVALID   1
25
0
#define TOOSMALL  2
26
0
#define TOOLARGE  3
27
28
long long
29
strtonum(const char *numstr, long long minval, long long maxval,
30
    const char **errstrp)
31
0
{
32
0
  long long ll = 0;
33
0
  int error = 0;
34
0
  char *ep;
35
0
  struct errval {
36
0
    const char *errstr;
37
0
    int err;
38
0
  } ev[4] = {
39
0
    { NULL,   0 },
40
0
    { "invalid",  EINVAL },
41
0
    { "too small",  ERANGE },
42
0
    { "too large",  ERANGE },
43
0
  };
44
45
0
  ev[0].err = errno;
46
0
  errno = 0;
47
0
  if (minval > maxval) {
48
0
    error = INVALID;
49
0
  } else {
50
0
    ll = strtoll(numstr, &ep, 10);
51
0
    if (numstr == ep || *ep != '\0')
52
0
      error = INVALID;
53
0
    else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54
0
      error = TOOSMALL;
55
0
    else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56
0
      error = TOOLARGE;
57
0
  }
58
0
  if (errstrp != NULL)
59
0
    *errstrp = ev[error].errstr;
60
0
  errno = ev[error].err;
61
0
  if (error)
62
0
    ll = 0;
63
64
0
  return (ll);
65
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/strtonum.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
2
3
/*
4
 * Copyright (c) 2004 Ted Unangst and Todd Miller
5
 * All rights reserved.
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <errno.h>
21
#include <limits.h>
22
#include <stdlib.h>
23
24
0
#define INVALID   1
25
0
#define TOOSMALL  2
26
0
#define TOOLARGE  3
27
28
long long
29
strtonum(const char *numstr, long long minval, long long maxval,
30
    const char **errstrp)
31
0
{
32
0
  long long ll = 0;
33
0
  int error = 0;
34
0
  char *ep;
35
0
  struct errval {
36
0
    const char *errstr;
37
0
    int err;
38
0
  } ev[4] = {
39
0
    { NULL,   0 },
40
0
    { "invalid",  EINVAL },
41
0
    { "too small",  ERANGE },
42
0
    { "too large",  ERANGE },
43
0
  };
44
45
0
  ev[0].err = errno;
46
0
  errno = 0;
47
0
  if (minval > maxval) {
48
0
    error = INVALID;
49
0
  } else {
50
0
    ll = strtoll(numstr, &ep, 10);
51
0
    if (numstr == ep || *ep != '\0')
52
0
      error = INVALID;
53
0
    else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54
0
      error = TOOSMALL;
55
0
    else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56
0
      error = TOOLARGE;
57
0
  }
58
0
  if (errstrp != NULL)
59
0
    *errstrp = ev[error].errstr;
60
0
  errno = ev[error].err;
61
0
  if (error)
62
0
    ll = 0;
63
64
0
  return (ll);
65
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/queue.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/queue.h.html index 5c83c8cc7..e8ef89344 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/queue.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/queue.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/sys/queue.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: queue.h,v 1.46 2020/12/30 13:33:12 millert Exp $  */
2
/*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
 * Copyright (c) 1991, 1993
6
 *  The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)queue.h 8.5 (Berkeley) 8/20/94
33
 */
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
#include <sys/_null.h>
39
40
/*
41
 * This file defines five types of data structures: singly-linked lists,
42
 * lists, simple queues, tail queues and XOR simple queues.
43
 *
44
 *
45
 * A singly-linked list is headed by a single forward pointer. The elements
46
 * are singly linked for minimum space and pointer manipulation overhead at
47
 * the expense of O(n) removal for arbitrary elements. New elements can be
48
 * added to the list after an existing element or at the head of the list.
49
 * Elements being removed from the head of the list should use the explicit
50
 * macro for this purpose for optimum efficiency. A singly-linked list may
51
 * only be traversed in the forward direction.  Singly-linked lists are ideal
52
 * for applications with large datasets and few or no removals or for
53
 * implementing a LIFO queue.
54
 *
55
 * A list is headed by a single forward pointer (or an array of forward
56
 * pointers for a hash table header). The elements are doubly linked
57
 * so that an arbitrary element can be removed without a need to
58
 * traverse the list. New elements can be added to the list before
59
 * or after an existing element or at the head of the list. A list
60
 * may only be traversed in the forward direction.
61
 *
62
 * A simple queue is headed by a pair of pointers, one to the head of the
63
 * list and the other to the tail of the list. The elements are singly
64
 * linked to save space, so elements can only be removed from the
65
 * head of the list. New elements can be added to the list before or after
66
 * an existing element, at the head of the list, or at the end of the
67
 * list. A simple queue may only be traversed in the forward direction.
68
 *
69
 * A tail queue is headed by a pair of pointers, one to the head of the
70
 * list and the other to the tail of the list. The elements are doubly
71
 * linked so that an arbitrary element can be removed without a need to
72
 * traverse the list. New elements can be added to the list before or
73
 * after an existing element, at the head of the list, or at the end of
74
 * the list. A tail queue may be traversed in either direction.
75
 *
76
 * An XOR simple queue is used in the same way as a regular simple queue.
77
 * The difference is that the head structure also includes a "cookie" that
78
 * is XOR'd with the queue pointer (first, last or next) to generate the
79
 * real pointer value.
80
 *
81
 * For details on the use of these macros, see the queue(3) manual page.
82
 */
83
84
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
85
#define _Q_INVALID ((void *)-1)
86
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
 * Singly-linked List definitions.
93
 */
94
#define SLIST_HEAD(name, type)            \
95
struct name {               \
96
  struct type *slh_first; /* first element */     \
97
}
98
99
#define SLIST_HEAD_INITIALIZER(head)          \
100
  { NULL }
101
102
#define SLIST_ENTRY(type)           \
103
struct {                \
104
  struct type *sle_next;  /* next element */      \
105
}
106
107
/*
108
 * Singly-linked List access methods.
109
 */
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head)   NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field)         \
116
  for((var) = SLIST_FIRST(head);          \
117
      (var) != SLIST_END(head);         \
118
      (var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
121
  for ((var) = SLIST_FIRST(head);       \
122
      (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
123
      (var) = (tvar))
124
125
/*
126
 * Singly-linked List functions.
127
 */
128
#define SLIST_INIT(head) {            \
129
  SLIST_FIRST(head) = SLIST_END(head);        \
130
}
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
133
  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
134
  (slistelm)->field.sle_next = (elm);       \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
138
  (elm)->field.sle_next = (head)->slh_first;      \
139
  (head)->slh_first = (elm);          \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do {       \
143
  (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do {       \
147
  (head)->slh_first = (head)->slh_first->field.sle_next;    \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do {     \
151
  if ((head)->slh_first == (elm)) {       \
152
    SLIST_REMOVE_HEAD((head), field);     \
153
  } else {              \
154
    struct type *curelm = (head)->slh_first;    \
155
                  \
156
    while (curelm->field.sle_next != (elm))     \
157
      curelm = curelm->field.sle_next;    \
158
    curelm->field.sle_next =        \
159
        curelm->field.sle_next->field.sle_next;   \
160
  }               \
161
  _Q_INVALIDATE((elm)->field.sle_next);       \
162
} while (0)
163
164
/*
165
 * List definitions.
166
 */
167
#define LIST_HEAD(name, type)           \
168
struct name {               \
169
  struct type *lh_first;  /* first element */     \
170
}
171
172
#define LIST_HEAD_INITIALIZER(head)         \
173
  { NULL }
174
175
#define LIST_ENTRY(type)            \
176
struct {                \
177
  struct type *le_next; /* next element */      \
178
  struct type **le_prev;  /* address of previous next element */  \
179
}
180
181
/*
182
 * List access methods.
183
 */
184
#define LIST_FIRST(head)    ((head)->lh_first)
185
#define LIST_END(head)      NULL
186
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
187
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field)          \
190
  for((var) = LIST_FIRST(head);         \
191
      (var)!= LIST_END(head);         \
192
      (var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
195
  for ((var) = LIST_FIRST(head);        \
196
      (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
197
      (var) = (tvar))
198
199
/*
200
 * List functions.
201
 */
202
#define LIST_INIT(head) do {            \
203
  LIST_FIRST(head) = LIST_END(head);        \
204
} while (0)
205
206
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
207
  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
208
    (listelm)->field.le_next->field.le_prev =   \
209
        &(elm)->field.le_next;        \
210
  (listelm)->field.le_next = (elm);       \
211
  (elm)->field.le_prev = &(listelm)->field.le_next;   \
212
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
215
  (elm)->field.le_prev = (listelm)->field.le_prev;    \
216
  (elm)->field.le_next = (listelm);       \
217
  *(listelm)->field.le_prev = (elm);        \
218
  (listelm)->field.le_prev = &(elm)->field.le_next;   \
219
} while (0)
220
221
#define LIST_INSERT_HEAD(head, elm, field) do {       \
222
  if (((elm)->field.le_next = (head)->lh_first) != NULL)    \
223
    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
  (head)->lh_first = (elm);         \
225
  (elm)->field.le_prev = &(head)->lh_first;     \
226
} while (0)
227
228
#define LIST_REMOVE(elm, field) do {          \
229
  if ((elm)->field.le_next != NULL)       \
230
    (elm)->field.le_next->field.le_prev =     \
231
        (elm)->field.le_prev;       \
232
  *(elm)->field.le_prev = (elm)->field.le_next;     \
233
  _Q_INVALIDATE((elm)->field.le_prev);        \
234
  _Q_INVALIDATE((elm)->field.le_next);        \
235
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do {       \
238
  if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
    (elm2)->field.le_next->field.le_prev =      \
240
        &(elm2)->field.le_next;       \
241
  (elm2)->field.le_prev = (elm)->field.le_prev;     \
242
  *(elm2)->field.le_prev = (elm2);        \
243
  _Q_INVALIDATE((elm)->field.le_prev);        \
244
  _Q_INVALIDATE((elm)->field.le_next);        \
245
} while (0)
246
247
/*
248
 * Simple queue definitions.
249
 */
250
#define SIMPLEQ_HEAD(name, type)          \
251
struct name {               \
252
  struct type *sqh_first; /* first element */     \
253
  struct type **sqh_last; /* addr of last next element */   \
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
257
  { NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type)           \
260
struct {                \
261
  struct type *sqe_next;  /* next element */      \
262
}
263
264
/*
265
 * Simple queue access methods.
266
 */
267
13.9k
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
268
#define SIMPLEQ_END(head)     NULL
269
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field)       \
273
  for((var) = SIMPLEQ_FIRST(head);        \
274
      (var) != SIMPLEQ_END(head);         \
275
      (var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
278
  for ((var) = SIMPLEQ_FIRST(head);       \
279
      (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);    \
280
      (var) = (tvar))
281
282
/*
283
 * Simple queue functions.
284
 */
285
13.0k
#define SIMPLEQ_INIT(head) do {           \
286
13.0k
  (head)->sqh_first = NULL;         \
287
13.0k
  (head)->sqh_last = &(head)->sqh_first;        \
288
13.0k
} while (0)
289
290
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
291
  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
292
    (head)->sqh_last = &(elm)->field.sqe_next;    \
293
  (head)->sqh_first = (elm);          \
294
} while (0)
295
296
897
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
897
  (elm)->field.sqe_next = NULL;         \
298
897
  *(head)->sqh_last = (elm);          \
299
897
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
897
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
303
  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
    (head)->sqh_last = &(elm)->field.sqe_next;    \
305
  (listelm)->field.sqe_next = (elm);        \
306
} while (0)
307
308
897
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
897
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
897
    (head)->sqh_last = &(head)->sqh_first;     \
311
897
} while (0)
312
313
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
314
  if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
      == NULL)              \
316
    (head)->sqh_last = &(elm)->field.sqe_next;    \
317
} while (0)
318
319
#define SIMPLEQ_CONCAT(head1, head2) do {       \
320
  if (!SIMPLEQ_EMPTY((head2))) {          \
321
    *(head1)->sqh_last = (head2)->sqh_first;    \
322
    (head1)->sqh_last = (head2)->sqh_last;      \
323
    SIMPLEQ_INIT((head2));          \
324
  }               \
325
} while (0)
326
327
/*
328
 * XOR Simple queue definitions.
329
 */
330
#define XSIMPLEQ_HEAD(name, type)         \
331
struct name {               \
332
  struct type *sqx_first; /* first element */     \
333
  struct type **sqx_last; /* addr of last next element */   \
334
  unsigned long sqx_cookie;         \
335
}
336
337
#define XSIMPLEQ_ENTRY(type)            \
338
struct {                \
339
  struct type *sqx_next;  /* next element */      \
340
}
341
342
/*
343
 * XOR Simple queue access methods.
344
 */
345
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
346
          (unsigned long)(ptr)))
347
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
348
#define XSIMPLEQ_END(head)      NULL
349
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
350
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
351
352
353
#define XSIMPLEQ_FOREACH(var, head, field)        \
354
  for ((var) = XSIMPLEQ_FIRST(head);        \
355
      (var) != XSIMPLEQ_END(head);        \
356
      (var) = XSIMPLEQ_NEXT(head, var, field))
357
358
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
359
  for ((var) = XSIMPLEQ_FIRST(head);        \
360
      (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
361
      (var) = (tvar))
362
363
/*
364
 * XOR Simple queue functions.
365
 */
366
#define XSIMPLEQ_INIT(head) do {          \
367
  arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
368
  (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
369
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
370
} while (0)
371
372
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
373
  if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
374
      XSIMPLEQ_XOR(head, NULL))         \
375
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
376
  (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
377
} while (0)
378
379
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
380
  (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
381
  *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
382
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
383
} while (0)
384
385
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
386
  if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
387
      XSIMPLEQ_XOR(head, NULL))         \
388
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
389
  (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
390
} while (0)
391
392
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
393
  if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
394
      (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
395
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
396
} while (0)
397
398
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
399
  if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
400
      (elm)->field.sqx_next)->field.sqx_next)     \
401
      == XSIMPLEQ_XOR(head, NULL))        \
402
    (head)->sqx_last =          \
403
        XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
404
} while (0)
405
406
407
/*
408
 * Tail queue definitions.
409
 */
410
#define TAILQ_HEAD(name, type)            \
411
struct name {               \
412
  struct type *tqh_first; /* first element */     \
413
  struct type **tqh_last; /* addr of last next element */   \
414
}
415
416
#define TAILQ_HEAD_INITIALIZER(head)          \
417
  { NULL, &(head).tqh_first }
418
419
#define TAILQ_ENTRY(type)           \
420
struct {                \
421
  struct type *tqe_next;  /* next element */      \
422
  struct type **tqe_prev; /* address of previous next element */  \
423
}
424
425
/*
426
 * Tail queue access methods.
427
 */
428
13.0k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
26.0k
#define TAILQ_END(head)     NULL
430
0
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
431
#define TAILQ_LAST(head, headname)          \
432
  (*(((struct headname *)((head)->tqh_last))->tqh_last))
433
/* XXX */
434
#define TAILQ_PREV(elm, headname, field)        \
435
  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
436
#define TAILQ_EMPTY(head)           \
437
  (TAILQ_FIRST(head) == TAILQ_END(head))
438
439
#define TAILQ_FOREACH(var, head, field)         \
440
0
  for((var) = TAILQ_FIRST(head);         \
441
0
      (var) != TAILQ_END(head);         \
442
0
      (var) = TAILQ_NEXT(var, field))
443
444
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
445
13.0k
  for ((var) = TAILQ_FIRST(head);         \
446
13.0k
      (var) != TAILQ_END(head) &&         \
447
13.0k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
13.0k
      (var) = (tvar))
449
450
451
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
452
  for((var) = TAILQ_LAST(head, headname);       \
453
      (var) != TAILQ_END(head);         \
454
      (var) = TAILQ_PREV(var, headname, field))
455
456
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
457
  for ((var) = TAILQ_LAST(head, headname);      \
458
      (var) != TAILQ_END(head) &&         \
459
      ((tvar) = TAILQ_PREV(var, headname, field), 1);   \
460
      (var) = (tvar))
461
462
/*
463
 * Tail queue functions.
464
 */
465
13.0k
#define TAILQ_INIT(head) do {           \
466
13.0k
  (head)->tqh_first = NULL;         \
467
13.0k
  (head)->tqh_last = &(head)->tqh_first;        \
468
13.0k
} while (0)
469
470
#define TAILQ_INSERT_HEAD(head, elm, field) do {      \
471
  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)  \
472
    (head)->tqh_first->field.tqe_prev =     \
473
        &(elm)->field.tqe_next;       \
474
  else                \
475
    (head)->tqh_last = &(elm)->field.tqe_next;    \
476
  (head)->tqh_first = (elm);          \
477
  (elm)->field.tqe_prev = &(head)->tqh_first;     \
478
} while (0)
479
480
0
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
481
0
  (elm)->field.tqe_next = NULL;         \
482
0
  (elm)->field.tqe_prev = (head)->tqh_last;     \
483
0
  *(head)->tqh_last = (elm);          \
484
0
  (head)->tqh_last = &(elm)->field.tqe_next;      \
485
0
} while (0)
486
487
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {    \
488
  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
489
    (elm)->field.tqe_next->field.tqe_prev =     \
490
        &(elm)->field.tqe_next;       \
491
  else                \
492
    (head)->tqh_last = &(elm)->field.tqe_next;    \
493
  (listelm)->field.tqe_next = (elm);        \
494
  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
495
} while (0)
496
497
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
498
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
499
  (elm)->field.tqe_next = (listelm);        \
500
  *(listelm)->field.tqe_prev = (elm);       \
501
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
502
} while (0)
503
504
0
#define TAILQ_REMOVE(head, elm, field) do {       \
505
0
  if (((elm)->field.tqe_next) != NULL)       \
506
0
    (elm)->field.tqe_next->field.tqe_prev =     \
507
0
        (elm)->field.tqe_prev;       \
508
0
  else                \
509
0
    (head)->tqh_last = (elm)->field.tqe_prev;   \
510
0
  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
511
0
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
512
0
  _Q_INVALIDATE((elm)->field.tqe_next);       \
513
0
} while (0)
514
515
#define TAILQ_REPLACE(head, elm, elm2, field) do {      \
516
  if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
517
    (elm2)->field.tqe_next->field.tqe_prev =    \
518
        &(elm2)->field.tqe_next;        \
519
  else                \
520
    (head)->tqh_last = &(elm2)->field.tqe_next;   \
521
  (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
522
  *(elm2)->field.tqe_prev = (elm2);       \
523
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
524
  _Q_INVALIDATE((elm)->field.tqe_next);       \
525
} while (0)
526
527
#define TAILQ_CONCAT(head1, head2, field) do {        \
528
  if (!TAILQ_EMPTY(head2)) {          \
529
    *(head1)->tqh_last = (head2)->tqh_first;    \
530
    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
531
    (head1)->tqh_last = (head2)->tqh_last;      \
532
    TAILQ_INIT((head2));          \
533
  }               \
534
} while (0)
535
536
/*
537
 * Singly-linked Tail queue declarations.
538
 */
539
#define STAILQ_HEAD(name, type)           \
540
struct name {               \
541
  struct type *stqh_first;  /* first element */   \
542
  struct type **stqh_last;  /* addr of last next element */ \
543
}
544
545
#define STAILQ_HEAD_INITIALIZER(head)         \
546
  { NULL, &(head).stqh_first }
547
548
#define STAILQ_ENTRY(type)            \
549
struct {                \
550
  struct type *stqe_next; /* next element */      \
551
}
552
553
/*
554
 * Singly-linked Tail queue access methods.
555
 */
556
#define STAILQ_FIRST(head)  ((head)->stqh_first)
557
#define STAILQ_END(head)  NULL
558
#define STAILQ_EMPTY(head)  (STAILQ_FIRST(head) == STAILQ_END(head))
559
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
560
561
#define STAILQ_FOREACH(var, head, field)        \
562
  for ((var) = STAILQ_FIRST(head);        \
563
      (var) != STAILQ_END(head);          \
564
      (var) = STAILQ_NEXT(var, field))
565
566
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)     \
567
  for ((var) = STAILQ_FIRST(head);        \
568
      (var) && ((tvar) = STAILQ_NEXT(var, field), 1);   \
569
      (var) = (tvar))
570
571
/*
572
 * Singly-linked Tail queue functions.
573
 */
574
#define STAILQ_INIT(head) do {            \
575
  STAILQ_FIRST((head)) = NULL;          \
576
  (head)->stqh_last = &STAILQ_FIRST((head));      \
577
} while (0)
578
579
#define STAILQ_INSERT_HEAD(head, elm, field) do {     \
580
  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
581
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
582
  STAILQ_FIRST((head)) = (elm);         \
583
} while (0)
584
585
#define STAILQ_INSERT_TAIL(head, elm, field) do {     \
586
  STAILQ_NEXT((elm), field) = NULL;       \
587
  *(head)->stqh_last = (elm);         \
588
  (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
589
} while (0)
590
591
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
592
  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
593
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
594
  STAILQ_NEXT((elm), field) = (elm);        \
595
} while (0)
596
597
#define STAILQ_REMOVE_HEAD(head, field) do {                            \
598
  if ((STAILQ_FIRST((head)) =         \
599
      STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)    \
600
    (head)->stqh_last = &STAILQ_FIRST((head));    \
601
} while (0)
602
603
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
604
  if ((STAILQ_NEXT(elm, field) =          \
605
      STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
606
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
607
} while (0)
608
609
#define STAILQ_REMOVE(head, elm, type, field) do {      \
610
  if (STAILQ_FIRST((head)) == (elm)) {        \
611
    STAILQ_REMOVE_HEAD((head), field);      \
612
  } else {              \
613
    struct type *curelm = (head)->stqh_first;   \
614
    while (STAILQ_NEXT(curelm, field) != (elm))   \
615
      curelm = STAILQ_NEXT(curelm, field);    \
616
    STAILQ_REMOVE_AFTER(head, curelm, field);   \
617
  }               \
618
} while (0)
619
620
#define STAILQ_CONCAT(head1, head2) do {        \
621
  if (!STAILQ_EMPTY((head2))) {         \
622
    *(head1)->stqh_last = (head2)->stqh_first;    \
623
    (head1)->stqh_last = (head2)->stqh_last;    \
624
    STAILQ_INIT((head2));         \
625
  }               \
626
} while (0)
627
628
#define STAILQ_LAST(head, type, field)          \
629
  (STAILQ_EMPTY((head)) ? NULL :          \
630
          ((struct type *)(void *)        \
631
    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
632
633
#endif  /* !_SYS_QUEUE_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/sys/queue.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: queue.h,v 1.46 2020/12/30 13:33:12 millert Exp $  */
2
/*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
 * Copyright (c) 1991, 1993
6
 *  The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)queue.h 8.5 (Berkeley) 8/20/94
33
 */
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
#include <sys/_null.h>
39
40
/*
41
 * This file defines five types of data structures: singly-linked lists,
42
 * lists, simple queues, tail queues and XOR simple queues.
43
 *
44
 *
45
 * A singly-linked list is headed by a single forward pointer. The elements
46
 * are singly linked for minimum space and pointer manipulation overhead at
47
 * the expense of O(n) removal for arbitrary elements. New elements can be
48
 * added to the list after an existing element or at the head of the list.
49
 * Elements being removed from the head of the list should use the explicit
50
 * macro for this purpose for optimum efficiency. A singly-linked list may
51
 * only be traversed in the forward direction.  Singly-linked lists are ideal
52
 * for applications with large datasets and few or no removals or for
53
 * implementing a LIFO queue.
54
 *
55
 * A list is headed by a single forward pointer (or an array of forward
56
 * pointers for a hash table header). The elements are doubly linked
57
 * so that an arbitrary element can be removed without a need to
58
 * traverse the list. New elements can be added to the list before
59
 * or after an existing element or at the head of the list. A list
60
 * may only be traversed in the forward direction.
61
 *
62
 * A simple queue is headed by a pair of pointers, one to the head of the
63
 * list and the other to the tail of the list. The elements are singly
64
 * linked to save space, so elements can only be removed from the
65
 * head of the list. New elements can be added to the list before or after
66
 * an existing element, at the head of the list, or at the end of the
67
 * list. A simple queue may only be traversed in the forward direction.
68
 *
69
 * A tail queue is headed by a pair of pointers, one to the head of the
70
 * list and the other to the tail of the list. The elements are doubly
71
 * linked so that an arbitrary element can be removed without a need to
72
 * traverse the list. New elements can be added to the list before or
73
 * after an existing element, at the head of the list, or at the end of
74
 * the list. A tail queue may be traversed in either direction.
75
 *
76
 * An XOR simple queue is used in the same way as a regular simple queue.
77
 * The difference is that the head structure also includes a "cookie" that
78
 * is XOR'd with the queue pointer (first, last or next) to generate the
79
 * real pointer value.
80
 *
81
 * For details on the use of these macros, see the queue(3) manual page.
82
 */
83
84
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
85
#define _Q_INVALID ((void *)-1)
86
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
 * Singly-linked List definitions.
93
 */
94
#define SLIST_HEAD(name, type)            \
95
struct name {               \
96
  struct type *slh_first; /* first element */     \
97
}
98
99
#define SLIST_HEAD_INITIALIZER(head)          \
100
  { NULL }
101
102
#define SLIST_ENTRY(type)           \
103
struct {                \
104
  struct type *sle_next;  /* next element */      \
105
}
106
107
/*
108
 * Singly-linked List access methods.
109
 */
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head)   NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field)         \
116
  for((var) = SLIST_FIRST(head);          \
117
      (var) != SLIST_END(head);         \
118
      (var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
121
  for ((var) = SLIST_FIRST(head);       \
122
      (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
123
      (var) = (tvar))
124
125
/*
126
 * Singly-linked List functions.
127
 */
128
#define SLIST_INIT(head) {            \
129
  SLIST_FIRST(head) = SLIST_END(head);        \
130
}
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
133
  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
134
  (slistelm)->field.sle_next = (elm);       \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
138
  (elm)->field.sle_next = (head)->slh_first;      \
139
  (head)->slh_first = (elm);          \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do {       \
143
  (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do {       \
147
  (head)->slh_first = (head)->slh_first->field.sle_next;    \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do {     \
151
  if ((head)->slh_first == (elm)) {       \
152
    SLIST_REMOVE_HEAD((head), field);     \
153
  } else {              \
154
    struct type *curelm = (head)->slh_first;    \
155
                  \
156
    while (curelm->field.sle_next != (elm))     \
157
      curelm = curelm->field.sle_next;    \
158
    curelm->field.sle_next =        \
159
        curelm->field.sle_next->field.sle_next;   \
160
  }               \
161
  _Q_INVALIDATE((elm)->field.sle_next);       \
162
} while (0)
163
164
/*
165
 * List definitions.
166
 */
167
#define LIST_HEAD(name, type)           \
168
struct name {               \
169
  struct type *lh_first;  /* first element */     \
170
}
171
172
#define LIST_HEAD_INITIALIZER(head)         \
173
  { NULL }
174
175
#define LIST_ENTRY(type)            \
176
struct {                \
177
  struct type *le_next; /* next element */      \
178
  struct type **le_prev;  /* address of previous next element */  \
179
}
180
181
/*
182
 * List access methods.
183
 */
184
#define LIST_FIRST(head)    ((head)->lh_first)
185
#define LIST_END(head)      NULL
186
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
187
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field)          \
190
  for((var) = LIST_FIRST(head);         \
191
      (var)!= LIST_END(head);         \
192
      (var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
195
  for ((var) = LIST_FIRST(head);        \
196
      (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
197
      (var) = (tvar))
198
199
/*
200
 * List functions.
201
 */
202
#define LIST_INIT(head) do {            \
203
  LIST_FIRST(head) = LIST_END(head);        \
204
} while (0)
205
206
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
207
  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
208
    (listelm)->field.le_next->field.le_prev =   \
209
        &(elm)->field.le_next;        \
210
  (listelm)->field.le_next = (elm);       \
211
  (elm)->field.le_prev = &(listelm)->field.le_next;   \
212
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
215
  (elm)->field.le_prev = (listelm)->field.le_prev;    \
216
  (elm)->field.le_next = (listelm);       \
217
  *(listelm)->field.le_prev = (elm);        \
218
  (listelm)->field.le_prev = &(elm)->field.le_next;   \
219
} while (0)
220
221
#define LIST_INSERT_HEAD(head, elm, field) do {       \
222
  if (((elm)->field.le_next = (head)->lh_first) != NULL)    \
223
    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
  (head)->lh_first = (elm);         \
225
  (elm)->field.le_prev = &(head)->lh_first;     \
226
} while (0)
227
228
#define LIST_REMOVE(elm, field) do {          \
229
  if ((elm)->field.le_next != NULL)       \
230
    (elm)->field.le_next->field.le_prev =     \
231
        (elm)->field.le_prev;       \
232
  *(elm)->field.le_prev = (elm)->field.le_next;     \
233
  _Q_INVALIDATE((elm)->field.le_prev);        \
234
  _Q_INVALIDATE((elm)->field.le_next);        \
235
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do {       \
238
  if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
    (elm2)->field.le_next->field.le_prev =      \
240
        &(elm2)->field.le_next;       \
241
  (elm2)->field.le_prev = (elm)->field.le_prev;     \
242
  *(elm2)->field.le_prev = (elm2);        \
243
  _Q_INVALIDATE((elm)->field.le_prev);        \
244
  _Q_INVALIDATE((elm)->field.le_next);        \
245
} while (0)
246
247
/*
248
 * Simple queue definitions.
249
 */
250
#define SIMPLEQ_HEAD(name, type)          \
251
struct name {               \
252
  struct type *sqh_first; /* first element */     \
253
  struct type **sqh_last; /* addr of last next element */   \
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
257
  { NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type)           \
260
struct {                \
261
  struct type *sqe_next;  /* next element */      \
262
}
263
264
/*
265
 * Simple queue access methods.
266
 */
267
14.0k
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
268
#define SIMPLEQ_END(head)     NULL
269
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field)       \
273
  for((var) = SIMPLEQ_FIRST(head);        \
274
      (var) != SIMPLEQ_END(head);         \
275
      (var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
278
  for ((var) = SIMPLEQ_FIRST(head);       \
279
      (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);    \
280
      (var) = (tvar))
281
282
/*
283
 * Simple queue functions.
284
 */
285
13.1k
#define SIMPLEQ_INIT(head) do {           \
286
13.1k
  (head)->sqh_first = NULL;         \
287
13.1k
  (head)->sqh_last = &(head)->sqh_first;        \
288
13.1k
} while (0)
289
290
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
291
  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
292
    (head)->sqh_last = &(elm)->field.sqe_next;    \
293
  (head)->sqh_first = (elm);          \
294
} while (0)
295
296
897
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
897
  (elm)->field.sqe_next = NULL;         \
298
897
  *(head)->sqh_last = (elm);          \
299
897
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
897
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
303
  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
    (head)->sqh_last = &(elm)->field.sqe_next;    \
305
  (listelm)->field.sqe_next = (elm);        \
306
} while (0)
307
308
897
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
897
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
897
    (head)->sqh_last = &(head)->sqh_first;     \
311
897
} while (0)
312
313
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
314
  if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
      == NULL)              \
316
    (head)->sqh_last = &(elm)->field.sqe_next;    \
317
} while (0)
318
319
#define SIMPLEQ_CONCAT(head1, head2) do {       \
320
  if (!SIMPLEQ_EMPTY((head2))) {          \
321
    *(head1)->sqh_last = (head2)->sqh_first;    \
322
    (head1)->sqh_last = (head2)->sqh_last;      \
323
    SIMPLEQ_INIT((head2));          \
324
  }               \
325
} while (0)
326
327
/*
328
 * XOR Simple queue definitions.
329
 */
330
#define XSIMPLEQ_HEAD(name, type)         \
331
struct name {               \
332
  struct type *sqx_first; /* first element */     \
333
  struct type **sqx_last; /* addr of last next element */   \
334
  unsigned long sqx_cookie;         \
335
}
336
337
#define XSIMPLEQ_ENTRY(type)            \
338
struct {                \
339
  struct type *sqx_next;  /* next element */      \
340
}
341
342
/*
343
 * XOR Simple queue access methods.
344
 */
345
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
346
          (unsigned long)(ptr)))
347
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
348
#define XSIMPLEQ_END(head)      NULL
349
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
350
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
351
352
353
#define XSIMPLEQ_FOREACH(var, head, field)        \
354
  for ((var) = XSIMPLEQ_FIRST(head);        \
355
      (var) != XSIMPLEQ_END(head);        \
356
      (var) = XSIMPLEQ_NEXT(head, var, field))
357
358
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
359
  for ((var) = XSIMPLEQ_FIRST(head);        \
360
      (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
361
      (var) = (tvar))
362
363
/*
364
 * XOR Simple queue functions.
365
 */
366
#define XSIMPLEQ_INIT(head) do {          \
367
  arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
368
  (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
369
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
370
} while (0)
371
372
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
373
  if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
374
      XSIMPLEQ_XOR(head, NULL))         \
375
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
376
  (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
377
} while (0)
378
379
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
380
  (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
381
  *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
382
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
383
} while (0)
384
385
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
386
  if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
387
      XSIMPLEQ_XOR(head, NULL))         \
388
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
389
  (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
390
} while (0)
391
392
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
393
  if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
394
      (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
395
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
396
} while (0)
397
398
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
399
  if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
400
      (elm)->field.sqx_next)->field.sqx_next)     \
401
      == XSIMPLEQ_XOR(head, NULL))        \
402
    (head)->sqx_last =          \
403
        XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
404
} while (0)
405
406
407
/*
408
 * Tail queue definitions.
409
 */
410
#define TAILQ_HEAD(name, type)            \
411
struct name {               \
412
  struct type *tqh_first; /* first element */     \
413
  struct type **tqh_last; /* addr of last next element */   \
414
}
415
416
#define TAILQ_HEAD_INITIALIZER(head)          \
417
  { NULL, &(head).tqh_first }
418
419
#define TAILQ_ENTRY(type)           \
420
struct {                \
421
  struct type *tqe_next;  /* next element */      \
422
  struct type **tqe_prev; /* address of previous next element */  \
423
}
424
425
/*
426
 * Tail queue access methods.
427
 */
428
13.1k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
26.3k
#define TAILQ_END(head)     NULL
430
0
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
431
#define TAILQ_LAST(head, headname)          \
432
  (*(((struct headname *)((head)->tqh_last))->tqh_last))
433
/* XXX */
434
#define TAILQ_PREV(elm, headname, field)        \
435
  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
436
#define TAILQ_EMPTY(head)           \
437
  (TAILQ_FIRST(head) == TAILQ_END(head))
438
439
#define TAILQ_FOREACH(var, head, field)         \
440
0
  for((var) = TAILQ_FIRST(head);         \
441
0
      (var) != TAILQ_END(head);         \
442
0
      (var) = TAILQ_NEXT(var, field))
443
444
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
445
13.1k
  for ((var) = TAILQ_FIRST(head);         \
446
13.1k
      (var) != TAILQ_END(head) &&         \
447
13.1k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
13.1k
      (var) = (tvar))
449
450
451
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
452
  for((var) = TAILQ_LAST(head, headname);       \
453
      (var) != TAILQ_END(head);         \
454
      (var) = TAILQ_PREV(var, headname, field))
455
456
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
457
  for ((var) = TAILQ_LAST(head, headname);      \
458
      (var) != TAILQ_END(head) &&         \
459
      ((tvar) = TAILQ_PREV(var, headname, field), 1);   \
460
      (var) = (tvar))
461
462
/*
463
 * Tail queue functions.
464
 */
465
13.1k
#define TAILQ_INIT(head) do {           \
466
13.1k
  (head)->tqh_first = NULL;         \
467
13.1k
  (head)->tqh_last = &(head)->tqh_first;        \
468
13.1k
} while (0)
469
470
#define TAILQ_INSERT_HEAD(head, elm, field) do {      \
471
  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)  \
472
    (head)->tqh_first->field.tqe_prev =     \
473
        &(elm)->field.tqe_next;       \
474
  else                \
475
    (head)->tqh_last = &(elm)->field.tqe_next;    \
476
  (head)->tqh_first = (elm);          \
477
  (elm)->field.tqe_prev = &(head)->tqh_first;     \
478
} while (0)
479
480
0
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
481
0
  (elm)->field.tqe_next = NULL;         \
482
0
  (elm)->field.tqe_prev = (head)->tqh_last;     \
483
0
  *(head)->tqh_last = (elm);          \
484
0
  (head)->tqh_last = &(elm)->field.tqe_next;      \
485
0
} while (0)
486
487
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {    \
488
  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
489
    (elm)->field.tqe_next->field.tqe_prev =     \
490
        &(elm)->field.tqe_next;       \
491
  else                \
492
    (head)->tqh_last = &(elm)->field.tqe_next;    \
493
  (listelm)->field.tqe_next = (elm);        \
494
  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
495
} while (0)
496
497
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
498
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
499
  (elm)->field.tqe_next = (listelm);        \
500
  *(listelm)->field.tqe_prev = (elm);       \
501
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
502
} while (0)
503
504
0
#define TAILQ_REMOVE(head, elm, field) do {       \
505
0
  if (((elm)->field.tqe_next) != NULL)       \
506
0
    (elm)->field.tqe_next->field.tqe_prev =     \
507
0
        (elm)->field.tqe_prev;       \
508
0
  else                \
509
0
    (head)->tqh_last = (elm)->field.tqe_prev;   \
510
0
  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
511
0
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
512
0
  _Q_INVALIDATE((elm)->field.tqe_next);       \
513
0
} while (0)
514
515
#define TAILQ_REPLACE(head, elm, elm2, field) do {      \
516
  if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
517
    (elm2)->field.tqe_next->field.tqe_prev =    \
518
        &(elm2)->field.tqe_next;        \
519
  else                \
520
    (head)->tqh_last = &(elm2)->field.tqe_next;   \
521
  (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
522
  *(elm2)->field.tqe_prev = (elm2);       \
523
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
524
  _Q_INVALIDATE((elm)->field.tqe_next);       \
525
} while (0)
526
527
#define TAILQ_CONCAT(head1, head2, field) do {        \
528
  if (!TAILQ_EMPTY(head2)) {          \
529
    *(head1)->tqh_last = (head2)->tqh_first;    \
530
    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
531
    (head1)->tqh_last = (head2)->tqh_last;      \
532
    TAILQ_INIT((head2));          \
533
  }               \
534
} while (0)
535
536
/*
537
 * Singly-linked Tail queue declarations.
538
 */
539
#define STAILQ_HEAD(name, type)           \
540
struct name {               \
541
  struct type *stqh_first;  /* first element */   \
542
  struct type **stqh_last;  /* addr of last next element */ \
543
}
544
545
#define STAILQ_HEAD_INITIALIZER(head)         \
546
  { NULL, &(head).stqh_first }
547
548
#define STAILQ_ENTRY(type)            \
549
struct {                \
550
  struct type *stqe_next; /* next element */      \
551
}
552
553
/*
554
 * Singly-linked Tail queue access methods.
555
 */
556
#define STAILQ_FIRST(head)  ((head)->stqh_first)
557
#define STAILQ_END(head)  NULL
558
#define STAILQ_EMPTY(head)  (STAILQ_FIRST(head) == STAILQ_END(head))
559
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
560
561
#define STAILQ_FOREACH(var, head, field)        \
562
  for ((var) = STAILQ_FIRST(head);        \
563
      (var) != STAILQ_END(head);          \
564
      (var) = STAILQ_NEXT(var, field))
565
566
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)     \
567
  for ((var) = STAILQ_FIRST(head);        \
568
      (var) && ((tvar) = STAILQ_NEXT(var, field), 1);   \
569
      (var) = (tvar))
570
571
/*
572
 * Singly-linked Tail queue functions.
573
 */
574
#define STAILQ_INIT(head) do {            \
575
  STAILQ_FIRST((head)) = NULL;          \
576
  (head)->stqh_last = &STAILQ_FIRST((head));      \
577
} while (0)
578
579
#define STAILQ_INSERT_HEAD(head, elm, field) do {     \
580
  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
581
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
582
  STAILQ_FIRST((head)) = (elm);         \
583
} while (0)
584
585
#define STAILQ_INSERT_TAIL(head, elm, field) do {     \
586
  STAILQ_NEXT((elm), field) = NULL;       \
587
  *(head)->stqh_last = (elm);         \
588
  (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
589
} while (0)
590
591
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
592
  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((elm), field)) == NULL)\
593
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
594
  STAILQ_NEXT((elm), field) = (elm);        \
595
} while (0)
596
597
#define STAILQ_REMOVE_HEAD(head, field) do {                            \
598
  if ((STAILQ_FIRST((head)) =         \
599
      STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)    \
600
    (head)->stqh_last = &STAILQ_FIRST((head));    \
601
} while (0)
602
603
#define STAILQ_REMOVE_AFTER(head, elm, field) do {                      \
604
  if ((STAILQ_NEXT(elm, field) =          \
605
      STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
606
    (head)->stqh_last = &STAILQ_NEXT((elm), field);   \
607
} while (0)
608
609
#define STAILQ_REMOVE(head, elm, type, field) do {      \
610
  if (STAILQ_FIRST((head)) == (elm)) {        \
611
    STAILQ_REMOVE_HEAD((head), field);      \
612
  } else {              \
613
    struct type *curelm = (head)->stqh_first;   \
614
    while (STAILQ_NEXT(curelm, field) != (elm))   \
615
      curelm = STAILQ_NEXT(curelm, field);    \
616
    STAILQ_REMOVE_AFTER(head, curelm, field);   \
617
  }               \
618
} while (0)
619
620
#define STAILQ_CONCAT(head1, head2) do {        \
621
  if (!STAILQ_EMPTY((head2))) {         \
622
    *(head1)->stqh_last = (head2)->stqh_first;    \
623
    (head1)->stqh_last = (head2)->stqh_last;    \
624
    STAILQ_INIT((head2));         \
625
  }               \
626
} while (0)
627
628
#define STAILQ_LAST(head, type, field)          \
629
  (STAILQ_EMPTY((head)) ? NULL :          \
630
          ((struct type *)(void *)        \
631
    ((char *)((head)->stqh_last) - offsetof(struct type, field))))
632
633
#endif  /* !_SYS_QUEUE_H_ */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/tree.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/tree.h.html index 860b3fa8f..8e4b37032 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/tree.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/sys/tree.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/sys/tree.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: tree.h,v 1.31 2023/03/08 04:43:09 guenther Exp $  */
2
/*
3
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#ifndef _SYS_TREE_H_
28
#define _SYS_TREE_H_
29
30
#include <sys/_null.h>
31
32
/*
33
 * This file defines data structures for different types of trees:
34
 * splay trees and red-black trees.
35
 *
36
 * A splay tree is a self-organizing data structure.  Every operation
37
 * on the tree causes a splay to happen.  The splay moves the requested
38
 * node to the root of the tree and partly rebalances it.
39
 *
40
 * This has the benefit that request locality causes faster lookups as
41
 * the requested nodes move to the top of the tree.  On the other hand,
42
 * every lookup causes memory writes.
43
 *
44
 * The Balance Theorem bounds the total access time for m operations
45
 * and n inserts on an initially empty tree as O((m + n)lg n).  The
46
 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
47
 *
48
 * A red-black tree is a binary search tree with the node color as an
49
 * extra attribute.  It fulfills a set of conditions:
50
 *  - every search path from the root to a leaf consists of the
51
 *    same number of black nodes,
52
 *  - each red node (except for the root) has a black parent,
53
 *  - each leaf node is black.
54
 *
55
 * Every operation on a red-black tree is bounded as O(lg n).
56
 * The maximum height of a red-black tree is 2lg (n+1).
57
 */
58
59
#define SPLAY_HEAD(name, type)            \
60
struct name {               \
61
  struct type *sph_root; /* root of the tree */     \
62
}
63
64
#define SPLAY_INITIALIZER(root)           \
65
  { NULL }
66
67
#define SPLAY_INIT(root) do {           \
68
  (root)->sph_root = NULL;          \
69
} while (0)
70
71
#define SPLAY_ENTRY(type)           \
72
struct {                \
73
  struct type *spe_left; /* left element */     \
74
  struct type *spe_right; /* right element */     \
75
}
76
77
#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
78
#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
79
#define SPLAY_ROOT(head)    (head)->sph_root
80
#define SPLAY_EMPTY(head)   (SPLAY_ROOT(head) == NULL)
81
82
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
83
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {     \
84
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \
85
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
86
  (head)->sph_root = tmp;           \
87
} while (0)
88
89
#define SPLAY_ROTATE_LEFT(head, tmp, field) do {      \
90
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \
91
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
92
  (head)->sph_root = tmp;           \
93
} while (0)
94
95
#define SPLAY_LINKLEFT(head, tmp, field) do {       \
96
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
97
  tmp = (head)->sph_root;           \
98
  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);   \
99
} while (0)
100
101
#define SPLAY_LINKRIGHT(head, tmp, field) do {        \
102
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
103
  tmp = (head)->sph_root;           \
104
  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
105
} while (0)
106
107
#define SPLAY_ASSEMBLE(head, node, left, right, field) do {   \
108
  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
109
  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
110
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
111
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
112
} while (0)
113
114
/* Generates prototypes and inline functions */
115
116
#define SPLAY_PROTOTYPE(name, type, field, cmp)       \
117
void name##_SPLAY(struct name *, struct type *);      \
118
void name##_SPLAY_MINMAX(struct name *, int);       \
119
struct type *name##_SPLAY_INSERT(struct name *, struct type *);   \
120
struct type *name##_SPLAY_REMOVE(struct name *, struct type *);   \
121
                  \
122
/* Finds the node with the same key as elm */       \
123
static __unused __inline struct type *          \
124
name##_SPLAY_FIND(struct name *head, struct type *elm)      \
125
{                 \
126
  if (SPLAY_EMPTY(head))            \
127
    return(NULL);           \
128
  name##_SPLAY(head, elm);          \
129
  if ((cmp)(elm, (head)->sph_root) == 0)        \
130
    return (head->sph_root);        \
131
  return (NULL);              \
132
}                 \
133
                  \
134
static __unused __inline struct type *          \
135
name##_SPLAY_NEXT(struct name *head, struct type *elm)      \
136
{                 \
137
  name##_SPLAY(head, elm);          \
138
  if (SPLAY_RIGHT(elm, field) != NULL) {        \
139
    elm = SPLAY_RIGHT(elm, field);        \
140
    while (SPLAY_LEFT(elm, field) != NULL) {    \
141
      elm = SPLAY_LEFT(elm, field);     \
142
    }             \
143
  } else                \
144
    elm = NULL;           \
145
  return (elm);             \
146
}                 \
147
                  \
148
static __unused __inline struct type *          \
149
name##_SPLAY_MIN_MAX(struct name *head, int val)      \
150
{                 \
151
  name##_SPLAY_MINMAX(head, val);         \
152
        return (SPLAY_ROOT(head));          \
153
}
154
155
/* Main splay operation.
156
 * Moves node close to the key of elm to top
157
 */
158
#define SPLAY_GENERATE(name, type, field, cmp)        \
159
struct type *               \
160
name##_SPLAY_INSERT(struct name *head, struct type *elm)    \
161
{                 \
162
    if (SPLAY_EMPTY(head)) {            \
163
      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;  \
164
    } else {                \
165
      int __comp;             \
166
      name##_SPLAY(head, elm);          \
167
      __comp = (cmp)(elm, (head)->sph_root);      \
168
      if(__comp < 0) {            \
169
        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
170
        SPLAY_RIGHT(elm, field) = (head)->sph_root;   \
171
        SPLAY_LEFT((head)->sph_root, field) = NULL;   \
172
      } else if (__comp > 0) {          \
173
        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
174
        SPLAY_LEFT(elm, field) = (head)->sph_root;    \
175
        SPLAY_RIGHT((head)->sph_root, field) = NULL;  \
176
      } else              \
177
        return ((head)->sph_root);        \
178
    }                 \
179
    (head)->sph_root = (elm);           \
180
    return (NULL);              \
181
}                 \
182
                  \
183
struct type *               \
184
name##_SPLAY_REMOVE(struct name *head, struct type *elm)    \
185
{                 \
186
  struct type *__tmp;           \
187
  if (SPLAY_EMPTY(head))            \
188
    return (NULL);            \
189
  name##_SPLAY(head, elm);          \
190
  if ((cmp)(elm, (head)->sph_root) == 0) {      \
191
    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \
192
      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
193
    } else {            \
194
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
195
      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
196
      name##_SPLAY(head, elm);      \
197
      SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
198
    }             \
199
    return (elm);           \
200
  }               \
201
  return (NULL);              \
202
}                 \
203
                  \
204
void                  \
205
name##_SPLAY(struct name *head, struct type *elm)     \
206
{                 \
207
  struct type __node, *__left, *__right, *__tmp;      \
208
  int __comp;             \
209
\
210
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
211
  __left = __right = &__node;         \
212
\
213
  while ((__comp = (cmp)(elm, (head)->sph_root))) {   \
214
    if (__comp < 0) {         \
215
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
216
      if (__tmp == NULL)        \
217
        break;          \
218
      if ((cmp)(elm, __tmp) < 0){     \
219
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
220
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
221
          break;        \
222
      }           \
223
      SPLAY_LINKLEFT(head, __right, field);   \
224
    } else if (__comp > 0) {        \
225
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
226
      if (__tmp == NULL)        \
227
        break;          \
228
      if ((cmp)(elm, __tmp) > 0){     \
229
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
230
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
231
          break;        \
232
      }           \
233
      SPLAY_LINKRIGHT(head, __left, field);   \
234
    }             \
235
  }               \
236
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
237
}                 \
238
                  \
239
/* Splay with either the minimum or the maximum element     \
240
 * Used to find minimum or maximum element in tree.     \
241
 */                 \
242
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
243
{                 \
244
  struct type __node, *__left, *__right, *__tmp;      \
245
\
246
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
247
  __left = __right = &__node;         \
248
\
249
  while (1) {             \
250
    if (__comp < 0) {         \
251
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
252
      if (__tmp == NULL)        \
253
        break;          \
254
      if (__comp < 0){        \
255
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
256
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
257
          break;        \
258
      }           \
259
      SPLAY_LINKLEFT(head, __right, field);   \
260
    } else if (__comp > 0) {        \
261
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
262
      if (__tmp == NULL)        \
263
        break;          \
264
      if (__comp > 0) {       \
265
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
266
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
267
          break;        \
268
      }           \
269
      SPLAY_LINKRIGHT(head, __left, field);   \
270
    }             \
271
  }               \
272
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
273
}
274
275
#define SPLAY_NEGINF  -1
276
#define SPLAY_INF 1
277
278
#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
279
#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
280
#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
281
#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
282
#define SPLAY_MIN(name, x)    (SPLAY_EMPTY(x) ? NULL  \
283
          : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
284
#define SPLAY_MAX(name, x)    (SPLAY_EMPTY(x) ? NULL  \
285
          : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
286
287
#define SPLAY_FOREACH(x, name, head)          \
288
  for ((x) = SPLAY_MIN(name, head);       \
289
       (x) != NULL;           \
290
       (x) = SPLAY_NEXT(name, head, x))
291
292
/* Macros that define a red-black tree */
293
#define RB_HEAD(name, type)           \
294
struct name {               \
295
  struct type *rbh_root; /* root of the tree */     \
296
}
297
298
#define RB_INITIALIZER(root)            \
299
  { NULL }
300
301
#define RB_INIT(root) do {            \
302
  (root)->rbh_root = NULL;          \
303
} while (0)
304
305
#define RB_BLACK  0
306
#define RB_RED    1
307
#define RB_ENTRY(type)              \
308
struct {                \
309
  struct type *rbe_left;    /* left element */    \
310
  struct type *rbe_right;   /* right element */   \
311
  struct type *rbe_parent;  /* parent element */    \
312
  int rbe_color;      /* node color */    \
313
}
314
315
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
316
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
317
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
318
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
319
#define RB_ROOT(head)     (head)->rbh_root
320
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
321
322
#define RB_SET(elm, parent, field) do {         \
323
  RB_PARENT(elm, field) = parent;         \
324
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
325
  RB_COLOR(elm, field) = RB_RED;          \
326
} while (0)
327
328
#define RB_SET_BLACKRED(black, red, field) do {       \
329
  RB_COLOR(black, field) = RB_BLACK;        \
330
  RB_COLOR(red, field) = RB_RED;          \
331
} while (0)
332
333
#ifndef RB_AUGMENT
334
#define RB_AUGMENT(x) do {} while (0)
335
#endif
336
337
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {      \
338
  (tmp) = RB_RIGHT(elm, field);         \
339
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {   \
340
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);    \
341
  }               \
342
  RB_AUGMENT(elm);            \
343
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
344
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
345
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
346
    else              \
347
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
348
  } else                \
349
    (head)->rbh_root = (tmp);       \
350
  RB_LEFT(tmp, field) = (elm);          \
351
  RB_PARENT(elm, field) = (tmp);          \
352
  RB_AUGMENT(tmp);            \
353
  if ((RB_PARENT(tmp, field)))          \
354
    RB_AUGMENT(RB_PARENT(tmp, field));      \
355
} while (0)
356
357
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
358
  (tmp) = RB_LEFT(elm, field);          \
359
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {   \
360
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);   \
361
  }               \
362
  RB_AUGMENT(elm);            \
363
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
364
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
365
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
366
    else              \
367
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
368
  } else                \
369
    (head)->rbh_root = (tmp);       \
370
  RB_RIGHT(tmp, field) = (elm);         \
371
  RB_PARENT(elm, field) = (tmp);          \
372
  RB_AUGMENT(tmp);            \
373
  if ((RB_PARENT(tmp, field)))          \
374
    RB_AUGMENT(RB_PARENT(tmp, field));      \
375
} while (0)
376
377
/* Generates prototypes and inline functions */
378
#define RB_PROTOTYPE(name, type, field, cmp)        \
379
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
380
#define RB_PROTOTYPE_STATIC(name, type, field, cmp)     \
381
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
382
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)   \
383
attr void name##_RB_INSERT_COLOR(struct name *, struct type *);   \
384
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
385
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
386
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
387
attr struct type *name##_RB_FIND(struct name *, struct type *);   \
388
attr struct type *name##_RB_NFIND(struct name *, struct type *);  \
389
attr struct type *name##_RB_NEXT(struct type *);      \
390
attr struct type *name##_RB_PREV(struct type *);      \
391
attr struct type *name##_RB_MINMAX(struct name *, int);     \
392
                  \
393
394
/* Main rb operation.
395
 * Moves node close to the key of elm to top
396
 */
397
#define RB_GENERATE(name, type, field, cmp)       \
398
  RB_GENERATE_INTERNAL(name, type, field, cmp,)
399
#define RB_GENERATE_STATIC(name, type, field, cmp)      \
400
  RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
401
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)    \
402
attr void               \
403
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
404
{                 \
405
  struct type *parent, *gparent, *tmp;        \
406
  while ((parent = RB_PARENT(elm, field)) &&      \
407
      RB_COLOR(parent, field) == RB_RED) {      \
408
    gparent = RB_PARENT(parent, field);     \
409
    if (parent == RB_LEFT(gparent, field)) {    \
410
      tmp = RB_RIGHT(gparent, field);     \
411
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
412
        RB_COLOR(tmp, field) = RB_BLACK;  \
413
        RB_SET_BLACKRED(parent, gparent, field);\
414
        elm = gparent;        \
415
        continue;       \
416
      }           \
417
      if (RB_RIGHT(parent, field) == elm) {   \
418
        RB_ROTATE_LEFT(head, parent, tmp, field);\
419
        tmp = parent;       \
420
        parent = elm;       \
421
        elm = tmp;        \
422
      }           \
423
      RB_SET_BLACKRED(parent, gparent, field);  \
424
      RB_ROTATE_RIGHT(head, gparent, tmp, field); \
425
    } else {            \
426
      tmp = RB_LEFT(gparent, field);      \
427
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
428
        RB_COLOR(tmp, field) = RB_BLACK;  \
429
        RB_SET_BLACKRED(parent, gparent, field);\
430
        elm = gparent;        \
431
        continue;       \
432
      }           \
433
      if (RB_LEFT(parent, field) == elm) {    \
434
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
435
        tmp = parent;       \
436
        parent = elm;       \
437
        elm = tmp;        \
438
      }           \
439
      RB_SET_BLACKRED(parent, gparent, field);  \
440
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
441
    }             \
442
  }               \
443
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
444
}                 \
445
                  \
446
attr void               \
447
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
448
{                 \
449
  struct type *tmp;           \
450
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
451
      elm != RB_ROOT(head)) {         \
452
    if (RB_LEFT(parent, field) == elm) {      \
453
      tmp = RB_RIGHT(parent, field);      \
454
      if (RB_COLOR(tmp, field) == RB_RED) {   \
455
        RB_SET_BLACKRED(tmp, parent, field);  \
456
        RB_ROTATE_LEFT(head, parent, tmp, field);\
457
        tmp = RB_RIGHT(parent, field);    \
458
      }           \
459
      if ((RB_LEFT(tmp, field) == NULL ||   \
460
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
461
          (RB_RIGHT(tmp, field) == NULL ||    \
462
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
463
        RB_COLOR(tmp, field) = RB_RED;    \
464
        elm = parent;       \
465
        parent = RB_PARENT(elm, field);   \
466
      } else {          \
467
        if (RB_RIGHT(tmp, field) == NULL || \
468
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
469
          struct type *oleft;   \
470
          if ((oleft = RB_LEFT(tmp, field)))\
471
            RB_COLOR(oleft, field) = RB_BLACK;\
472
          RB_COLOR(tmp, field) = RB_RED;  \
473
          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
474
          tmp = RB_RIGHT(parent, field);  \
475
        }         \
476
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
477
        RB_COLOR(parent, field) = RB_BLACK; \
478
        if (RB_RIGHT(tmp, field))   \
479
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
480
        RB_ROTATE_LEFT(head, parent, tmp, field);\
481
        elm = RB_ROOT(head);      \
482
        break;          \
483
      }           \
484
    } else {            \
485
      tmp = RB_LEFT(parent, field);     \
486
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
        RB_SET_BLACKRED(tmp, parent, field);  \
488
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
489
        tmp = RB_LEFT(parent, field);   \
490
      }           \
491
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
          (RB_RIGHT(tmp, field) == NULL ||    \
494
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
        RB_COLOR(tmp, field) = RB_RED;    \
496
        elm = parent;       \
497
        parent = RB_PARENT(elm, field);   \
498
      } else {          \
499
        if (RB_LEFT(tmp, field) == NULL ||  \
500
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
501
          struct type *oright;    \
502
          if ((oright = RB_RIGHT(tmp, field)))\
503
            RB_COLOR(oright, field) = RB_BLACK;\
504
          RB_COLOR(tmp, field) = RB_RED;  \
505
          RB_ROTATE_LEFT(head, tmp, oright, field);\
506
          tmp = RB_LEFT(parent, field); \
507
        }         \
508
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
509
        RB_COLOR(parent, field) = RB_BLACK; \
510
        if (RB_LEFT(tmp, field))    \
511
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
512
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
513
        elm = RB_ROOT(head);      \
514
        break;          \
515
      }           \
516
    }             \
517
  }               \
518
  if (elm)              \
519
    RB_COLOR(elm, field) = RB_BLACK;      \
520
}                 \
521
                  \
522
attr struct type *              \
523
name##_RB_REMOVE(struct name *head, struct type *elm)     \
524
{                 \
525
  struct type *child, *parent, *old = elm;      \
526
  int color;              \
527
  if (RB_LEFT(elm, field) == NULL)        \
528
    child = RB_RIGHT(elm, field);       \
529
  else if (RB_RIGHT(elm, field) == NULL)        \
530
    child = RB_LEFT(elm, field);        \
531
  else {                \
532
    struct type *left;          \
533
    elm = RB_RIGHT(elm, field);       \
534
    while ((left = RB_LEFT(elm, field)))      \
535
      elm = left;         \
536
    child = RB_RIGHT(elm, field);       \
537
    parent = RB_PARENT(elm, field);       \
538
    color = RB_COLOR(elm, field);       \
539
    if (child)            \
540
      RB_PARENT(child, field) = parent;   \
541
    if (parent) {           \
542
      if (RB_LEFT(parent, field) == elm)    \
543
        RB_LEFT(parent, field) = child;   \
544
      else            \
545
        RB_RIGHT(parent, field) = child;  \
546
      RB_AUGMENT(parent);       \
547
    } else              \
548
      RB_ROOT(head) = child;        \
549
    if (RB_PARENT(elm, field) == old)     \
550
      parent = elm;         \
551
    (elm)->field = (old)->field;        \
552
    if (RB_PARENT(old, field)) {        \
553
      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
554
        RB_LEFT(RB_PARENT(old, field), field) = elm;\
555
      else            \
556
        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
557
      RB_AUGMENT(RB_PARENT(old, field));    \
558
    } else              \
559
      RB_ROOT(head) = elm;        \
560
    RB_PARENT(RB_LEFT(old, field), field) = elm;    \
561
    if (RB_RIGHT(old, field))       \
562
      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
563
    if (parent) {           \
564
      left = parent;          \
565
      do {            \
566
        RB_AUGMENT(left);     \
567
      } while ((left = RB_PARENT(left, field)));  \
568
    }             \
569
    goto color;           \
570
  }               \
571
  parent = RB_PARENT(elm, field);         \
572
  color = RB_COLOR(elm, field);         \
573
  if (child)              \
574
    RB_PARENT(child, field) = parent;     \
575
  if (parent) {             \
576
    if (RB_LEFT(parent, field) == elm)      \
577
      RB_LEFT(parent, field) = child;     \
578
    else              \
579
      RB_RIGHT(parent, field) = child;    \
580
    RB_AUGMENT(parent);         \
581
  } else                \
582
    RB_ROOT(head) = child;          \
583
color:                  \
584
  if (color == RB_BLACK)            \
585
    name##_RB_REMOVE_COLOR(head, parent, child);    \
586
  return (old);             \
587
}                 \
588
                  \
589
/* Inserts a node into the RB tree */         \
590
attr struct type *              \
591
name##_RB_INSERT(struct name *head, struct type *elm)     \
592
{                 \
593
  struct type *tmp;           \
594
  struct type *parent = NULL;         \
595
  int comp = 0;             \
596
  tmp = RB_ROOT(head);            \
597
  while (tmp) {             \
598
    parent = tmp;           \
599
    comp = (cmp)(elm, parent);        \
600
    if (comp < 0)           \
601
      tmp = RB_LEFT(tmp, field);      \
602
    else if (comp > 0)          \
603
      tmp = RB_RIGHT(tmp, field);     \
604
    else              \
605
      return (tmp);         \
606
  }               \
607
  RB_SET(elm, parent, field);         \
608
  if (parent != NULL) {           \
609
    if (comp < 0)           \
610
      RB_LEFT(parent, field) = elm;     \
611
    else              \
612
      RB_RIGHT(parent, field) = elm;      \
613
    RB_AUGMENT(parent);         \
614
  } else                \
615
    RB_ROOT(head) = elm;          \
616
  name##_RB_INSERT_COLOR(head, elm);        \
617
  return (NULL);              \
618
}                 \
619
                  \
620
/* Finds the node with the same key as elm */       \
621
attr struct type *              \
622
name##_RB_FIND(struct name *head, struct type *elm)     \
623
{                 \
624
  struct type *tmp = RB_ROOT(head);       \
625
  int comp;             \
626
  while (tmp) {             \
627
    comp = cmp(elm, tmp);         \
628
    if (comp < 0)           \
629
      tmp = RB_LEFT(tmp, field);      \
630
    else if (comp > 0)          \
631
      tmp = RB_RIGHT(tmp, field);     \
632
    else              \
633
      return (tmp);         \
634
  }               \
635
  return (NULL);              \
636
}                 \
637
                  \
638
/* Finds the first node greater than or equal to the search key */  \
639
attr struct type *              \
640
name##_RB_NFIND(struct name *head, struct type *elm)      \
641
{                 \
642
  struct type *tmp = RB_ROOT(head);       \
643
  struct type *res = NULL;          \
644
  int comp;             \
645
  while (tmp) {             \
646
    comp = cmp(elm, tmp);         \
647
    if (comp < 0) {           \
648
      res = tmp;          \
649
      tmp = RB_LEFT(tmp, field);      \
650
    }             \
651
    else if (comp > 0)          \
652
      tmp = RB_RIGHT(tmp, field);     \
653
    else              \
654
      return (tmp);         \
655
  }               \
656
  return (res);             \
657
}                 \
658
                  \
659
attr struct type *              \
660
name##_RB_NEXT(struct type *elm)          \
661
{                 \
662
  if (RB_RIGHT(elm, field)) {         \
663
    elm = RB_RIGHT(elm, field);       \
664
    while (RB_LEFT(elm, field))       \
665
      elm = RB_LEFT(elm, field);      \
666
  } else {              \
667
    if (RB_PARENT(elm, field) &&        \
668
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
669
      elm = RB_PARENT(elm, field);      \
670
    else {              \
671
      while (RB_PARENT(elm, field) &&     \
672
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
673
        elm = RB_PARENT(elm, field);    \
674
      elm = RB_PARENT(elm, field);      \
675
    }             \
676
  }               \
677
  return (elm);             \
678
}                 \
679
                  \
680
attr struct type *              \
681
name##_RB_PREV(struct type *elm)          \
682
{                 \
683
  if (RB_LEFT(elm, field)) {          \
684
    elm = RB_LEFT(elm, field);        \
685
    while (RB_RIGHT(elm, field))        \
686
      elm = RB_RIGHT(elm, field);     \
687
  } else {              \
688
    if (RB_PARENT(elm, field) &&        \
689
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))  \
690
      elm = RB_PARENT(elm, field);      \
691
    else {              \
692
      while (RB_PARENT(elm, field) &&     \
693
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
694
        elm = RB_PARENT(elm, field);    \
695
      elm = RB_PARENT(elm, field);      \
696
    }             \
697
  }               \
698
  return (elm);             \
699
}                 \
700
                  \
701
attr struct type *              \
702
name##_RB_MINMAX(struct name *head, int val)        \
703
{                 \
704
  struct type *tmp = RB_ROOT(head);       \
705
  struct type *parent = NULL;         \
706
  while (tmp) {             \
707
    parent = tmp;           \
708
    if (val < 0)            \
709
      tmp = RB_LEFT(tmp, field);      \
710
    else              \
711
      tmp = RB_RIGHT(tmp, field);     \
712
  }               \
713
  return (parent);            \
714
}
715
716
#define RB_NEGINF -1
717
#define RB_INF  1
718
719
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
720
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
721
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
722
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
723
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
724
#define RB_PREV(name, x, y) name##_RB_PREV(y)
725
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
726
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
727
728
#define RB_FOREACH(x, name, head)         \
729
  for ((x) = RB_MIN(name, head);          \
730
       (x) != NULL;           \
731
       (x) = name##_RB_NEXT(x))
732
733
#define RB_FOREACH_SAFE(x, name, head, y)       \
734
  for ((x) = RB_MIN(name, head);          \
735
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);    \
736
       (x) = (y))
737
738
#define RB_FOREACH_REVERSE(x, name, head)       \
739
  for ((x) = RB_MAX(name, head);          \
740
       (x) != NULL;           \
741
       (x) = name##_RB_PREV(x))
742
743
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)     \
744
  for ((x) = RB_MAX(name, head);          \
745
      ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);    \
746
       (x) = (y))
747
748
749
/*
750
 * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
751
 *
752
 * Permission to use, copy, modify, and distribute this software for any
753
 * purpose with or without fee is hereby granted, provided that the above
754
 * copyright notice and this permission notice appear in all copies.
755
 *
756
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
757
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
758
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
759
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
760
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
761
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
762
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
763
 */
764
765
struct rb_type {
766
  int   (*t_compare)(const void *, const void *);
767
  void    (*t_augment)(void *);
768
  unsigned int    t_offset; /* offset of rb_entry in type */
769
};
770
771
struct rb_tree {
772
  struct rb_entry *rbt_root;
773
};
774
775
struct rb_entry {
776
  struct rb_entry  *rbt_parent;
777
  struct rb_entry  *rbt_left;
778
  struct rb_entry  *rbt_right;
779
  unsigned int    rbt_color;
780
};
781
782
#define RBT_HEAD(_name, _type)            \
783
struct _name {                \
784
  struct rb_tree rbh_root;          \
785
}
786
787
#define RBT_ENTRY(_type)  struct rb_entry
788
789
static inline void
790
_rb_init(struct rb_tree *rbt)
791
0
{
792
0
  rbt->rbt_root = NULL;
793
0
}
Unexecuted instantiation: common.c:_rb_init
Unexecuted instantiation: test_parser_fuzz.c:_rb_init
Unexecuted instantiation: ikev2_pld.c:_rb_init
Unexecuted instantiation: imsg_util.c:_rb_init
Unexecuted instantiation: util.c:_rb_init
794
795
static inline int
796
_rb_empty(struct rb_tree *rbt)
797
0
{
798
0
  return (rbt->rbt_root == NULL);
799
0
}
Unexecuted instantiation: common.c:_rb_empty
Unexecuted instantiation: test_parser_fuzz.c:_rb_empty
Unexecuted instantiation: ikev2_pld.c:_rb_empty
Unexecuted instantiation: imsg_util.c:_rb_empty
Unexecuted instantiation: util.c:_rb_empty
800
801
void  *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
802
void  *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
803
void  *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
804
void  *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
805
void  *_rb_root(const struct rb_type *, struct rb_tree *);
806
void  *_rb_min(const struct rb_type *, struct rb_tree *);
807
void  *_rb_max(const struct rb_type *, struct rb_tree *);
808
void  *_rb_next(const struct rb_type *, void *);
809
void  *_rb_prev(const struct rb_type *, void *);
810
void  *_rb_left(const struct rb_type *, void *);
811
void  *_rb_right(const struct rb_type *, void *);
812
void  *_rb_parent(const struct rb_type *, void *);
813
void   _rb_set_left(const struct rb_type *, void *, void *);
814
void   _rb_set_right(const struct rb_type *, void *, void *);
815
void   _rb_set_parent(const struct rb_type *, void *, void *);
816
void   _rb_poison(const struct rb_type *, void *, unsigned long);
817
int  _rb_check(const struct rb_type *, void *, unsigned long);
818
819
#define RBT_INITIALIZER(_head)  { { NULL } }
820
821
#define RBT_PROTOTYPE(_name, _type, _field, _cmp)     \
822
extern const struct rb_type *const _name##_RBT_TYPE;      \
823
                  \
824
__unused static inline void           \
825
_name##_RBT_INIT(struct _name *head)          \
826
{                 \
827
  _rb_init(&head->rbh_root);          \
828
}                 \
829
                  \
830
__unused static inline struct _type *         \
831
_name##_RBT_INSERT(struct _name *head, struct _type *elm)   \
832
{                 \
833
  return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm);  \
834
}                 \
835
                  \
836
__unused static inline struct _type *         \
837
_name##_RBT_REMOVE(struct _name *head, struct _type *elm)   \
838
{                 \
839
  return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm);  \
840
}                 \
841
                  \
842
__unused static inline struct _type *         \
843
_name##_RBT_FIND(struct _name *head, const struct _type *key)   \
844
{                 \
845
  return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key);  \
846
}                 \
847
                  \
848
__unused static inline struct _type *         \
849
_name##_RBT_NFIND(struct _name *head, const struct _type *key)    \
850
{                 \
851
  return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
852
}                 \
853
                  \
854
__unused static inline struct _type *         \
855
_name##_RBT_ROOT(struct _name *head)          \
856
{                 \
857
  return _rb_root(_name##_RBT_TYPE, &head->rbh_root);   \
858
}                 \
859
                  \
860
__unused static inline int            \
861
_name##_RBT_EMPTY(struct _name *head)         \
862
{                 \
863
  return _rb_empty(&head->rbh_root);        \
864
}                 \
865
                  \
866
__unused static inline struct _type *         \
867
_name##_RBT_MIN(struct _name *head)         \
868
{                 \
869
  return _rb_min(_name##_RBT_TYPE, &head->rbh_root);    \
870
}                 \
871
                  \
872
__unused static inline struct _type *         \
873
_name##_RBT_MAX(struct _name *head)         \
874
{                 \
875
  return _rb_max(_name##_RBT_TYPE, &head->rbh_root);    \
876
}                 \
877
                  \
878
__unused static inline struct _type *         \
879
_name##_RBT_NEXT(struct _type *elm)         \
880
{                 \
881
  return _rb_next(_name##_RBT_TYPE, elm);       \
882
}                 \
883
                  \
884
__unused static inline struct _type *         \
885
_name##_RBT_PREV(struct _type *elm)         \
886
{                 \
887
  return _rb_prev(_name##_RBT_TYPE, elm);       \
888
}                 \
889
                  \
890
__unused static inline struct _type *         \
891
_name##_RBT_LEFT(struct _type *elm)         \
892
{                 \
893
  return _rb_left(_name##_RBT_TYPE, elm);       \
894
}                 \
895
                  \
896
__unused static inline struct _type *         \
897
_name##_RBT_RIGHT(struct _type *elm)          \
898
{                 \
899
  return _rb_right(_name##_RBT_TYPE, elm);      \
900
}                 \
901
                  \
902
__unused static inline struct _type *         \
903
_name##_RBT_PARENT(struct _type *elm)         \
904
{                 \
905
  return _rb_parent(_name##_RBT_TYPE, elm);     \
906
}                 \
907
                  \
908
__unused static inline void           \
909
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left)   \
910
{                 \
911
  _rb_set_left(_name##_RBT_TYPE, elm, left);      \
912
}                 \
913
                  \
914
__unused static inline void           \
915
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right)   \
916
{                 \
917
  _rb_set_right(_name##_RBT_TYPE, elm, right);      \
918
}                 \
919
                  \
920
__unused static inline void           \
921
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent)   \
922
{                 \
923
  _rb_set_parent(_name##_RBT_TYPE, elm, parent);      \
924
}                 \
925
                  \
926
__unused static inline void           \
927
_name##_RBT_POISON(struct _type *elm, unsigned long poison)   \
928
{                 \
929
  _rb_poison(_name##_RBT_TYPE, elm, poison);      \
930
}                 \
931
                  \
932
__unused static inline int            \
933
_name##_RBT_CHECK(struct _type *elm, unsigned long poison)    \
934
{                 \
935
  return _rb_check(_name##_RBT_TYPE, elm, poison);    \
936
}
937
938
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug)   \
939
static int                \
940
_name##_RBT_COMPARE(const void *lptr, const void *rptr)     \
941
{                 \
942
  const struct _type *l = lptr, *r = rptr;      \
943
  return _cmp(l, r);            \
944
}                 \
945
static const struct rb_type _name##_RBT_INFO = {      \
946
  _name##_RBT_COMPARE,            \
947
  _aug,               \
948
  offsetof(struct _type, _field),         \
949
};                  \
950
const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
951
952
#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug)    \
953
static void               \
954
_name##_RBT_AUGMENT(void *ptr)            \
955
{                 \
956
  struct _type *p = ptr;            \
957
  return _aug(p);             \
958
}                 \
959
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
960
961
#define RBT_GENERATE(_name, _type, _field, _cmp)      \
962
    RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
963
964
#define RBT_INIT(_name, _head)    _name##_RBT_INIT(_head)
965
#define RBT_INSERT(_name, _head, _elm)  _name##_RBT_INSERT(_head, _elm)
966
#define RBT_REMOVE(_name, _head, _elm)  _name##_RBT_REMOVE(_head, _elm)
967
#define RBT_FIND(_name, _head, _key)  _name##_RBT_FIND(_head, _key)
968
#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)
969
#define RBT_ROOT(_name, _head)    _name##_RBT_ROOT(_head)
970
#define RBT_EMPTY(_name, _head)   _name##_RBT_EMPTY(_head)
971
#define RBT_MIN(_name, _head)   _name##_RBT_MIN(_head)
972
#define RBT_MAX(_name, _head)   _name##_RBT_MAX(_head)
973
#define RBT_NEXT(_name, _elm)   _name##_RBT_NEXT(_elm)
974
#define RBT_PREV(_name, _elm)   _name##_RBT_PREV(_elm)
975
#define RBT_LEFT(_name, _elm)   _name##_RBT_LEFT(_elm)
976
#define RBT_RIGHT(_name, _elm)    _name##_RBT_RIGHT(_elm)
977
#define RBT_PARENT(_name, _elm)   _name##_RBT_PARENT(_elm)
978
#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)
979
#define RBT_SET_RIGHT(_name, _elm, _r)  _name##_RBT_SET_RIGHT(_elm, _r)
980
#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)
981
#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
982
#define RBT_CHECK(_name, _elm, _p)  _name##_RBT_CHECK(_elm, _p)
983
984
#define RBT_FOREACH(_e, _name, _head)         \
985
  for ((_e) = RBT_MIN(_name, (_head));        \
986
       (_e) != NULL;            \
987
       (_e) = RBT_NEXT(_name, (_e)))
988
989
#define RBT_FOREACH_SAFE(_e, _name, _head, _n)        \
990
  for ((_e) = RBT_MIN(_name, (_head));        \
991
       (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \
992
       (_e) = (_n))
993
994
#define RBT_FOREACH_REVERSE(_e, _name, _head)       \
995
  for ((_e) = RBT_MAX(_name, (_head));        \
996
       (_e) != NULL;            \
997
       (_e) = RBT_PREV(_name, (_e)))
998
999
#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n)      \
1000
  for ((_e) = RBT_MAX(_name, (_head));        \
1001
       (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \
1002
       (_e) = (_n))
1003
1004
#endif  /* _SYS_TREE_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/sys/tree.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: tree.h,v 1.31 2023/03/08 04:43:09 guenther Exp $  */
2
/*
3
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
27
#ifndef _SYS_TREE_H_
28
#define _SYS_TREE_H_
29
30
#include <sys/_null.h>
31
32
/*
33
 * This file defines data structures for different types of trees:
34
 * splay trees and red-black trees.
35
 *
36
 * A splay tree is a self-organizing data structure.  Every operation
37
 * on the tree causes a splay to happen.  The splay moves the requested
38
 * node to the root of the tree and partly rebalances it.
39
 *
40
 * This has the benefit that request locality causes faster lookups as
41
 * the requested nodes move to the top of the tree.  On the other hand,
42
 * every lookup causes memory writes.
43
 *
44
 * The Balance Theorem bounds the total access time for m operations
45
 * and n inserts on an initially empty tree as O((m + n)lg n).  The
46
 * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
47
 *
48
 * A red-black tree is a binary search tree with the node color as an
49
 * extra attribute.  It fulfills a set of conditions:
50
 *  - every search path from the root to a leaf consists of the
51
 *    same number of black nodes,
52
 *  - each red node (except for the root) has a black parent,
53
 *  - each leaf node is black.
54
 *
55
 * Every operation on a red-black tree is bounded as O(lg n).
56
 * The maximum height of a red-black tree is 2lg (n+1).
57
 */
58
59
#define SPLAY_HEAD(name, type)            \
60
struct name {               \
61
  struct type *sph_root; /* root of the tree */     \
62
}
63
64
#define SPLAY_INITIALIZER(root)           \
65
  { NULL }
66
67
#define SPLAY_INIT(root) do {           \
68
  (root)->sph_root = NULL;          \
69
} while (0)
70
71
#define SPLAY_ENTRY(type)           \
72
struct {                \
73
  struct type *spe_left; /* left element */     \
74
  struct type *spe_right; /* right element */     \
75
}
76
77
#define SPLAY_LEFT(elm, field)    (elm)->field.spe_left
78
#define SPLAY_RIGHT(elm, field)   (elm)->field.spe_right
79
#define SPLAY_ROOT(head)    (head)->sph_root
80
#define SPLAY_EMPTY(head)   (SPLAY_ROOT(head) == NULL)
81
82
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
83
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do {     \
84
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field);  \
85
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
86
  (head)->sph_root = tmp;           \
87
} while (0)
88
89
#define SPLAY_ROTATE_LEFT(head, tmp, field) do {      \
90
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field);  \
91
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
92
  (head)->sph_root = tmp;           \
93
} while (0)
94
95
#define SPLAY_LINKLEFT(head, tmp, field) do {       \
96
  SPLAY_LEFT(tmp, field) = (head)->sph_root;      \
97
  tmp = (head)->sph_root;           \
98
  (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);   \
99
} while (0)
100
101
#define SPLAY_LINKRIGHT(head, tmp, field) do {        \
102
  SPLAY_RIGHT(tmp, field) = (head)->sph_root;     \
103
  tmp = (head)->sph_root;           \
104
  (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);  \
105
} while (0)
106
107
#define SPLAY_ASSEMBLE(head, node, left, right, field) do {   \
108
  SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
109
  SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
110
  SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
111
  SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
112
} while (0)
113
114
/* Generates prototypes and inline functions */
115
116
#define SPLAY_PROTOTYPE(name, type, field, cmp)       \
117
void name##_SPLAY(struct name *, struct type *);      \
118
void name##_SPLAY_MINMAX(struct name *, int);       \
119
struct type *name##_SPLAY_INSERT(struct name *, struct type *);   \
120
struct type *name##_SPLAY_REMOVE(struct name *, struct type *);   \
121
                  \
122
/* Finds the node with the same key as elm */       \
123
static __unused __inline struct type *          \
124
name##_SPLAY_FIND(struct name *head, struct type *elm)      \
125
{                 \
126
  if (SPLAY_EMPTY(head))            \
127
    return(NULL);           \
128
  name##_SPLAY(head, elm);          \
129
  if ((cmp)(elm, (head)->sph_root) == 0)        \
130
    return (head->sph_root);        \
131
  return (NULL);              \
132
}                 \
133
                  \
134
static __unused __inline struct type *          \
135
name##_SPLAY_NEXT(struct name *head, struct type *elm)      \
136
{                 \
137
  name##_SPLAY(head, elm);          \
138
  if (SPLAY_RIGHT(elm, field) != NULL) {        \
139
    elm = SPLAY_RIGHT(elm, field);        \
140
    while (SPLAY_LEFT(elm, field) != NULL) {    \
141
      elm = SPLAY_LEFT(elm, field);     \
142
    }             \
143
  } else                \
144
    elm = NULL;           \
145
  return (elm);             \
146
}                 \
147
                  \
148
static __unused __inline struct type *          \
149
name##_SPLAY_MIN_MAX(struct name *head, int val)      \
150
{                 \
151
  name##_SPLAY_MINMAX(head, val);         \
152
        return (SPLAY_ROOT(head));          \
153
}
154
155
/* Main splay operation.
156
 * Moves node close to the key of elm to top
157
 */
158
#define SPLAY_GENERATE(name, type, field, cmp)        \
159
struct type *               \
160
name##_SPLAY_INSERT(struct name *head, struct type *elm)    \
161
{                 \
162
    if (SPLAY_EMPTY(head)) {            \
163
      SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL;  \
164
    } else {                \
165
      int __comp;             \
166
      name##_SPLAY(head, elm);          \
167
      __comp = (cmp)(elm, (head)->sph_root);      \
168
      if(__comp < 0) {            \
169
        SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
170
        SPLAY_RIGHT(elm, field) = (head)->sph_root;   \
171
        SPLAY_LEFT((head)->sph_root, field) = NULL;   \
172
      } else if (__comp > 0) {          \
173
        SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
174
        SPLAY_LEFT(elm, field) = (head)->sph_root;    \
175
        SPLAY_RIGHT((head)->sph_root, field) = NULL;  \
176
      } else              \
177
        return ((head)->sph_root);        \
178
    }                 \
179
    (head)->sph_root = (elm);           \
180
    return (NULL);              \
181
}                 \
182
                  \
183
struct type *               \
184
name##_SPLAY_REMOVE(struct name *head, struct type *elm)    \
185
{                 \
186
  struct type *__tmp;           \
187
  if (SPLAY_EMPTY(head))            \
188
    return (NULL);            \
189
  name##_SPLAY(head, elm);          \
190
  if ((cmp)(elm, (head)->sph_root) == 0) {      \
191
    if (SPLAY_LEFT((head)->sph_root, field) == NULL) {  \
192
      (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
193
    } else {            \
194
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
195
      (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
196
      name##_SPLAY(head, elm);      \
197
      SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
198
    }             \
199
    return (elm);           \
200
  }               \
201
  return (NULL);              \
202
}                 \
203
                  \
204
void                  \
205
name##_SPLAY(struct name *head, struct type *elm)     \
206
{                 \
207
  struct type __node, *__left, *__right, *__tmp;      \
208
  int __comp;             \
209
\
210
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
211
  __left = __right = &__node;         \
212
\
213
  while ((__comp = (cmp)(elm, (head)->sph_root))) {   \
214
    if (__comp < 0) {         \
215
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
216
      if (__tmp == NULL)        \
217
        break;          \
218
      if ((cmp)(elm, __tmp) < 0){     \
219
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
220
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
221
          break;        \
222
      }           \
223
      SPLAY_LINKLEFT(head, __right, field);   \
224
    } else if (__comp > 0) {        \
225
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
226
      if (__tmp == NULL)        \
227
        break;          \
228
      if ((cmp)(elm, __tmp) > 0){     \
229
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
230
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
231
          break;        \
232
      }           \
233
      SPLAY_LINKRIGHT(head, __left, field);   \
234
    }             \
235
  }               \
236
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
237
}                 \
238
                  \
239
/* Splay with either the minimum or the maximum element     \
240
 * Used to find minimum or maximum element in tree.     \
241
 */                 \
242
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
243
{                 \
244
  struct type __node, *__left, *__right, *__tmp;      \
245
\
246
  SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
247
  __left = __right = &__node;         \
248
\
249
  while (1) {             \
250
    if (__comp < 0) {         \
251
      __tmp = SPLAY_LEFT((head)->sph_root, field);  \
252
      if (__tmp == NULL)        \
253
        break;          \
254
      if (__comp < 0){        \
255
        SPLAY_ROTATE_RIGHT(head, __tmp, field); \
256
        if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
257
          break;        \
258
      }           \
259
      SPLAY_LINKLEFT(head, __right, field);   \
260
    } else if (__comp > 0) {        \
261
      __tmp = SPLAY_RIGHT((head)->sph_root, field); \
262
      if (__tmp == NULL)        \
263
        break;          \
264
      if (__comp > 0) {       \
265
        SPLAY_ROTATE_LEFT(head, __tmp, field);  \
266
        if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
267
          break;        \
268
      }           \
269
      SPLAY_LINKRIGHT(head, __left, field);   \
270
    }             \
271
  }               \
272
  SPLAY_ASSEMBLE(head, &__node, __left, __right, field);    \
273
}
274
275
#define SPLAY_NEGINF  -1
276
#define SPLAY_INF 1
277
278
#define SPLAY_INSERT(name, x, y)  name##_SPLAY_INSERT(x, y)
279
#define SPLAY_REMOVE(name, x, y)  name##_SPLAY_REMOVE(x, y)
280
#define SPLAY_FIND(name, x, y)    name##_SPLAY_FIND(x, y)
281
#define SPLAY_NEXT(name, x, y)    name##_SPLAY_NEXT(x, y)
282
#define SPLAY_MIN(name, x)    (SPLAY_EMPTY(x) ? NULL  \
283
          : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
284
#define SPLAY_MAX(name, x)    (SPLAY_EMPTY(x) ? NULL  \
285
          : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
286
287
#define SPLAY_FOREACH(x, name, head)          \
288
  for ((x) = SPLAY_MIN(name, head);       \
289
       (x) != NULL;           \
290
       (x) = SPLAY_NEXT(name, head, x))
291
292
/* Macros that define a red-black tree */
293
#define RB_HEAD(name, type)           \
294
struct name {               \
295
  struct type *rbh_root; /* root of the tree */     \
296
}
297
298
#define RB_INITIALIZER(root)            \
299
  { NULL }
300
301
#define RB_INIT(root) do {            \
302
  (root)->rbh_root = NULL;          \
303
} while (0)
304
305
#define RB_BLACK  0
306
#define RB_RED    1
307
#define RB_ENTRY(type)              \
308
struct {                \
309
  struct type *rbe_left;    /* left element */    \
310
  struct type *rbe_right;   /* right element */   \
311
  struct type *rbe_parent;  /* parent element */    \
312
  int rbe_color;      /* node color */    \
313
}
314
315
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
316
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
317
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
318
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
319
#define RB_ROOT(head)     (head)->rbh_root
320
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
321
322
#define RB_SET(elm, parent, field) do {         \
323
  RB_PARENT(elm, field) = parent;         \
324
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
325
  RB_COLOR(elm, field) = RB_RED;          \
326
} while (0)
327
328
#define RB_SET_BLACKRED(black, red, field) do {       \
329
  RB_COLOR(black, field) = RB_BLACK;        \
330
  RB_COLOR(red, field) = RB_RED;          \
331
} while (0)
332
333
#ifndef RB_AUGMENT
334
#define RB_AUGMENT(x) do {} while (0)
335
#endif
336
337
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {      \
338
  (tmp) = RB_RIGHT(elm, field);         \
339
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) {   \
340
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);    \
341
  }               \
342
  RB_AUGMENT(elm);            \
343
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
344
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
345
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
346
    else              \
347
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
348
  } else                \
349
    (head)->rbh_root = (tmp);       \
350
  RB_LEFT(tmp, field) = (elm);          \
351
  RB_PARENT(elm, field) = (tmp);          \
352
  RB_AUGMENT(tmp);            \
353
  if ((RB_PARENT(tmp, field)))          \
354
    RB_AUGMENT(RB_PARENT(tmp, field));      \
355
} while (0)
356
357
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
358
  (tmp) = RB_LEFT(elm, field);          \
359
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) {   \
360
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);   \
361
  }               \
362
  RB_AUGMENT(elm);            \
363
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) {    \
364
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
365
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);  \
366
    else              \
367
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
368
  } else                \
369
    (head)->rbh_root = (tmp);       \
370
  RB_RIGHT(tmp, field) = (elm);         \
371
  RB_PARENT(elm, field) = (tmp);          \
372
  RB_AUGMENT(tmp);            \
373
  if ((RB_PARENT(tmp, field)))          \
374
    RB_AUGMENT(RB_PARENT(tmp, field));      \
375
} while (0)
376
377
/* Generates prototypes and inline functions */
378
#define RB_PROTOTYPE(name, type, field, cmp)        \
379
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
380
#define RB_PROTOTYPE_STATIC(name, type, field, cmp)     \
381
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
382
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)   \
383
attr void name##_RB_INSERT_COLOR(struct name *, struct type *);   \
384
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
385
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
386
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
387
attr struct type *name##_RB_FIND(struct name *, struct type *);   \
388
attr struct type *name##_RB_NFIND(struct name *, struct type *);  \
389
attr struct type *name##_RB_NEXT(struct type *);      \
390
attr struct type *name##_RB_PREV(struct type *);      \
391
attr struct type *name##_RB_MINMAX(struct name *, int);     \
392
                  \
393
394
/* Main rb operation.
395
 * Moves node close to the key of elm to top
396
 */
397
#define RB_GENERATE(name, type, field, cmp)       \
398
  RB_GENERATE_INTERNAL(name, type, field, cmp,)
399
#define RB_GENERATE_STATIC(name, type, field, cmp)      \
400
  RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)
401
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)    \
402
attr void               \
403
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
404
{                 \
405
  struct type *parent, *gparent, *tmp;        \
406
  while ((parent = RB_PARENT(elm, field)) &&      \
407
      RB_COLOR(parent, field) == RB_RED) {      \
408
    gparent = RB_PARENT(parent, field);     \
409
    if (parent == RB_LEFT(gparent, field)) {    \
410
      tmp = RB_RIGHT(gparent, field);     \
411
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
412
        RB_COLOR(tmp, field) = RB_BLACK;  \
413
        RB_SET_BLACKRED(parent, gparent, field);\
414
        elm = gparent;        \
415
        continue;       \
416
      }           \
417
      if (RB_RIGHT(parent, field) == elm) {   \
418
        RB_ROTATE_LEFT(head, parent, tmp, field);\
419
        tmp = parent;       \
420
        parent = elm;       \
421
        elm = tmp;        \
422
      }           \
423
      RB_SET_BLACKRED(parent, gparent, field);  \
424
      RB_ROTATE_RIGHT(head, gparent, tmp, field); \
425
    } else {            \
426
      tmp = RB_LEFT(gparent, field);      \
427
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {  \
428
        RB_COLOR(tmp, field) = RB_BLACK;  \
429
        RB_SET_BLACKRED(parent, gparent, field);\
430
        elm = gparent;        \
431
        continue;       \
432
      }           \
433
      if (RB_LEFT(parent, field) == elm) {    \
434
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
435
        tmp = parent;       \
436
        parent = elm;       \
437
        elm = tmp;        \
438
      }           \
439
      RB_SET_BLACKRED(parent, gparent, field);  \
440
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
441
    }             \
442
  }               \
443
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
444
}                 \
445
                  \
446
attr void               \
447
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
448
{                 \
449
  struct type *tmp;           \
450
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
451
      elm != RB_ROOT(head)) {         \
452
    if (RB_LEFT(parent, field) == elm) {      \
453
      tmp = RB_RIGHT(parent, field);      \
454
      if (RB_COLOR(tmp, field) == RB_RED) {   \
455
        RB_SET_BLACKRED(tmp, parent, field);  \
456
        RB_ROTATE_LEFT(head, parent, tmp, field);\
457
        tmp = RB_RIGHT(parent, field);    \
458
      }           \
459
      if ((RB_LEFT(tmp, field) == NULL ||   \
460
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
461
          (RB_RIGHT(tmp, field) == NULL ||    \
462
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
463
        RB_COLOR(tmp, field) = RB_RED;    \
464
        elm = parent;       \
465
        parent = RB_PARENT(elm, field);   \
466
      } else {          \
467
        if (RB_RIGHT(tmp, field) == NULL || \
468
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
469
          struct type *oleft;   \
470
          if ((oleft = RB_LEFT(tmp, field)))\
471
            RB_COLOR(oleft, field) = RB_BLACK;\
472
          RB_COLOR(tmp, field) = RB_RED;  \
473
          RB_ROTATE_RIGHT(head, tmp, oleft, field);\
474
          tmp = RB_RIGHT(parent, field);  \
475
        }         \
476
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
477
        RB_COLOR(parent, field) = RB_BLACK; \
478
        if (RB_RIGHT(tmp, field))   \
479
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
480
        RB_ROTATE_LEFT(head, parent, tmp, field);\
481
        elm = RB_ROOT(head);      \
482
        break;          \
483
      }           \
484
    } else {            \
485
      tmp = RB_LEFT(parent, field);     \
486
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
        RB_SET_BLACKRED(tmp, parent, field);  \
488
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
489
        tmp = RB_LEFT(parent, field);   \
490
      }           \
491
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
          (RB_RIGHT(tmp, field) == NULL ||    \
494
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
        RB_COLOR(tmp, field) = RB_RED;    \
496
        elm = parent;       \
497
        parent = RB_PARENT(elm, field);   \
498
      } else {          \
499
        if (RB_LEFT(tmp, field) == NULL ||  \
500
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
501
          struct type *oright;    \
502
          if ((oright = RB_RIGHT(tmp, field)))\
503
            RB_COLOR(oright, field) = RB_BLACK;\
504
          RB_COLOR(tmp, field) = RB_RED;  \
505
          RB_ROTATE_LEFT(head, tmp, oright, field);\
506
          tmp = RB_LEFT(parent, field); \
507
        }         \
508
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
509
        RB_COLOR(parent, field) = RB_BLACK; \
510
        if (RB_LEFT(tmp, field))    \
511
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
512
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
513
        elm = RB_ROOT(head);      \
514
        break;          \
515
      }           \
516
    }             \
517
  }               \
518
  if (elm)              \
519
    RB_COLOR(elm, field) = RB_BLACK;      \
520
}                 \
521
                  \
522
attr struct type *              \
523
name##_RB_REMOVE(struct name *head, struct type *elm)     \
524
{                 \
525
  struct type *child, *parent, *old = elm;      \
526
  int color;              \
527
  if (RB_LEFT(elm, field) == NULL)        \
528
    child = RB_RIGHT(elm, field);       \
529
  else if (RB_RIGHT(elm, field) == NULL)        \
530
    child = RB_LEFT(elm, field);        \
531
  else {                \
532
    struct type *left;          \
533
    elm = RB_RIGHT(elm, field);       \
534
    while ((left = RB_LEFT(elm, field)))      \
535
      elm = left;         \
536
    child = RB_RIGHT(elm, field);       \
537
    parent = RB_PARENT(elm, field);       \
538
    color = RB_COLOR(elm, field);       \
539
    if (child)            \
540
      RB_PARENT(child, field) = parent;   \
541
    if (parent) {           \
542
      if (RB_LEFT(parent, field) == elm)    \
543
        RB_LEFT(parent, field) = child;   \
544
      else            \
545
        RB_RIGHT(parent, field) = child;  \
546
      RB_AUGMENT(parent);       \
547
    } else              \
548
      RB_ROOT(head) = child;        \
549
    if (RB_PARENT(elm, field) == old)     \
550
      parent = elm;         \
551
    (elm)->field = (old)->field;        \
552
    if (RB_PARENT(old, field)) {        \
553
      if (RB_LEFT(RB_PARENT(old, field), field) == old)\
554
        RB_LEFT(RB_PARENT(old, field), field) = elm;\
555
      else            \
556
        RB_RIGHT(RB_PARENT(old, field), field) = elm;\
557
      RB_AUGMENT(RB_PARENT(old, field));    \
558
    } else              \
559
      RB_ROOT(head) = elm;        \
560
    RB_PARENT(RB_LEFT(old, field), field) = elm;    \
561
    if (RB_RIGHT(old, field))       \
562
      RB_PARENT(RB_RIGHT(old, field), field) = elm; \
563
    if (parent) {           \
564
      left = parent;          \
565
      do {            \
566
        RB_AUGMENT(left);     \
567
      } while ((left = RB_PARENT(left, field)));  \
568
    }             \
569
    goto color;           \
570
  }               \
571
  parent = RB_PARENT(elm, field);         \
572
  color = RB_COLOR(elm, field);         \
573
  if (child)              \
574
    RB_PARENT(child, field) = parent;     \
575
  if (parent) {             \
576
    if (RB_LEFT(parent, field) == elm)      \
577
      RB_LEFT(parent, field) = child;     \
578
    else              \
579
      RB_RIGHT(parent, field) = child;    \
580
    RB_AUGMENT(parent);         \
581
  } else                \
582
    RB_ROOT(head) = child;          \
583
color:                  \
584
  if (color == RB_BLACK)            \
585
    name##_RB_REMOVE_COLOR(head, parent, child);    \
586
  return (old);             \
587
}                 \
588
                  \
589
/* Inserts a node into the RB tree */         \
590
attr struct type *              \
591
name##_RB_INSERT(struct name *head, struct type *elm)     \
592
{                 \
593
  struct type *tmp;           \
594
  struct type *parent = NULL;         \
595
  int comp = 0;             \
596
  tmp = RB_ROOT(head);            \
597
  while (tmp) {             \
598
    parent = tmp;           \
599
    comp = (cmp)(elm, parent);        \
600
    if (comp < 0)           \
601
      tmp = RB_LEFT(tmp, field);      \
602
    else if (comp > 0)          \
603
      tmp = RB_RIGHT(tmp, field);     \
604
    else              \
605
      return (tmp);         \
606
  }               \
607
  RB_SET(elm, parent, field);         \
608
  if (parent != NULL) {           \
609
    if (comp < 0)           \
610
      RB_LEFT(parent, field) = elm;     \
611
    else              \
612
      RB_RIGHT(parent, field) = elm;      \
613
    RB_AUGMENT(parent);         \
614
  } else                \
615
    RB_ROOT(head) = elm;          \
616
  name##_RB_INSERT_COLOR(head, elm);        \
617
  return (NULL);              \
618
}                 \
619
                  \
620
/* Finds the node with the same key as elm */       \
621
attr struct type *              \
622
name##_RB_FIND(struct name *head, struct type *elm)     \
623
{                 \
624
  struct type *tmp = RB_ROOT(head);       \
625
  int comp;             \
626
  while (tmp) {             \
627
    comp = cmp(elm, tmp);         \
628
    if (comp < 0)           \
629
      tmp = RB_LEFT(tmp, field);      \
630
    else if (comp > 0)          \
631
      tmp = RB_RIGHT(tmp, field);     \
632
    else              \
633
      return (tmp);         \
634
  }               \
635
  return (NULL);              \
636
}                 \
637
                  \
638
/* Finds the first node greater than or equal to the search key */  \
639
attr struct type *              \
640
name##_RB_NFIND(struct name *head, struct type *elm)      \
641
{                 \
642
  struct type *tmp = RB_ROOT(head);       \
643
  struct type *res = NULL;          \
644
  int comp;             \
645
  while (tmp) {             \
646
    comp = cmp(elm, tmp);         \
647
    if (comp < 0) {           \
648
      res = tmp;          \
649
      tmp = RB_LEFT(tmp, field);      \
650
    }             \
651
    else if (comp > 0)          \
652
      tmp = RB_RIGHT(tmp, field);     \
653
    else              \
654
      return (tmp);         \
655
  }               \
656
  return (res);             \
657
}                 \
658
                  \
659
attr struct type *              \
660
name##_RB_NEXT(struct type *elm)          \
661
{                 \
662
  if (RB_RIGHT(elm, field)) {         \
663
    elm = RB_RIGHT(elm, field);       \
664
    while (RB_LEFT(elm, field))       \
665
      elm = RB_LEFT(elm, field);      \
666
  } else {              \
667
    if (RB_PARENT(elm, field) &&        \
668
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
669
      elm = RB_PARENT(elm, field);      \
670
    else {              \
671
      while (RB_PARENT(elm, field) &&     \
672
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
673
        elm = RB_PARENT(elm, field);    \
674
      elm = RB_PARENT(elm, field);      \
675
    }             \
676
  }               \
677
  return (elm);             \
678
}                 \
679
                  \
680
attr struct type *              \
681
name##_RB_PREV(struct type *elm)          \
682
{                 \
683
  if (RB_LEFT(elm, field)) {          \
684
    elm = RB_LEFT(elm, field);        \
685
    while (RB_RIGHT(elm, field))        \
686
      elm = RB_RIGHT(elm, field);     \
687
  } else {              \
688
    if (RB_PARENT(elm, field) &&        \
689
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))  \
690
      elm = RB_PARENT(elm, field);      \
691
    else {              \
692
      while (RB_PARENT(elm, field) &&     \
693
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))\
694
        elm = RB_PARENT(elm, field);    \
695
      elm = RB_PARENT(elm, field);      \
696
    }             \
697
  }               \
698
  return (elm);             \
699
}                 \
700
                  \
701
attr struct type *              \
702
name##_RB_MINMAX(struct name *head, int val)        \
703
{                 \
704
  struct type *tmp = RB_ROOT(head);       \
705
  struct type *parent = NULL;         \
706
  while (tmp) {             \
707
    parent = tmp;           \
708
    if (val < 0)            \
709
      tmp = RB_LEFT(tmp, field);      \
710
    else              \
711
      tmp = RB_RIGHT(tmp, field);     \
712
  }               \
713
  return (parent);            \
714
}
715
716
#define RB_NEGINF -1
717
#define RB_INF  1
718
719
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
720
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
721
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
722
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
723
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
724
#define RB_PREV(name, x, y) name##_RB_PREV(y)
725
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
726
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
727
728
#define RB_FOREACH(x, name, head)         \
729
  for ((x) = RB_MIN(name, head);          \
730
       (x) != NULL;           \
731
       (x) = name##_RB_NEXT(x))
732
733
#define RB_FOREACH_SAFE(x, name, head, y)       \
734
  for ((x) = RB_MIN(name, head);          \
735
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1);    \
736
       (x) = (y))
737
738
#define RB_FOREACH_REVERSE(x, name, head)       \
739
  for ((x) = RB_MAX(name, head);          \
740
       (x) != NULL;           \
741
       (x) = name##_RB_PREV(x))
742
743
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)     \
744
  for ((x) = RB_MAX(name, head);          \
745
      ((x) != NULL) && ((y) = name##_RB_PREV(x), 1);    \
746
       (x) = (y))
747
748
749
/*
750
 * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
751
 *
752
 * Permission to use, copy, modify, and distribute this software for any
753
 * purpose with or without fee is hereby granted, provided that the above
754
 * copyright notice and this permission notice appear in all copies.
755
 *
756
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
757
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
758
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
759
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
760
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
761
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
762
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
763
 */
764
765
struct rb_type {
766
  int   (*t_compare)(const void *, const void *);
767
  void    (*t_augment)(void *);
768
  unsigned int    t_offset; /* offset of rb_entry in type */
769
};
770
771
struct rb_tree {
772
  struct rb_entry *rbt_root;
773
};
774
775
struct rb_entry {
776
  struct rb_entry  *rbt_parent;
777
  struct rb_entry  *rbt_left;
778
  struct rb_entry  *rbt_right;
779
  unsigned int    rbt_color;
780
};
781
782
#define RBT_HEAD(_name, _type)            \
783
struct _name {                \
784
  struct rb_tree rbh_root;          \
785
}
786
787
#define RBT_ENTRY(_type)  struct rb_entry
788
789
static inline void
790
_rb_init(struct rb_tree *rbt)
791
0
{
792
0
  rbt->rbt_root = NULL;
793
0
}
Unexecuted instantiation: common.c:_rb_init
Unexecuted instantiation: test_parser_fuzz.c:_rb_init
Unexecuted instantiation: ikev2_pld.c:_rb_init
Unexecuted instantiation: imsg_util.c:_rb_init
Unexecuted instantiation: util.c:_rb_init
794
795
static inline int
796
_rb_empty(struct rb_tree *rbt)
797
0
{
798
0
  return (rbt->rbt_root == NULL);
799
0
}
Unexecuted instantiation: common.c:_rb_empty
Unexecuted instantiation: test_parser_fuzz.c:_rb_empty
Unexecuted instantiation: ikev2_pld.c:_rb_empty
Unexecuted instantiation: imsg_util.c:_rb_empty
Unexecuted instantiation: util.c:_rb_empty
800
801
void  *_rb_insert(const struct rb_type *, struct rb_tree *, void *);
802
void  *_rb_remove(const struct rb_type *, struct rb_tree *, void *);
803
void  *_rb_find(const struct rb_type *, struct rb_tree *, const void *);
804
void  *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);
805
void  *_rb_root(const struct rb_type *, struct rb_tree *);
806
void  *_rb_min(const struct rb_type *, struct rb_tree *);
807
void  *_rb_max(const struct rb_type *, struct rb_tree *);
808
void  *_rb_next(const struct rb_type *, void *);
809
void  *_rb_prev(const struct rb_type *, void *);
810
void  *_rb_left(const struct rb_type *, void *);
811
void  *_rb_right(const struct rb_type *, void *);
812
void  *_rb_parent(const struct rb_type *, void *);
813
void   _rb_set_left(const struct rb_type *, void *, void *);
814
void   _rb_set_right(const struct rb_type *, void *, void *);
815
void   _rb_set_parent(const struct rb_type *, void *, void *);
816
void   _rb_poison(const struct rb_type *, void *, unsigned long);
817
int  _rb_check(const struct rb_type *, void *, unsigned long);
818
819
#define RBT_INITIALIZER(_head)  { { NULL } }
820
821
#define RBT_PROTOTYPE(_name, _type, _field, _cmp)     \
822
extern const struct rb_type *const _name##_RBT_TYPE;      \
823
                  \
824
__unused static inline void           \
825
_name##_RBT_INIT(struct _name *head)          \
826
{                 \
827
  _rb_init(&head->rbh_root);          \
828
}                 \
829
                  \
830
__unused static inline struct _type *         \
831
_name##_RBT_INSERT(struct _name *head, struct _type *elm)   \
832
{                 \
833
  return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm);  \
834
}                 \
835
                  \
836
__unused static inline struct _type *         \
837
_name##_RBT_REMOVE(struct _name *head, struct _type *elm)   \
838
{                 \
839
  return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm);  \
840
}                 \
841
                  \
842
__unused static inline struct _type *         \
843
_name##_RBT_FIND(struct _name *head, const struct _type *key)   \
844
{                 \
845
  return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key);  \
846
}                 \
847
                  \
848
__unused static inline struct _type *         \
849
_name##_RBT_NFIND(struct _name *head, const struct _type *key)    \
850
{                 \
851
  return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \
852
}                 \
853
                  \
854
__unused static inline struct _type *         \
855
_name##_RBT_ROOT(struct _name *head)          \
856
{                 \
857
  return _rb_root(_name##_RBT_TYPE, &head->rbh_root);   \
858
}                 \
859
                  \
860
__unused static inline int            \
861
_name##_RBT_EMPTY(struct _name *head)         \
862
{                 \
863
  return _rb_empty(&head->rbh_root);        \
864
}                 \
865
                  \
866
__unused static inline struct _type *         \
867
_name##_RBT_MIN(struct _name *head)         \
868
{                 \
869
  return _rb_min(_name##_RBT_TYPE, &head->rbh_root);    \
870
}                 \
871
                  \
872
__unused static inline struct _type *         \
873
_name##_RBT_MAX(struct _name *head)         \
874
{                 \
875
  return _rb_max(_name##_RBT_TYPE, &head->rbh_root);    \
876
}                 \
877
                  \
878
__unused static inline struct _type *         \
879
_name##_RBT_NEXT(struct _type *elm)         \
880
{                 \
881
  return _rb_next(_name##_RBT_TYPE, elm);       \
882
}                 \
883
                  \
884
__unused static inline struct _type *         \
885
_name##_RBT_PREV(struct _type *elm)         \
886
{                 \
887
  return _rb_prev(_name##_RBT_TYPE, elm);       \
888
}                 \
889
                  \
890
__unused static inline struct _type *         \
891
_name##_RBT_LEFT(struct _type *elm)         \
892
{                 \
893
  return _rb_left(_name##_RBT_TYPE, elm);       \
894
}                 \
895
                  \
896
__unused static inline struct _type *         \
897
_name##_RBT_RIGHT(struct _type *elm)          \
898
{                 \
899
  return _rb_right(_name##_RBT_TYPE, elm);      \
900
}                 \
901
                  \
902
__unused static inline struct _type *         \
903
_name##_RBT_PARENT(struct _type *elm)         \
904
{                 \
905
  return _rb_parent(_name##_RBT_TYPE, elm);     \
906
}                 \
907
                  \
908
__unused static inline void           \
909
_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left)   \
910
{                 \
911
  _rb_set_left(_name##_RBT_TYPE, elm, left);      \
912
}                 \
913
                  \
914
__unused static inline void           \
915
_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right)   \
916
{                 \
917
  _rb_set_right(_name##_RBT_TYPE, elm, right);      \
918
}                 \
919
                  \
920
__unused static inline void           \
921
_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent)   \
922
{                 \
923
  _rb_set_parent(_name##_RBT_TYPE, elm, parent);      \
924
}                 \
925
                  \
926
__unused static inline void           \
927
_name##_RBT_POISON(struct _type *elm, unsigned long poison)   \
928
{                 \
929
  _rb_poison(_name##_RBT_TYPE, elm, poison);      \
930
}                 \
931
                  \
932
__unused static inline int            \
933
_name##_RBT_CHECK(struct _type *elm, unsigned long poison)    \
934
{                 \
935
  return _rb_check(_name##_RBT_TYPE, elm, poison);    \
936
}
937
938
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug)   \
939
static int                \
940
_name##_RBT_COMPARE(const void *lptr, const void *rptr)     \
941
{                 \
942
  const struct _type *l = lptr, *r = rptr;      \
943
  return _cmp(l, r);            \
944
}                 \
945
static const struct rb_type _name##_RBT_INFO = {      \
946
  _name##_RBT_COMPARE,            \
947
  _aug,               \
948
  offsetof(struct _type, _field),         \
949
};                  \
950
const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO
951
952
#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug)    \
953
static void               \
954
_name##_RBT_AUGMENT(void *ptr)            \
955
{                 \
956
  struct _type *p = ptr;            \
957
  return _aug(p);             \
958
}                 \
959
RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
960
961
#define RBT_GENERATE(_name, _type, _field, _cmp)      \
962
    RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
963
964
#define RBT_INIT(_name, _head)    _name##_RBT_INIT(_head)
965
#define RBT_INSERT(_name, _head, _elm)  _name##_RBT_INSERT(_head, _elm)
966
#define RBT_REMOVE(_name, _head, _elm)  _name##_RBT_REMOVE(_head, _elm)
967
#define RBT_FIND(_name, _head, _key)  _name##_RBT_FIND(_head, _key)
968
#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)
969
#define RBT_ROOT(_name, _head)    _name##_RBT_ROOT(_head)
970
#define RBT_EMPTY(_name, _head)   _name##_RBT_EMPTY(_head)
971
#define RBT_MIN(_name, _head)   _name##_RBT_MIN(_head)
972
#define RBT_MAX(_name, _head)   _name##_RBT_MAX(_head)
973
#define RBT_NEXT(_name, _elm)   _name##_RBT_NEXT(_elm)
974
#define RBT_PREV(_name, _elm)   _name##_RBT_PREV(_elm)
975
#define RBT_LEFT(_name, _elm)   _name##_RBT_LEFT(_elm)
976
#define RBT_RIGHT(_name, _elm)    _name##_RBT_RIGHT(_elm)
977
#define RBT_PARENT(_name, _elm)   _name##_RBT_PARENT(_elm)
978
#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)
979
#define RBT_SET_RIGHT(_name, _elm, _r)  _name##_RBT_SET_RIGHT(_elm, _r)
980
#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)
981
#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
982
#define RBT_CHECK(_name, _elm, _p)  _name##_RBT_CHECK(_elm, _p)
983
984
#define RBT_FOREACH(_e, _name, _head)         \
985
  for ((_e) = RBT_MIN(_name, (_head));        \
986
       (_e) != NULL;            \
987
       (_e) = RBT_NEXT(_name, (_e)))
988
989
#define RBT_FOREACH_SAFE(_e, _name, _head, _n)        \
990
  for ((_e) = RBT_MIN(_name, (_head));        \
991
       (_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \
992
       (_e) = (_n))
993
994
#define RBT_FOREACH_REVERSE(_e, _name, _head)       \
995
  for ((_e) = RBT_MAX(_name, (_head));        \
996
       (_e) != NULL;            \
997
       (_e) = RBT_PREV(_name, (_e)))
998
999
#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n)      \
1000
  for ((_e) = RBT_MAX(_name, (_head));        \
1001
       (_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \
1002
       (_e) = (_n))
1003
1004
#endif  /* _SYS_TREE_H_ */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.c.html index 462a8a191..29d83c21c 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/vis.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.c,v 1.26 2022/05/04 18:57:50 deraadt Exp $ */
2
/*-
3
 * Copyright (c) 1989, 1993
4
 *  The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
32
33
#if !defined(HAVE_STRNVIS)
34
35
#include <sys/types.h>
36
#include <errno.h>
37
#include <ctype.h>
38
#include <limits.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <vis.h>
42
43
static int
44
isoctal(int c)
45
0
{
46
0
  u_char uc = c;
47
48
0
  return uc >= '0' && uc <= '7';
49
0
}
50
51
static int
52
isvisible(int c, int flag)
53
0
{
54
0
  int vis_sp = flag & VIS_SP;
55
0
  int vis_tab = flag & VIS_TAB;
56
0
  int vis_nl = flag & VIS_NL;
57
0
  int vis_safe = flag & VIS_SAFE;
58
0
  int vis_glob = flag & VIS_GLOB;
59
0
  int vis_all = flag & VIS_ALL;
60
0
  u_char uc = c;
61
62
0
  if (c == '\\' || !vis_all) {
63
0
    if ((u_int)c <= UCHAR_MAX && isascii(uc) &&
64
0
        ((c != '*' && c != '?' && c != '[' && c != '#') || !vis_glob) &&
65
0
        isgraph(uc))
66
0
      return 1;
67
0
    if (!vis_sp && c == ' ')
68
0
      return 1;
69
0
    if (!vis_tab && c == '\t')
70
0
      return 1;
71
0
    if (!vis_nl && c == '\n')
72
0
      return 1;
73
0
    if (vis_safe && (c == '\b' || c == '\007' || c == '\r' || isgraph(uc)))
74
0
      return 1;
75
0
  }
76
0
  return 0;
77
0
}
78
79
/*
80
 * vis - visually encode characters
81
 */
82
char *
83
vis(char *dst, int c, int flag, int nextc)
84
0
{
85
0
  int vis_dq = flag & VIS_DQ;
86
0
  int vis_noslash = flag & VIS_NOSLASH;
87
0
  int vis_cstyle = flag & VIS_CSTYLE;
88
0
  int vis_octal = flag & VIS_OCTAL;
89
0
  int vis_glob = flag & VIS_GLOB;
90
91
0
  if (isvisible(c, flag)) {
92
0
    if ((c == '"' && vis_dq) ||
93
0
        (c == '\\' && !vis_noslash))
94
0
      *dst++ = '\\';
95
0
    *dst++ = c;
96
0
    *dst = '\0';
97
0
    return (dst);
98
0
  }
99
100
0
  if (vis_cstyle) {
101
0
    switch (c) {
102
0
    case '\n':
103
0
      *dst++ = '\\';
104
0
      *dst++ = 'n';
105
0
      goto done;
106
0
    case '\r':
107
0
      *dst++ = '\\';
108
0
      *dst++ = 'r';
109
0
      goto done;
110
0
    case '\b':
111
0
      *dst++ = '\\';
112
0
      *dst++ = 'b';
113
0
      goto done;
114
0
    case '\a':
115
0
      *dst++ = '\\';
116
0
      *dst++ = 'a';
117
0
      goto done;
118
0
    case '\v':
119
0
      *dst++ = '\\';
120
0
      *dst++ = 'v';
121
0
      goto done;
122
0
    case '\t':
123
0
      *dst++ = '\\';
124
0
      *dst++ = 't';
125
0
      goto done;
126
0
    case '\f':
127
0
      *dst++ = '\\';
128
0
      *dst++ = 'f';
129
0
      goto done;
130
0
    case ' ':
131
0
      *dst++ = '\\';
132
0
      *dst++ = 's';
133
0
      goto done;
134
0
    case '\0':
135
0
      *dst++ = '\\';
136
0
      *dst++ = '0';
137
0
      if (isoctal(nextc)) {
138
0
        *dst++ = '0';
139
0
        *dst++ = '0';
140
0
      }
141
0
      goto done;
142
0
    }
143
0
  }
144
0
  if (((c & 0177) == ' ') || vis_octal ||
145
0
      (vis_glob && (c == '*' || c == '?' || c == '[' || c == '#'))) {
146
0
    *dst++ = '\\';
147
0
    *dst++ = ((u_char)c >> 6 & 07) + '0';
148
0
    *dst++ = ((u_char)c >> 3 & 07) + '0';
149
0
    *dst++ = ((u_char)c & 07) + '0';
150
0
    goto done;
151
0
  }
152
0
  if (!vis_noslash)
153
0
    *dst++ = '\\';
154
0
  if (c & 0200) {
155
0
    c &= 0177;
156
0
    *dst++ = 'M';
157
0
  }
158
0
  if (iscntrl((u_char)c)) {
159
0
    *dst++ = '^';
160
0
    if (c == 0177)
161
0
      *dst++ = '?';
162
0
    else
163
0
      *dst++ = c + '@';
164
0
  } else {
165
0
    *dst++ = '-';
166
0
    *dst++ = c;
167
0
  }
168
0
done:
169
0
  *dst = '\0';
170
0
  return (dst);
171
0
}
172
173
/*
174
 * strvis, strnvis, strvisx - visually encode characters from src into dst
175
 *  
176
 *  Dst must be 4 times the size of src to account for possible
177
 *  expansion.  The length of dst, not including the trailing NULL,
178
 *  is returned. 
179
 *
180
 *  Strnvis will write no more than siz-1 bytes (and will NULL terminate).
181
 *  The number of bytes needed to fully encode the string is returned.
182
 *
183
 *  Strvisx encodes exactly len bytes from src into dst.
184
 *  This is useful for encoding a block of data.
185
 */
186
int
187
strvis(char *dst, const char *src, int flag)
188
0
{
189
0
  char c;
190
0
  char *start;
191
192
0
  for (start = dst; (c = *src);)
193
0
    dst = vis(dst, c, flag, *++src);
194
0
  *dst = '\0';
195
0
  return (dst - start);
196
0
}
197
198
int
199
strnvis(char *dst, const char *src, size_t siz, int flag)
200
0
{
201
0
  int vis_dq = flag & VIS_DQ;
202
0
  int vis_noslash = flag & VIS_NOSLASH;
203
0
  char *start, *end;
204
0
  char tbuf[5];
205
0
  int c, i;
206
207
0
  i = 0;
208
0
  for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
209
0
    if (isvisible(c, flag)) {
210
0
      if ((c == '"' && vis_dq) ||
211
0
          (c == '\\' && !vis_noslash)) {
212
        /* need space for the extra '\\' */
213
0
        if (dst + 1 >= end) {
214
0
          i = 2;
215
0
          break;
216
0
        }
217
0
        *dst++ = '\\';
218
0
      }
219
0
      i = 1;
220
0
      *dst++ = c;
221
0
      src++;
222
0
    } else {
223
0
      i = vis(tbuf, c, flag, *++src) - tbuf;
224
0
      if (dst + i <= end) {
225
0
        memcpy(dst, tbuf, i);
226
0
        dst += i;
227
0
      } else {
228
0
        src--;
229
0
        break;
230
0
      }
231
0
    }
232
0
  }
233
0
  if (siz > 0)
234
0
    *dst = '\0';
235
0
  if (dst + i > end) {
236
    /* adjust return value for truncation */
237
0
    while ((c = *src))
238
0
      dst += vis(tbuf, c, flag, *++src) - tbuf;
239
0
  }
240
0
  return (dst - start);
241
0
}
242
243
int
244
stravis(char **outp, const char *src, int flag)
245
0
{
246
0
  char *buf;
247
0
  int len, serrno;
248
249
0
  buf = reallocarray(NULL, 4, strlen(src) + 1);
250
0
  if (buf == NULL)
251
0
    return -1;
252
0
  len = strvis(buf, src, flag);
253
0
  serrno = errno;
254
0
  *outp = realloc(buf, len + 1);
255
0
  if (*outp == NULL) {
256
0
    *outp = buf;
257
0
    errno = serrno;
258
0
  }
259
0
  return (len);
260
0
}
261
262
int
263
strvisx(char *dst, const char *src, size_t len, int flag)
264
0
{
265
0
  char c;
266
0
  char *start;
267
268
0
  for (start = dst; len > 1; len--) {
269
0
    c = *src;
270
0
    dst = vis(dst, c, flag, *++src);
271
0
  }
272
0
  if (len)
273
0
    dst = vis(dst, *src, flag, '\0');
274
0
  *dst = '\0';
275
0
  return (dst - start);
276
0
}
277
278
#endif
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/vis.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.c,v 1.26 2022/05/04 18:57:50 deraadt Exp $ */
2
/*-
3
 * Copyright (c) 1989, 1993
4
 *  The Regents of the University of California.  All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the University nor the names of its contributors
15
 *    may be used to endorse or promote products derived from this software
16
 *    without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 */
30
31
/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */
32
33
#if !defined(HAVE_STRNVIS)
34
35
#include <sys/types.h>
36
#include <errno.h>
37
#include <ctype.h>
38
#include <limits.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <vis.h>
42
43
static int
44
isoctal(int c)
45
0
{
46
0
  u_char uc = c;
47
48
0
  return uc >= '0' && uc <= '7';
49
0
}
50
51
static int
52
isvisible(int c, int flag)
53
0
{
54
0
  int vis_sp = flag & VIS_SP;
55
0
  int vis_tab = flag & VIS_TAB;
56
0
  int vis_nl = flag & VIS_NL;
57
0
  int vis_safe = flag & VIS_SAFE;
58
0
  int vis_glob = flag & VIS_GLOB;
59
0
  int vis_all = flag & VIS_ALL;
60
0
  u_char uc = c;
61
62
0
  if (c == '\\' || !vis_all) {
63
0
    if ((u_int)c <= UCHAR_MAX && isascii(uc) &&
64
0
        ((c != '*' && c != '?' && c != '[' && c != '#') || !vis_glob) &&
65
0
        isgraph(uc))
66
0
      return 1;
67
0
    if (!vis_sp && c == ' ')
68
0
      return 1;
69
0
    if (!vis_tab && c == '\t')
70
0
      return 1;
71
0
    if (!vis_nl && c == '\n')
72
0
      return 1;
73
0
    if (vis_safe && (c == '\b' || c == '\007' || c == '\r' || isgraph(uc)))
74
0
      return 1;
75
0
  }
76
0
  return 0;
77
0
}
78
79
/*
80
 * vis - visually encode characters
81
 */
82
char *
83
vis(char *dst, int c, int flag, int nextc)
84
0
{
85
0
  int vis_dq = flag & VIS_DQ;
86
0
  int vis_noslash = flag & VIS_NOSLASH;
87
0
  int vis_cstyle = flag & VIS_CSTYLE;
88
0
  int vis_octal = flag & VIS_OCTAL;
89
0
  int vis_glob = flag & VIS_GLOB;
90
91
0
  if (isvisible(c, flag)) {
92
0
    if ((c == '"' && vis_dq) ||
93
0
        (c == '\\' && !vis_noslash))
94
0
      *dst++ = '\\';
95
0
    *dst++ = c;
96
0
    *dst = '\0';
97
0
    return (dst);
98
0
  }
99
100
0
  if (vis_cstyle) {
101
0
    switch (c) {
102
0
    case '\n':
103
0
      *dst++ = '\\';
104
0
      *dst++ = 'n';
105
0
      goto done;
106
0
    case '\r':
107
0
      *dst++ = '\\';
108
0
      *dst++ = 'r';
109
0
      goto done;
110
0
    case '\b':
111
0
      *dst++ = '\\';
112
0
      *dst++ = 'b';
113
0
      goto done;
114
0
    case '\a':
115
0
      *dst++ = '\\';
116
0
      *dst++ = 'a';
117
0
      goto done;
118
0
    case '\v':
119
0
      *dst++ = '\\';
120
0
      *dst++ = 'v';
121
0
      goto done;
122
0
    case '\t':
123
0
      *dst++ = '\\';
124
0
      *dst++ = 't';
125
0
      goto done;
126
0
    case '\f':
127
0
      *dst++ = '\\';
128
0
      *dst++ = 'f';
129
0
      goto done;
130
0
    case ' ':
131
0
      *dst++ = '\\';
132
0
      *dst++ = 's';
133
0
      goto done;
134
0
    case '\0':
135
0
      *dst++ = '\\';
136
0
      *dst++ = '0';
137
0
      if (isoctal(nextc)) {
138
0
        *dst++ = '0';
139
0
        *dst++ = '0';
140
0
      }
141
0
      goto done;
142
0
    }
143
0
  }
144
0
  if (((c & 0177) == ' ') || vis_octal ||
145
0
      (vis_glob && (c == '*' || c == '?' || c == '[' || c == '#'))) {
146
0
    *dst++ = '\\';
147
0
    *dst++ = ((u_char)c >> 6 & 07) + '0';
148
0
    *dst++ = ((u_char)c >> 3 & 07) + '0';
149
0
    *dst++ = ((u_char)c & 07) + '0';
150
0
    goto done;
151
0
  }
152
0
  if (!vis_noslash)
153
0
    *dst++ = '\\';
154
0
  if (c & 0200) {
155
0
    c &= 0177;
156
0
    *dst++ = 'M';
157
0
  }
158
0
  if (iscntrl((u_char)c)) {
159
0
    *dst++ = '^';
160
0
    if (c == 0177)
161
0
      *dst++ = '?';
162
0
    else
163
0
      *dst++ = c + '@';
164
0
  } else {
165
0
    *dst++ = '-';
166
0
    *dst++ = c;
167
0
  }
168
0
done:
169
0
  *dst = '\0';
170
0
  return (dst);
171
0
}
172
173
/*
174
 * strvis, strnvis, strvisx - visually encode characters from src into dst
175
 *  
176
 *  Dst must be 4 times the size of src to account for possible
177
 *  expansion.  The length of dst, not including the trailing NULL,
178
 *  is returned. 
179
 *
180
 *  Strnvis will write no more than siz-1 bytes (and will NULL terminate).
181
 *  The number of bytes needed to fully encode the string is returned.
182
 *
183
 *  Strvisx encodes exactly len bytes from src into dst.
184
 *  This is useful for encoding a block of data.
185
 */
186
int
187
strvis(char *dst, const char *src, int flag)
188
0
{
189
0
  char c;
190
0
  char *start;
191
192
0
  for (start = dst; (c = *src);)
193
0
    dst = vis(dst, c, flag, *++src);
194
0
  *dst = '\0';
195
0
  return (dst - start);
196
0
}
197
198
int
199
strnvis(char *dst, const char *src, size_t siz, int flag)
200
0
{
201
0
  int vis_dq = flag & VIS_DQ;
202
0
  int vis_noslash = flag & VIS_NOSLASH;
203
0
  char *start, *end;
204
0
  char tbuf[5];
205
0
  int c, i;
206
207
0
  i = 0;
208
0
  for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
209
0
    if (isvisible(c, flag)) {
210
0
      if ((c == '"' && vis_dq) ||
211
0
          (c == '\\' && !vis_noslash)) {
212
        /* need space for the extra '\\' */
213
0
        if (dst + 1 >= end) {
214
0
          i = 2;
215
0
          break;
216
0
        }
217
0
        *dst++ = '\\';
218
0
      }
219
0
      i = 1;
220
0
      *dst++ = c;
221
0
      src++;
222
0
    } else {
223
0
      i = vis(tbuf, c, flag, *++src) - tbuf;
224
0
      if (dst + i <= end) {
225
0
        memcpy(dst, tbuf, i);
226
0
        dst += i;
227
0
      } else {
228
0
        src--;
229
0
        break;
230
0
      }
231
0
    }
232
0
  }
233
0
  if (siz > 0)
234
0
    *dst = '\0';
235
0
  if (dst + i > end) {
236
    /* adjust return value for truncation */
237
0
    while ((c = *src))
238
0
      dst += vis(tbuf, c, flag, *++src) - tbuf;
239
0
  }
240
0
  return (dst - start);
241
0
}
242
243
int
244
stravis(char **outp, const char *src, int flag)
245
0
{
246
0
  char *buf;
247
0
  int len, serrno;
248
249
0
  buf = reallocarray(NULL, 4, strlen(src) + 1);
250
0
  if (buf == NULL)
251
0
    return -1;
252
0
  len = strvis(buf, src, flag);
253
0
  serrno = errno;
254
0
  *outp = realloc(buf, len + 1);
255
0
  if (*outp == NULL) {
256
0
    *outp = buf;
257
0
    errno = serrno;
258
0
  }
259
0
  return (len);
260
0
}
261
262
int
263
strvisx(char *dst, const char *src, size_t len, int flag)
264
0
{
265
0
  char c;
266
0
  char *start;
267
268
0
  for (start = dst; len > 1; len--) {
269
0
    c = *src;
270
0
    dst = vis(dst, c, flag, *++src);
271
0
  }
272
0
  if (len)
273
0
    dst = vis(dst, *src, flag, '\0');
274
0
  *dst = '\0';
275
0
  return (dst - start);
276
0
}
277
278
#endif
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.h.html index 526ccd38c..bc110eeea 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/compat/vis.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/compat/vis.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $  */
2
/*  $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $  */
3
4
/*-
5
 * Copyright (c) 1990 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)vis.h 5.9 (Berkeley) 4/3/91
33
 */
34
35
/* OPENBSD ORIGINAL: include/vis.h */
36
37
#ifdef HAVE_CONFIG_H
38
#include "includes.h"
39
#endif
40
41
#ifndef _VIS_H_
42
#define _VIS_H_
43
44
#include <sys/types.h>
45
#include <limits.h>
46
47
/*
48
 * to select alternate encoding format
49
 */
50
0
#define VIS_OCTAL 0x01  /* use octal \ddd format */
51
0
#define VIS_CSTYLE  0x02  /* use \[nrft0..] where appropriate */
52
53
/*
54
 * to alter set of characters encoded (default is to encode all
55
 * non-graphic except space, tab, and newline).
56
 */
57
0
#define VIS_SP    0x04  /* also encode space */
58
0
#define VIS_TAB   0x08  /* also encode tab */
59
0
#define VIS_NL    0x10  /* also encode newline */
60
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
61
0
#define VIS_SAFE  0x20  /* only encode "unsafe" characters */
62
0
#define VIS_DQ    0x200  /* backslash-escape double quotes */
63
0
#define VIS_ALL   0x400  /* encode all characters */
64
65
/*
66
 * other
67
 */
68
0
#define VIS_NOSLASH 0x40  /* inhibit printing '\' */
69
0
#define VIS_GLOB  0x100  /* encode glob(3) magics and '#' */
70
71
/*
72
 * unvis return codes
73
 */
74
#define UNVIS_VALID  1  /* character valid */
75
#define UNVIS_VALIDPUSH  2  /* character valid, push back passed char */
76
#define UNVIS_NOCHAR   3  /* valid sequence, no character produced */
77
#define UNVIS_SYNBAD  -1  /* unrecognized escape sequence */
78
#define UNVIS_ERROR -2  /* decoder in unknown state (unrecoverable) */
79
80
/*
81
 * unvis flags
82
 */
83
#define UNVIS_END 1 /* no more characters */
84
85
char  *vis(char *, int, int, int);
86
int strvis(char *, const char *, int);
87
int stravis(char **, const char *, int);
88
int strnvis(char *, const char *, size_t, int)
89
    __attribute__ ((__bounded__(__string__,1,3)));
90
int strvisx(char *, const char *, size_t, int)
91
    __attribute__ ((__bounded__(__string__,1,3)));
92
int strunvis(char *, const char *);
93
int unvis(char *, char, int *, int);
94
ssize_t strnunvis(char *, const char *, size_t)
95
    __attribute__ ((__bounded__(__string__,1,3)));
96
97
#endif /* !_VIS_H_ */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/compat/vis.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 millert Exp $  */
2
/*  $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $  */
3
4
/*-
5
 * Copyright (c) 1990 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)vis.h 5.9 (Berkeley) 4/3/91
33
 */
34
35
/* OPENBSD ORIGINAL: include/vis.h */
36
37
#ifdef HAVE_CONFIG_H
38
#include "includes.h"
39
#endif
40
41
#ifndef _VIS_H_
42
#define _VIS_H_
43
44
#include <sys/types.h>
45
#include <limits.h>
46
47
/*
48
 * to select alternate encoding format
49
 */
50
0
#define VIS_OCTAL 0x01  /* use octal \ddd format */
51
0
#define VIS_CSTYLE  0x02  /* use \[nrft0..] where appropriate */
52
53
/*
54
 * to alter set of characters encoded (default is to encode all
55
 * non-graphic except space, tab, and newline).
56
 */
57
0
#define VIS_SP    0x04  /* also encode space */
58
0
#define VIS_TAB   0x08  /* also encode tab */
59
0
#define VIS_NL    0x10  /* also encode newline */
60
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
61
0
#define VIS_SAFE  0x20  /* only encode "unsafe" characters */
62
0
#define VIS_DQ    0x200  /* backslash-escape double quotes */
63
0
#define VIS_ALL   0x400  /* encode all characters */
64
65
/*
66
 * other
67
 */
68
0
#define VIS_NOSLASH 0x40  /* inhibit printing '\' */
69
0
#define VIS_GLOB  0x100  /* encode glob(3) magics and '#' */
70
71
/*
72
 * unvis return codes
73
 */
74
#define UNVIS_VALID  1  /* character valid */
75
#define UNVIS_VALIDPUSH  2  /* character valid, push back passed char */
76
#define UNVIS_NOCHAR   3  /* valid sequence, no character produced */
77
#define UNVIS_SYNBAD  -1  /* unrecognized escape sequence */
78
#define UNVIS_ERROR -2  /* decoder in unknown state (unrecoverable) */
79
80
/*
81
 * unvis flags
82
 */
83
#define UNVIS_END 1 /* no more characters */
84
85
char  *vis(char *, int, int, int);
86
int strvis(char *, const char *, int);
87
int stravis(char **, const char *, int);
88
int strnvis(char *, const char *, size_t, int)
89
    __attribute__ ((__bounded__(__string__,1,3)));
90
int strvisx(char *, const char *, size_t, int)
91
    __attribute__ ((__bounded__(__string__,1,3)));
92
int strunvis(char *, const char *);
93
int unvis(char *, char, int *, int);
94
ssize_t strnunvis(char *, const char *, size_t)
95
    __attribute__ ((__bounded__(__string__,1,3)));
96
97
#endif /* !_VIS_H_ */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/iked.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/iked.h.html index 77fa25cb1..adc6251f3 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/iked.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/iked.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/iked.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: iked.h,v 1.224 2023/08/11 11:24:55 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019-2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/tree.h>
22
#include <sys/queue.h>
23
#include <arpa/inet.h>
24
#include <limits.h>
25
#include <imsg.h>
26
27
#include <openssl/evp.h>
28
29
#include "openbsd-compat.h"
30
31
#include "types.h"
32
#include "dh.h"
33
34
#define MAXIMUM(a,b) (((a)>(b))?(a):(b))
35
#define MINIMUM(a,b) (((a)<(b))?(a):(b))
36
#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
37
38
#ifndef IKED_H
39
#define IKED_H
40
41
/*
42
 * Common IKEv1/IKEv2 header
43
 */
44
45
struct ike_header {
46
  uint64_t   ike_ispi;    /* Initiator cookie */
47
  uint64_t   ike_rspi;    /* Responder cookie */
48
  uint8_t    ike_nextpayload; /* Next payload type */
49
  uint8_t    ike_version;   /* Major/Minor version number */
50
  uint8_t    ike_exchange;    /* Exchange type */
51
  uint8_t    ike_flags;   /* Message options */
52
  uint32_t   ike_msgid;   /* Message identifier */
53
  uint32_t   ike_length;    /* Total message length */
54
} __packed;
55
56
/*
57
 * Common daemon infrastructure, local imsg etc.
58
 */
59
60
struct imsgev {
61
  struct imsgbuf     ibuf;
62
  void      (*handler)(int, short, void *);
63
  struct event     ev;
64
  struct privsep_proc *proc;
65
  void      *data;
66
  short      events;
67
  const char    *name;
68
};
69
70
#define IMSG_SIZE_CHECK(imsg, p) do {       \
71
  if (IMSG_DATA_SIZE(imsg) < sizeof(*p))      \
72
    fatalx("bad length imsg received");   \
73
} while (0)
74
#define IMSG_DATA_SIZE(imsg)  ((imsg)->hdr.len - IMSG_HEADER_SIZE)
75
76
#define IKED_ADDR_EQ(_a, _b)            \
77
  ((_a)->addr_mask == (_b)->addr_mask &&        \
78
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
79
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) == 0)
80
81
#define IKED_ADDR_NEQ(_a, _b)           \
82
  ((_a)->addr_mask != (_b)->addr_mask ||        \
83
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
84
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) != 0)
85
86
/* initially control.h */
87
struct control_sock {
88
  const char  *cs_name;
89
  struct event   cs_ev;
90
  struct event   cs_evt;
91
  int    cs_fd;
92
  int    cs_restricted;
93
  void    *cs_env;
94
95
  TAILQ_ENTRY(control_sock) cs_entry;
96
};
97
TAILQ_HEAD(control_socks, control_sock);
98
99
struct ctl_conn {
100
  TAILQ_ENTRY(ctl_conn)  entry;
101
  uint8_t      flags;
102
#define CTL_CONN_NOTIFY    0x01
103
  struct imsgev    iev;
104
};
105
TAILQ_HEAD(ctl_connlist, ctl_conn);
106
107
extern enum privsep_procid privsep_process;
108
109
/*
110
 * Runtime structures
111
 */
112
113
struct iked_timer {
114
  struct event   tmr_ev;
115
  struct iked *tmr_env;
116
  void    (*tmr_cb)(struct iked *, void *);
117
  void    *tmr_cbarg;
118
};
119
120
struct iked_spi {
121
  uint64_t   spi;
122
  uint8_t    spi_size;
123
  uint8_t    spi_protoid;
124
};
125
126
struct iked_proposal {
127
  uint8_t        prop_id;
128
  uint8_t        prop_protoid;
129
130
  struct iked_spi      prop_localspi;
131
  struct iked_spi      prop_peerspi;
132
133
  struct iked_transform   *prop_xforms;
134
  unsigned int       prop_nxforms;
135
136
  TAILQ_ENTRY(iked_proposal)   prop_entry;
137
};
138
TAILQ_HEAD(iked_proposals, iked_proposal);
139
140
struct iked_addr {
141
  int        addr_af;
142
  struct sockaddr_storage    addr;
143
  uint8_t        addr_mask;
144
  int        addr_net;
145
  in_port_t      addr_port;
146
};
147
148
struct iked_ts {
149
  struct iked_addr     ts_addr;
150
  uint8_t        ts_ipproto;
151
  TAILQ_ENTRY(iked_ts)     ts_entry;
152
};
153
TAILQ_HEAD(iked_tss, iked_ts);
154
155
struct iked_flow {
156
  struct iked_addr     flow_src;
157
  struct iked_addr     flow_dst;
158
  unsigned int       flow_dir;  /* in/out */
159
  int        flow_rdomain;
160
  struct iked_addr     flow_prenat;
161
  int        flow_fixed;
162
163
  unsigned int       flow_loaded; /* pfkey done */
164
165
  uint8_t        flow_saproto;
166
  uint8_t        flow_ipproto;
167
168
  struct iked_addr    *flow_local;  /* outer source */
169
  struct iked_addr    *flow_peer; /* outer dest */
170
  struct iked_sa      *flow_ikesa;  /* parent SA */
171
172
  int        flow_transport;
173
174
  RB_ENTRY(iked_flow)    flow_node;
175
  TAILQ_ENTRY(iked_flow)     flow_entry;
176
};
177
RB_HEAD(iked_flows, iked_flow);
178
TAILQ_HEAD(iked_saflows, iked_flow);
179
180
struct iked_childsa {
181
  uint8_t        csa_saproto; /* IPsec protocol */
182
  unsigned int       csa_dir; /* in/out */
183
184
  uint64_t       csa_peerspi; /* peer relation */
185
  uint8_t        csa_loaded;  /* pfkey done */
186
  uint8_t        csa_rekey; /* will be deleted */
187
  uint8_t        csa_allocated; /* from the kernel */
188
  uint8_t        csa_persistent;/* do not rekey */
189
  uint8_t        csa_esn; /* use ESN */
190
  uint8_t        csa_transport; /* transport mode */
191
192
  struct iked_spi      csa_spi;
193
194
  struct ibuf     *csa_encrkey; /* encryption key */
195
  uint16_t       csa_encrid;  /* encryption xform id */
196
197
  struct ibuf     *csa_integrkey; /* auth key */
198
  uint16_t       csa_integrid;  /* auth xform id */
199
200
  struct iked_addr    *csa_local; /* outer source */
201
  struct iked_addr    *csa_peer;  /* outer dest */
202
  struct iked_sa      *csa_ikesa; /* parent SA */
203
204
  struct iked_childsa   *csa_peersa;  /* peer */
205
206
  struct iked_childsa   *csa_bundled; /* IPCOMP */
207
208
  uint16_t       csa_pfsgrpid;  /* pfs group id */
209
210
  RB_ENTRY(iked_childsa)     csa_node;
211
  TAILQ_ENTRY(iked_childsa)  csa_entry;
212
};
213
RB_HEAD(iked_activesas, iked_childsa);
214
TAILQ_HEAD(iked_childsas, iked_childsa);
215
216
217
struct iked_static_id {
218
  uint8_t   id_type;
219
  uint8_t   id_length;
220
  uint8_t   id_offset;
221
  uint8_t   id_data[IKED_ID_SIZE];
222
};
223
224
struct iked_auth {
225
  uint8_t   auth_method;
226
  uint8_t   auth_eap;     /* optional EAP */
227
  uint8_t   auth_length;      /* zero if EAP */
228
  uint8_t   auth_data[IKED_PSK_SIZE];
229
};
230
231
struct iked_cfg {
232
  uint8_t        cfg_action;
233
  uint16_t       cfg_type;
234
  union {
235
    struct iked_addr   address;
236
  } cfg;
237
};
238
239
TAILQ_HEAD(iked_sapeers, iked_sa);
240
241
struct iked_lifetime {
242
  uint64_t       lt_bytes;
243
  uint64_t       lt_seconds;
244
};
245
246
struct iked_policy {
247
  unsigned int       pol_id;
248
  char         pol_name[IKED_ID_SIZE];
249
  unsigned int       pol_iface;
250
251
#define IKED_SKIP_FLAGS      0
252
#define IKED_SKIP_AF       1
253
#define IKED_SKIP_SRC_ADDR     2
254
#define IKED_SKIP_DST_ADDR     3
255
#define IKED_SKIP_COUNT      4
256
  struct iked_policy    *pol_skip[IKED_SKIP_COUNT];
257
258
  uint8_t        pol_flags;
259
#define IKED_POLICY_PASSIVE    0x00
260
#define IKED_POLICY_DEFAULT    0x01
261
#define IKED_POLICY_ACTIVE     0x02
262
#define IKED_POLICY_REFCNT     0x04
263
#define IKED_POLICY_QUICK    0x08
264
#define IKED_POLICY_SKIP     0x10
265
#define IKED_POLICY_IPCOMP     0x20
266
0
#define IKED_POLICY_TRANSPORT    0x40
267
#define IKED_POLICY_ROUTING    0x80
268
269
  int        pol_refcnt;
270
271
  uint8_t        pol_certreqtype;
272
273
  int        pol_af;
274
  int        pol_rdomain;
275
  uint8_t        pol_saproto;
276
  unsigned int       pol_ipproto[IKED_IPPROTO_MAX];
277
  unsigned int       pol_nipproto;
278
279
  struct iked_addr     pol_peer;
280
  struct iked_static_id    pol_peerid;
281
  uint32_t       pol_peerdh;
282
283
  struct iked_addr     pol_local;
284
  struct iked_static_id    pol_localid;
285
286
  struct iked_auth     pol_auth;
287
288
  char         pol_tag[IKED_TAG_SIZE];
289
  unsigned int       pol_tap;
290
291
  struct iked_proposals    pol_proposals;
292
  size_t         pol_nproposals;
293
294
  struct iked_flows    pol_flows;
295
  size_t         pol_nflows;
296
  struct iked_tss      pol_tssrc; /* Traffic Selectors Initiator*/
297
  size_t         pol_tssrc_count;
298
  struct iked_tss      pol_tsdst; /* Traffic Selectors Responder*/
299
  size_t         pol_tsdst_count;
300
301
  struct iked_cfg      pol_cfg[IKED_CFG_MAX];
302
  unsigned int       pol_ncfg;
303
304
  uint32_t       pol_rekey; /* ike SA lifetime */
305
  struct iked_lifetime     pol_lifetime;  /* child SA lifetime */
306
307
  struct iked_sapeers    pol_sapeers;
308
309
  TAILQ_ENTRY(iked_policy)   pol_entry;
310
};
311
TAILQ_HEAD(iked_policies, iked_policy);
312
313
struct iked_hash {
314
  uint8_t    hash_type; /* PRF or INTEGR */
315
  uint16_t   hash_id; /* IKE PRF/INTEGR hash id */
316
  const void  *hash_priv; /* Identifying the hash alg */
317
  void    *hash_ctx;  /* Context of the current invocation */
318
  int    hash_fixedkey; /* Requires fixed key length */
319
  struct ibuf *hash_key;  /* MAC key derived from key seed */
320
  size_t     hash_length; /* Output length */
321
  size_t     hash_trunc;  /* Truncate the output length */
322
  struct iked_hash *hash_prf; /* PRF pointer */
323
  int    hash_isaead;
324
};
325
326
struct iked_cipher {
327
  uint8_t    encr_type; /* ENCR */
328
  uint16_t   encr_id; /* IKE ENCR hash id */
329
  const void  *encr_priv; /* Identifying the hash alg */
330
  void    *encr_ctx;  /* Context of the current invocation */
331
  int    encr_fixedkey; /* Requires fixed key length */
332
  struct ibuf *encr_key;  /* MAC key derived from key seed */
333
  struct ibuf *encr_iv; /* Initialization Vector */
334
  uint64_t   encr_civ;  /* Counter IV for GCM */
335
  size_t     encr_ivlength; /* IV length */
336
  size_t     encr_length; /* Block length */
337
  size_t     encr_saltlength; /* IV salt length */
338
  uint16_t   encr_authid; /* ID of associated authentication */
339
};
340
341
struct iked_dsa {
342
  uint8_t    dsa_method;  /* AUTH method */
343
  const void  *dsa_priv;  /* PRF or signature hash function */
344
  void    *dsa_ctx; /* PRF or signature hash ctx */
345
  struct ibuf *dsa_keydata; /* public, private or shared key */
346
  void    *dsa_key; /* parsed public or private key */
347
  int    dsa_hmac;  /* HMAC or public/private key */
348
  int    dsa_sign;  /* Sign or verify operation */
349
  uint32_t   dsa_flags; /* State flags */
350
};
351
352
struct iked_id {
353
  uint8_t    id_type;
354
  uint8_t    id_offset;
355
  struct ibuf *id_buf;
356
};
357
358
#define IKED_REQ_CERT   0x0001  /* get local certificate (if required) */
359
#define IKED_REQ_CERTVALID  0x0002  /* validated the peer cert */
360
#define IKED_REQ_CERTREQ  0x0004  /* CERTREQ has been received */
361
#define IKED_REQ_AUTH   0x0008  /* AUTH payload */
362
#define IKED_REQ_AUTHVALID  0x0010  /* AUTH payload has been verified */
363
#define IKED_REQ_SA   0x0020  /* SA available */
364
#define IKED_REQ_EAPVALID 0x0040  /* EAP payload has been verified */
365
#define IKED_REQ_CHILDSA  0x0080  /* Child SA initiated */
366
#define IKED_REQ_INF    0x0100  /* Informational exchange initiated */
367
368
#define IKED_REQ_BITS \
369
    "\20\01CERT\02CERTVALID\03CERTREQ\04AUTH\05AUTHVALID\06SA\07EAPVALID" \
370
    "\10CHILDSA\11INF"
371
372
TAILQ_HEAD(iked_msgqueue, iked_msg_retransmit);
373
TAILQ_HEAD(iked_msg_fragqueue, iked_message);
374
375
struct iked_sahdr {
376
  uint64_t       sh_ispi; /* Initiator SPI */
377
  uint64_t       sh_rspi; /* Responder SPI */
378
  unsigned int       sh_initiator;  /* Is initiator? */
379
} __packed;
380
381
struct iked_kex {
382
  struct ibuf     *kex_inonce;  /* Ni */
383
  struct ibuf     *kex_rnonce;  /* Nr */
384
385
  struct dh_group     *kex_dhgroup; /* DH group */
386
  struct ibuf     *kex_dhiexchange;
387
  struct ibuf     *kex_dhrexchange;
388
  struct ibuf     *kex_dhpeer;  /* pointer to i or r */
389
};
390
391
struct iked_frag_entry {
392
  uint8_t *frag_data;
393
  size_t   frag_size;
394
};
395
396
struct iked_frag {
397
  struct iked_frag_entry  **frag_arr; /* list of fragment buffers */
398
  size_t        frag_count; /* number of fragments received */
399
0
#define IKED_FRAG_TOTAL_MAX   111    /* upper limit (64kB / 576B) */
400
  size_t        frag_total; /* total numbe of fragments */
401
  size_t        frag_total_size;
402
  uint8_t       frag_nextpayload;
403
404
};
405
406
struct iked_ipcomp {
407
  uint16_t       ic_cpi_out;  /* outgoing CPI */
408
  uint16_t       ic_cpi_in; /* incoming CPI */
409
  uint8_t        ic_transform;  /* transform */
410
};
411
412
struct iked_sa {
413
  struct iked_sahdr    sa_hdr;
414
  uint32_t       sa_msgid;  /* Last request rcvd */
415
  int        sa_msgid_set;  /* msgid initialized */
416
  uint32_t       sa_msgid_current;  /* Current requested rcvd */
417
  uint32_t       sa_reqid;  /* Next request sent */
418
419
  int        sa_type;
420
#define IKED_SATYPE_LOOKUP     0    /* Used for lookup */
421
#define IKED_SATYPE_LOCAL    1    /* Local SA */
422
423
  struct iked_addr     sa_peer;
424
  struct iked_addr     sa_peer_loaded;/* MOBIKE */
425
  struct iked_addr     sa_local;
426
  int        sa_fd;
427
428
  struct iked_frag     sa_fragments;
429
430
  int        sa_natt; /* for IKE messages */
431
  int        sa_udpencap; /* for pfkey */
432
  int        sa_usekeepalive;/* NAT-T keepalive */
433
434
  int        sa_state;
435
  unsigned int       sa_stateflags;
436
  unsigned int       sa_stateinit;  /* SA_INIT */
437
  unsigned int       sa_statevalid; /* IKE_AUTH */
438
439
  int        sa_cp;   /* XXX */
440
  struct iked_addr    *sa_cp_addr;  /* requested address */
441
  struct iked_addr    *sa_cp_addr6; /* requested address */
442
  struct iked_addr    *sa_cp_dns; /* requested dns */
443
444
  struct iked_policy    *sa_policy;
445
  struct timeval       sa_timecreated;
446
  struct timeval       sa_timeused;
447
448
  char        *sa_tag;
449
  const char      *sa_reason; /* reason for close */
450
451
  struct iked_kex      sa_kex;
452
/* XXX compat defines until everything is converted */
453
#define sa_inonce   sa_kex.kex_inonce
454
#define sa_rnonce   sa_kex.kex_rnonce
455
#define sa_dhgroup    sa_kex.kex_dhgroup
456
#define sa_dhiexchange    sa_kex.kex_dhiexchange
457
#define sa_dhrexchange    sa_kex.kex_dhrexchange
458
#define sa_dhpeer   sa_kex.kex_dhpeer
459
460
  struct iked_hash    *sa_prf;  /* PRF alg */
461
  struct iked_hash    *sa_integr; /* integrity alg */
462
  struct iked_cipher    *sa_encr; /* encryption alg */
463
464
  struct ibuf     *sa_key_d;  /* SK_d */
465
  struct ibuf     *sa_key_iauth;  /* SK_ai */
466
  struct ibuf     *sa_key_rauth;  /* SK_ar */
467
  struct ibuf     *sa_key_iencr;  /* SK_ei */
468
  struct ibuf     *sa_key_rencr;  /* SK_er */
469
  struct ibuf     *sa_key_iprf; /* SK_pi */
470
  struct ibuf     *sa_key_rprf; /* SK_pr */
471
472
  struct ibuf     *sa_1stmsg; /* for initiator AUTH */
473
  struct ibuf     *sa_2ndmsg; /* for responder AUTH */
474
  struct iked_id       sa_localauth;  /* local AUTH message */
475
  struct iked_id       sa_peerauth; /* peer AUTH message */
476
  int        sa_sigsha2;  /* use SHA2 for signatures */
477
108k
#define IKED_SCERT_MAX  3 /* max # of supplemental cert payloads */
478
479
  struct iked_id       sa_iid;  /* initiator id */
480
  struct iked_id       sa_rid;  /* responder id */
481
  struct iked_id       sa_icert;  /* initiator cert */
482
  struct iked_id       sa_rcert;  /* responder cert */
483
  struct iked_id       sa_scert[IKED_SCERT_MAX]; /* supplemental certs */
484
#define IKESA_SRCID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_iid : &(x)->sa_rid)
485
#define IKESA_DSTID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_rid : &(x)->sa_iid)
486
487
  char        *sa_eapid;  /* EAP identity */
488
  struct iked_id       sa_eap;  /* EAP challenge */
489
  struct ibuf     *sa_eapmsk; /* EAK session key */
490
491
  struct iked_proposals    sa_proposals;  /* SA proposals */
492
  struct iked_childsas     sa_childsas; /* IPsec Child SAs */
493
  struct iked_saflows    sa_flows;  /* IPsec flows */
494
495
  struct iked_sa      *sa_nexti;  /* initiated IKE SA */
496
  struct iked_sa      *sa_previ;  /* matching back pointer */
497
  struct iked_sa      *sa_nextr;  /* simultaneous rekey */
498
  struct iked_sa      *sa_prevr;  /* matching back pointer */
499
  uint64_t       sa_rekeyspi; /* peerspi CSA rekey */
500
  struct ibuf     *sa_simult; /* simultaneous rekey */
501
502
  struct iked_ipcomp     sa_ipcompi;  /* IPcomp initator */
503
  struct iked_ipcomp     sa_ipcompr;  /* IPcomp responder */
504
505
  int        sa_mobike; /* MOBIKE */
506
  int        sa_frag; /* fragmentation */
507
508
  int        sa_use_transport_mode; /* peer requested */
509
  int        sa_used_transport_mode; /* we enabled */
510
511
  struct iked_timer    sa_timer;  /* SA timeouts */
512
#define IKED_IKE_SA_EXCHANGE_TIMEOUT   300    /* 5 minutes */
513
#define IKED_IKE_SA_REKEY_TIMEOUT  120    /* 2 minutes */
514
#define IKED_IKE_SA_DELETE_TIMEOUT   120    /* 2 minutes */
515
#define IKED_IKE_SA_ALIVE_TIMEOUT  60   /* 1 minute */
516
517
  struct iked_timer    sa_keepalive;  /* keepalive timer */
518
#define IKED_IKE_SA_KEEPALIVE_TIMEOUT  20
519
520
  struct iked_timer    sa_rekey;  /* rekey timeout */
521
  int        sa_tmpfail;
522
523
  struct iked_msgqueue     sa_requests; /* request queue */
524
#define IKED_RETRANSMIT_TIMEOUT    2    /* 2 seconds */
525
526
  struct iked_msgqueue     sa_responses;  /* response queue */
527
#define IKED_RESPONSE_TIMEOUT    120    /* 2 minutes */
528
529
  TAILQ_ENTRY(iked_sa)     sa_peer_entry;
530
  RB_ENTRY(iked_sa)    sa_entry;  /* all SAs */
531
532
  RB_ENTRY(iked_sa)    sa_dstid_entry;  /* SAs by DSTID */
533
  int        sa_dstid_entry_valid;    /* sa_dstid_entry valid */
534
535
  struct iked_addr    *sa_addrpool; /* address from pool */
536
  RB_ENTRY(iked_sa)    sa_addrpool_entry; /* pool entries */
537
538
  struct iked_addr    *sa_addrpool6;  /* address from pool */
539
  RB_ENTRY(iked_sa)    sa_addrpool6_entry;  /* pool entries */
540
  time_t         sa_last_recvd;
541
#define IKED_IKE_SA_LAST_RECVD_TIMEOUT   300    /* 5 minutes */
542
};
543
RB_HEAD(iked_sas, iked_sa);
544
RB_HEAD(iked_dstid_sas, iked_sa);
545
RB_HEAD(iked_addrpool, iked_sa);
546
RB_HEAD(iked_addrpool6, iked_sa);
547
548
/* stats */
549
550
struct iked_stats {
551
  uint64_t  ikes_sa_created;
552
  uint64_t  ikes_sa_established_total;
553
  uint64_t  ikes_sa_established_current;  /* gauge */
554
  uint64_t  ikes_sa_established_failures;
555
  uint64_t  ikes_sa_proposals_negotiate_failures;
556
  uint64_t  ikes_sa_rekeyed;
557
  uint64_t  ikes_sa_removed;
558
  uint64_t  ikes_csa_created;
559
  uint64_t  ikes_csa_removed;
560
  uint64_t  ikes_msg_sent;
561
  uint64_t  ikes_msg_send_failures;
562
  uint64_t  ikes_msg_rcvd;
563
  uint64_t  ikes_msg_rcvd_busy;
564
  uint64_t  ikes_msg_rcvd_dropped;
565
  uint64_t  ikes_retransmit_request;
566
  uint64_t  ikes_retransmit_response;
567
  uint64_t  ikes_retransmit_limit;
568
  uint64_t  ikes_frag_sent;
569
  uint64_t  ikes_frag_send_failures;
570
  uint64_t  ikes_frag_rcvd;
571
  uint64_t  ikes_frag_rcvd_drop;
572
  uint64_t  ikes_frag_reass_ok;
573
  uint64_t  ikes_frag_reass_drop;
574
  uint64_t  ikes_update_addresses_sent;
575
  uint64_t  ikes_dpd_sent;
576
  uint64_t  ikes_keepalive_sent;
577
};
578
579
0
#define ikestat_add(env, c, n)  do { env->sc_stats.c += (n); } while(0)
580
0
#define ikestat_inc(env, c) ikestat_add(env, c, 1)
581
#define ikestat_dec(env, c) ikestat_add(env, c, -1)
582
583
struct iked_certreq {
584
  struct ibuf     *cr_data;
585
  uint8_t        cr_type;
586
  SIMPLEQ_ENTRY(iked_certreq)  cr_entry;
587
};
588
SIMPLEQ_HEAD(iked_certreqs, iked_certreq);
589
590
#define EAP_STATE_IDENTITY    (1)
591
#define EAP_STATE_MSCHAPV2_CHALLENGE  (2)
592
#define EAP_STATE_MSCHAPV2_SUCCESS  (3)
593
#define EAP_STATE_SUCCESS   (4)
594
595
struct eap_msg {
596
  char    *eam_identity;
597
  char    *eam_user;
598
  int    eam_type;
599
  uint8_t    eam_id;
600
  uint8_t    eam_msrid;
601
  int    eam_success;
602
  int    eam_found;
603
  int    eam_response;
604
  uint8_t    eam_challenge[16];
605
  uint8_t    eam_ntresponse[24];
606
  uint32_t   eam_state;
607
};
608
609
struct iked_message {
610
  struct ibuf   *msg_data;
611
  size_t       msg_offset;
612
613
  struct sockaddr_storage  msg_local;
614
  socklen_t    msg_locallen;
615
616
  struct sockaddr_storage  msg_peer;
617
  socklen_t    msg_peerlen;
618
619
  struct iked_socket  *msg_sock;
620
621
  int      msg_fd;
622
  int      msg_response;
623
  int      msg_responded;
624
  int      msg_valid;
625
  int      msg_natt;
626
  int      msg_natt_rcvd;
627
  int      msg_nat_detected;
628
  int      msg_error;
629
  int      msg_e;
630
  struct iked_message *msg_parent;
631
632
  /* Associated policy and SA */
633
  struct iked_policy  *msg_policy;
634
  struct iked_sa    *msg_sa;
635
636
  uint32_t     msg_msgid;
637
  uint8_t      msg_exchange;
638
639
  /* Parsed information */
640
  struct iked_proposals  msg_proposals;
641
  struct iked_certreqs   msg_certreqs;
642
  struct iked_spi    msg_rekey;
643
  struct ibuf   *msg_nonce; /* dh NONCE */
644
  uint16_t     msg_dhgroup; /* dh group */
645
  struct ibuf   *msg_ke;  /* dh key exchange */
646
  struct iked_id     msg_auth;  /* AUTH payload */
647
  struct iked_id     msg_peerid;
648
  struct iked_id     msg_localid;
649
  struct iked_id     msg_cert;
650
  struct iked_id     msg_scert[IKED_SCERT_MAX]; /* supplemental certs */
651
  struct ibuf   *msg_cookie;
652
  uint16_t     msg_group;
653
  uint16_t     msg_cpi;
654
  uint8_t      msg_transform;
655
  uint16_t     msg_flags;
656
  struct eap_msg     msg_eap;
657
  size_t       msg_del_spisize;
658
  size_t       msg_del_cnt;
659
  struct ibuf   *msg_del_buf;
660
  int      msg_del_protoid;
661
  int      msg_cp;
662
  struct iked_addr  *msg_cp_addr; /* requested address */
663
  struct iked_addr  *msg_cp_addr6;  /* requested address */
664
  struct iked_addr  *msg_cp_dns;  /* requested dns */
665
666
  /* MOBIKE */
667
  int      msg_update_sa_addresses;
668
  struct ibuf   *msg_cookie2;
669
670
  /* Parse stack */
671
  struct iked_proposal  *msg_prop;
672
  uint16_t     msg_attrlength;
673
674
  /* Retransmit queue */
675
  TAILQ_ENTRY(iked_message)
676
         msg_entry;
677
};
678
679
struct iked_msg_retransmit {
680
  struct iked_msg_fragqueue       mrt_frags;
681
  TAILQ_ENTRY(iked_msg_retransmit)      mrt_entry;
682
  struct iked_timer         mrt_timer;
683
  int             mrt_tries;
684
#define IKED_RETRANSMIT_TRIES  5    /* try 5 times */
685
};
686
687
3.04k
#define IKED_MSG_NAT_SRC_IP       0x01
688
19.5k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
136
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
73
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
241
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
131
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
128
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
239
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
348
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
36
#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN   0x0400
701
702
703
struct iked_user {
704
  char       usr_name[LOGIN_NAME_MAX];
705
  char       usr_pass[IKED_PASSWORD_SIZE];
706
  RB_ENTRY(iked_user)  usr_entry;
707
};
708
RB_HEAD(iked_users, iked_user);
709
710
struct privsep_pipes {
711
  int       *pp_pipes[PROC_MAX];
712
};
713
714
struct privsep {
715
  struct privsep_pipes    *ps_pipes[PROC_MAX];
716
  struct privsep_pipes    *ps_pp;
717
718
  struct imsgev     *ps_ievs[PROC_MAX];
719
  const char      *ps_title[PROC_MAX];
720
  pid_t        ps_pid[PROC_MAX];
721
  struct passwd     *ps_pw;
722
  int        ps_noaction;
723
724
  struct control_sock    ps_csock;
725
  struct control_socks     ps_rcsocks;
726
727
  unsigned int       ps_instances[PROC_MAX];
728
  unsigned int       ps_ninstances;
729
  unsigned int       ps_instance;
730
731
  /* Event and signal handlers */
732
  struct event       ps_evsigint;
733
  struct event       ps_evsigterm;
734
  struct event       ps_evsigchld;
735
  struct event       ps_evsighup;
736
  struct event       ps_evsigpipe;
737
  struct event       ps_evsigusr1;
738
739
  struct iked     *ps_env;
740
};
741
742
struct privsep_proc {
743
  const char    *p_title;
744
  enum privsep_procid  p_id;
745
  int     (*p_cb)(int, struct privsep_proc *,
746
            struct imsg *);
747
  void      (*p_init)(struct privsep *,
748
            struct privsep_proc *);
749
  const char    *p_chroot;
750
  struct passwd   *p_pw;
751
  struct privsep    *p_ps;
752
  void      (*p_shutdown)(void);
753
};
754
755
struct privsep_fd {
756
  enum privsep_procid    pf_procid;
757
  unsigned int       pf_instance;
758
};
759
760
#define PROC_PARENT_SOCK_FILENO 3
761
#define PROC_MAX_INSTANCES      32
762
763
struct iked_ocsp_entry {
764
  TAILQ_ENTRY(iked_ocsp_entry) ioe_entry; /* next request */
765
  void      *ioe_ocsp;  /* private ocsp request data */
766
};
767
TAILQ_HEAD(iked_ocsp_requests, iked_ocsp_entry);
768
769
/*
770
 * Daemon configuration
771
 */
772
773
enum natt_mode {
774
  NATT_DEFAULT, /* send/recv with both :500 and NAT-T port */
775
  NATT_DISABLE, /* send/recv with only :500 */
776
  NATT_FORCE, /* send/recv with only NAT-T port */
777
};
778
779
struct iked_static {
780
  uint64_t     st_alive_timeout;
781
  int      st_enforcesingleikesa;
782
  uint8_t      st_frag; /* fragmentation */
783
  uint8_t      st_mobike; /* MOBIKE */
784
  in_port_t    st_nattport;
785
  int      st_stickyaddress; /* addr per DSTID  */
786
  int      st_vendorid;
787
};
788
789
struct iked {
790
  char         sc_conffile[PATH_MAX];
791
792
  uint32_t       sc_opts;
793
  enum natt_mode       sc_nattmode;
794
  uint8_t        sc_passive;
795
  uint8_t        sc_decoupled;
796
797
  struct iked_static     sc_static;
798
799
#define sc_alive_timeout  sc_static.st_alive_timeout
800
#define sc_enforcesingleikesa sc_static.st_enforcesingleikesa
801
#define sc_frag     sc_static.st_frag
802
#define sc_mobike   sc_static.st_mobike
803
#define sc_nattport   sc_static.st_nattport
804
#define sc_stickyaddress  sc_static.st_stickyaddress
805
#define sc_vendorid   sc_static.st_vendorid
806
807
  struct iked_policies     sc_policies;
808
  struct iked_policy    *sc_defaultcon;
809
810
  struct iked_sas      sc_sas;
811
  struct iked_dstid_sas    sc_dstid_sas;
812
  struct iked_activesas    sc_activesas;
813
  struct iked_flows    sc_activeflows;
814
  struct iked_users    sc_users;
815
816
  struct iked_stats    sc_stats;
817
818
  void        *sc_priv; /* per-process */
819
820
  int        sc_pfkey;  /* ike process */
821
  struct event       sc_pfkeyev;
822
  struct event       sc_routeev;
823
  uint8_t        sc_certreqtype;
824
  struct ibuf     *sc_certreq;
825
  void        *sc_vroute;
826
827
  struct iked_socket    *sc_sock4[2];
828
  struct iked_socket    *sc_sock6[2];
829
830
  struct iked_timer    sc_inittmr;
831
#define IKED_INITIATOR_INITIAL     2
832
#define IKED_INITIATOR_INTERVAL    60
833
834
  struct privsep       sc_ps;
835
836
  struct iked_ocsp_requests  sc_ocsp;
837
  char        *sc_ocsp_url;
838
  long         sc_ocsp_tolerate;
839
  long         sc_ocsp_maxage;
840
841
  struct iked_addrpool     sc_addrpool;
842
  struct iked_addrpool6    sc_addrpool6;
843
844
  int        sc_cert_partial_chain;
845
#ifdef WITH_APPARMOR
846
  int        sc_apparmor;
847
#endif
848
};
849
850
struct iked_socket {
851
  int      sock_fd;
852
  struct event     sock_ev;
853
  struct iked   *sock_env;
854
  struct sockaddr_storage  sock_addr;
855
};
856
857
struct ipsec_xf {
858
  const char  *name;
859
  unsigned int   id;
860
  unsigned int   length;
861
  unsigned int   keylength;
862
  unsigned int   nonce;
863
  unsigned int   noauth;
864
};
865
866
struct ipsec_transforms {
867
  const struct ipsec_xf **authxf;
868
  unsigned int      nauthxf;
869
  const struct ipsec_xf **prfxf;
870
  unsigned int      nprfxf;
871
  const struct ipsec_xf **encxf;
872
  unsigned int      nencxf;
873
  const struct ipsec_xf **groupxf;
874
  unsigned int      ngroupxf;
875
  const struct ipsec_xf **esnxf;
876
  unsigned int      nesnxf;
877
};
878
879
struct ipsec_mode {
880
  struct ipsec_transforms **xfs;
881
  unsigned int      nxfs;
882
};
883
884
/* iked.c */
885
void   parent_reload(struct iked *, int, const char *);
886
887
extern struct iked  *iked_env;
888
889
/* control.c */
890
void   control(struct privsep *, struct privsep_proc *);
891
int  control_init(struct privsep *, struct control_sock *);
892
int  control_listen(struct control_sock *);
893
894
/* config.c */
895
struct iked_policy *
896
   config_new_policy(struct iked *);
897
void   config_free_kex(struct iked_kex *);
898
void   config_free_fragments(struct iked_frag *);
899
void   config_free_sa(struct iked *, struct iked_sa *);
900
struct iked_sa *
901
   config_new_sa(struct iked *, int);
902
struct iked_user *
903
   config_new_user(struct iked *, struct iked_user *);
904
uint64_t
905
   config_getspi(void);
906
struct iked_transform *
907
   config_findtransform(struct iked_proposals *, uint8_t, unsigned int);
908
struct iked_transform *
909
   config_findtransform_ext(struct iked_proposals *, uint8_t,int, unsigned int);
910
void   config_free_policy(struct iked *, struct iked_policy *);
911
struct iked_proposal *
912
   config_add_proposal(struct iked_proposals *, unsigned int,
913
      unsigned int);
914
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
915
void   config_free_proposals(struct iked_proposals *, unsigned int);
916
void   config_free_flows(struct iked *, struct iked_flows *);
917
void   config_free_childsas(struct iked *, struct iked_childsas *,
918
      struct iked_spi *, struct iked_spi *);
919
int  config_add_transform(struct iked_proposal *,
920
      unsigned int, unsigned int, unsigned int, unsigned int);
921
int  config_setcoupled(struct iked *, unsigned int);
922
int  config_getcoupled(struct iked *, unsigned int);
923
int  config_setmode(struct iked *, unsigned int);
924
int  config_getmode(struct iked *, unsigned int);
925
int  config_setreset(struct iked *, unsigned int, enum privsep_procid);
926
int  config_getreset(struct iked *, struct imsg *);
927
int  config_doreset(struct iked *, unsigned int);
928
int  config_setpolicy(struct iked *, struct iked_policy *,
929
      enum privsep_procid);
930
int  config_getpolicy(struct iked *, struct imsg *);
931
int  config_setflow(struct iked *, struct iked_policy *,
932
      enum privsep_procid);
933
int  config_getflow(struct iked *, struct imsg *);
934
int  config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t,
935
      enum privsep_procid, int);
936
int  config_getsocket(struct iked *env, struct imsg *,
937
      void (*cb)(int, short, void *));
938
int  config_setpfkey(struct iked *);
939
int  config_getpfkey(struct iked *, struct imsg *);
940
int  config_setuser(struct iked *, struct iked_user *, enum privsep_procid);
941
int  config_getuser(struct iked *, struct imsg *);
942
int  config_setcompile(struct iked *, enum privsep_procid);
943
int  config_getcompile(struct iked *);
944
int  config_setocsp(struct iked *);
945
int  config_getocsp(struct iked *, struct imsg *);
946
int  config_setkeys(struct iked *);
947
int  config_getkey(struct iked *, struct imsg *);
948
int  config_setstatic(struct iked *);
949
int  config_getstatic(struct iked *, struct imsg *);
950
int  config_setcertpartialchain(struct iked *);
951
int  config_getcertpartialchain(struct iked *, struct imsg *);
952
953
/* policy.c */
954
void   policy_init(struct iked *);
955
int  policy_lookup(struct iked *, struct iked_message *,
956
      struct iked_proposals *, struct iked_flows *, int);
957
int  policy_lookup_sa(struct iked *, struct iked_sa *);
958
struct iked_policy *
959
   policy_test(struct iked *, struct iked_policy *);
960
int  policy_generate_ts(struct iked_policy *);
961
void   policy_calc_skip_steps(struct iked_policies *);
962
void   policy_ref(struct iked *, struct iked_policy *);
963
void   policy_unref(struct iked *, struct iked_policy *);
964
void   sa_state(struct iked *, struct iked_sa *, int);
965
void   sa_stateflags(struct iked_sa *, unsigned int);
966
int  sa_stateok(const struct iked_sa *, int);
967
struct iked_sa *
968
   sa_new(struct iked *, uint64_t, uint64_t, unsigned int,
969
      struct iked_policy *);
970
void   sa_free(struct iked *, struct iked_sa *);
971
void   sa_free_flows(struct iked *, struct iked_saflows *);
972
int  sa_configure_iface(struct iked *, struct iked_sa *, int);
973
int  sa_address(struct iked_sa *, struct iked_addr *, struct sockaddr *);
974
void   childsa_free(struct iked_childsa *);
975
struct iked_childsa *
976
   childsa_lookup(struct iked_sa *, uint64_t, uint8_t);
977
void   flow_free(struct iked_flow *);
978
int  flow_equal(struct iked_flow *, struct iked_flow *);
979
struct iked_sa *
980
   sa_lookup(struct iked *, uint64_t, uint64_t, unsigned int);
981
struct iked_user *
982
   user_lookup(struct iked *, const char *);
983
struct iked_sa *
984
   sa_dstid_lookup(struct iked *, struct iked_sa *);
985
struct iked_sa *
986
   sa_dstid_insert(struct iked *, struct iked_sa *);
987
void   sa_dstid_remove(struct iked *, struct iked_sa *);
988
int  proposals_negotiate(struct iked_proposals *, struct iked_proposals *,
989
      struct iked_proposals *, int, int);
990
RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
991
RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
992
RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
993
RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
994
RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
995
RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
996
RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
997
998
/* crypto.c */
999
struct iked_hash *
1000
   hash_new(uint8_t, uint16_t);
1001
struct ibuf *
1002
   hash_setkey(struct iked_hash *, void *, size_t);
1003
void   hash_free(struct iked_hash *);
1004
void   hash_init(struct iked_hash *);
1005
void   hash_update(struct iked_hash *, void *, size_t);
1006
void   hash_final(struct iked_hash *, void *, size_t *);
1007
size_t   hash_keylength(struct iked_hash *);
1008
size_t   hash_length(struct iked_hash *);
1009
1010
struct iked_cipher *
1011
   cipher_new(uint8_t, uint16_t, uint16_t);
1012
struct ibuf *
1013
   cipher_setkey(struct iked_cipher *, const void *, size_t);
1014
struct ibuf *
1015
   cipher_setiv(struct iked_cipher *, const void *, size_t);
1016
int  cipher_settag(struct iked_cipher *, uint8_t *, size_t);
1017
int  cipher_gettag(struct iked_cipher *, uint8_t *, size_t);
1018
void   cipher_free(struct iked_cipher *);
1019
int  cipher_init(struct iked_cipher *, int);
1020
int  cipher_init_encrypt(struct iked_cipher *);
1021
int  cipher_init_decrypt(struct iked_cipher *);
1022
void   cipher_aad(struct iked_cipher *, const void *, size_t, size_t *);
1023
int  cipher_update(struct iked_cipher *, const void *, size_t, void *, size_t *);
1024
int  cipher_final(struct iked_cipher *);
1025
size_t   cipher_length(struct iked_cipher *);
1026
size_t   cipher_keylength(struct iked_cipher *);
1027
size_t   cipher_ivlength(struct iked_cipher *);
1028
size_t   cipher_outlength(struct iked_cipher *, size_t);
1029
1030
struct iked_dsa *
1031
   dsa_new(uint8_t, struct iked_hash *, int);
1032
struct iked_dsa *
1033
   dsa_sign_new(uint8_t, struct iked_hash *);
1034
struct iked_dsa *
1035
   dsa_verify_new(uint8_t, struct iked_hash *);
1036
struct ibuf *
1037
   dsa_setkey(struct iked_dsa *, void *, size_t, uint8_t);
1038
void   dsa_free(struct iked_dsa *);
1039
int  dsa_init(struct iked_dsa *, const void *, size_t);
1040
size_t   dsa_prefix(struct iked_dsa *);
1041
size_t   dsa_length(struct iked_dsa *);
1042
int  dsa_update(struct iked_dsa *, const void *, size_t);
1043
ssize_t  dsa_sign_final(struct iked_dsa *, void *, size_t);
1044
ssize_t  dsa_verify_final(struct iked_dsa *, void *, size_t);
1045
1046
/* vroute.c */
1047
void vroute_init(struct iked *);
1048
int vroute_setaddr(struct iked *, int, struct sockaddr *, int, unsigned int);
1049
void vroute_cleanup(struct iked *);
1050
int vroute_getaddr(struct iked *, struct imsg *);
1051
int vroute_setdns(struct iked *, int, struct sockaddr *, unsigned int);
1052
int vroute_getdns(struct iked *, struct imsg *);
1053
int vroute_setaddroute(struct iked *, uint8_t, struct sockaddr *,
1054
    uint8_t, struct sockaddr *);
1055
int vroute_setcloneroute(struct iked *, uint8_t, struct sockaddr *,
1056
    uint8_t, struct sockaddr *);
1057
int vroute_setdelroute(struct iked *, uint8_t, struct sockaddr *,
1058
    uint8_t, struct sockaddr *);
1059
int vroute_getroute(struct iked *, struct imsg *);
1060
int vroute_getcloneroute(struct iked *, struct imsg *);
1061
1062
/* ikev2.c */
1063
void   ikev2(struct privsep *, struct privsep_proc *);
1064
void   ikev2_recv(struct iked *, struct iked_message *);
1065
void   ikev2_init_ike_sa(struct iked *, void *);
1066
int  ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
1067
int  ikev2_childsa_enable(struct iked *, struct iked_sa *);
1068
int  ikev2_childsa_delete(struct iked *, struct iked_sa *,
1069
      uint8_t, uint64_t, uint64_t *, int);
1070
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
1071
void   ikev2_ike_sa_timeout(struct iked *env, void *);
1072
void   ikev2_ike_sa_setreason(struct iked_sa *, char *);
1073
void   ikev2_reset_alive_timer(struct iked *);
1074
int  ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
1075
1076
struct ibuf *
1077
   ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
1078
      size_t);
1079
ssize_t  ikev2_psk(struct iked_sa *, uint8_t *, size_t, uint8_t **);
1080
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
1081
      void *, size_t, unsigned int, int);
1082
void   ikev2_enable_natt(struct iked *, struct iked_sa *,
1083
      struct iked_message *, int);
1084
int  ikev2_send_informational(struct iked *, struct iked_message *);
1085
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
1086
      uint8_t, uint8_t, int);
1087
struct ike_header *
1088
   ikev2_add_header(struct ibuf *, struct iked_sa *,
1089
      uint32_t, uint8_t, uint8_t, uint8_t);
1090
int  ikev2_set_header(struct ike_header *, size_t);
1091
struct ikev2_payload *
1092
   ikev2_add_payload(struct ibuf *);
1093
int  ikev2_next_payload(struct ikev2_payload *, size_t,
1094
      uint8_t);
1095
int  ikev2_child_sa_acquire(struct iked *, struct iked_flow *);
1096
int  ikev2_child_sa_drop(struct iked *, struct iked_spi *);
1097
int  ikev2_child_sa_rekey(struct iked *, struct iked_spi *);
1098
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
1099
int  ikev2_print_id(struct iked_id *, char *, size_t);
1100
int  ikev2_print_static_id(struct iked_static_id *, char *, size_t);
1101
1102
const char  *ikev2_ikesa_info(uint64_t, const char *msg);
1103
#define SPI_IH(hdr)      ikev2_ikesa_info(betoh64((hdr)->ike_ispi), NULL)
1104
7.69k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.69k
#define SPI_SA(sa, f)    SPI_SH(&(sa)->sa_hdr, (f))
1106
1107
/* ikev2_msg.c */
1108
void   ikev2_msg_cb(int, short, void *);
1109
struct ibuf *
1110
   ikev2_msg_init(struct iked *, struct iked_message *,
1111
      struct sockaddr_storage *, socklen_t,
1112
      struct sockaddr_storage *, socklen_t, int);
1113
struct iked_message *
1114
   ikev2_msg_copy(struct iked *, struct iked_message *);
1115
void   ikev2_msg_cleanup(struct iked *, struct iked_message *);
1116
uint32_t
1117
   ikev2_msg_id(struct iked *, struct iked_sa *);
1118
struct ibuf
1119
  *ikev2_msg_auth(struct iked *, struct iked_sa *, int);
1120
int  ikev2_msg_authsign(struct iked *, struct iked_sa *,
1121
      struct iked_auth *, struct ibuf *);
1122
int  ikev2_msg_authverify(struct iked *, struct iked_sa *,
1123
      struct iked_auth *, uint8_t *, size_t, struct ibuf *);
1124
int  ikev2_msg_valid_ike_sa(struct iked *, struct ike_header *,
1125
      struct iked_message *);
1126
int  ikev2_msg_send(struct iked *, struct iked_message *);
1127
int  ikev2_msg_send_encrypt(struct iked *, struct iked_sa *,
1128
      struct ibuf **, uint8_t, uint8_t, int);
1129
struct ibuf
1130
  *ikev2_msg_encrypt(struct iked *, struct iked_sa *, struct ibuf *,
1131
      struct ibuf *);
1132
struct ibuf *
1133
   ikev2_msg_decrypt(struct iked *, struct iked_sa *,
1134
      struct ibuf *, struct ibuf *);
1135
int  ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
1136
int  ikev2_msg_frompeer(struct iked_message *);
1137
struct iked_socket *
1138
   ikev2_msg_getsocket(struct iked *, int, int);
1139
int  ikev2_msg_enqueue(struct iked *, struct iked_msgqueue *,
1140
      struct iked_message *, int);
1141
int  ikev2_msg_retransmit_response(struct iked *, struct iked_sa *,
1142
      struct iked_message *, uint8_t);
1143
void   ikev2_msg_prevail(struct iked *, struct iked_msgqueue *,
1144
      struct iked_message *);
1145
void   ikev2_msg_dispose(struct iked *, struct iked_msgqueue *,
1146
      struct iked_msg_retransmit *);
1147
void   ikev2_msg_flushqueue(struct iked *, struct iked_msgqueue *);
1148
struct iked_msg_retransmit *
1149
   ikev2_msg_lookup(struct iked *, struct iked_msgqueue *,
1150
      struct iked_message *, uint8_t);
1151
1152
/* ikev2_pld.c */
1153
int  ikev2_pld_parse(struct iked *, struct ike_header *,
1154
      struct iked_message *, size_t);
1155
1156
/* eap.c */
1157
int  eap_parse(struct iked *, const struct iked_sa *, struct iked_message*,
1158
      void *, int);
1159
int  eap_success(struct iked *, struct iked_sa *, int);
1160
int  eap_identity_request(struct iked *, struct iked_sa *);
1161
int  eap_mschap_challenge(struct iked *, struct iked_sa *, int, int,
1162
      uint8_t *, size_t);
1163
int  eap_mschap_success(struct iked *, struct iked_sa *, int);
1164
int  eap_challenge_request(struct iked *, struct iked_sa *, int);
1165
1166
/* pfkey.c */
1167
int  pfkey_couple(struct iked *, struct iked_sas *, int);
1168
int  pfkey_flow_add(struct iked *, struct iked_flow *);
1169
int  pfkey_flow_delete(struct iked *, struct iked_flow *);
1170
int  pfkey_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1171
int  pfkey_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1172
int  pfkey_sa_update_addresses(struct iked *, struct iked_childsa *);
1173
int  pfkey_sa_delete(struct iked *, struct iked_childsa *);
1174
int  pfkey_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1175
int  pfkey_flush(struct iked *);
1176
int  pfkey_socket(struct iked *);
1177
void   pfkey_init(struct iked *, int fd);
1178
1179
/* ipsec.c */
1180
int  ipsec_couple(struct iked *, struct iked_sas *, int);
1181
int  ipsec_flow_add(struct iked *, struct iked_flow *);
1182
int  ipsec_flow_delete(struct iked *, struct iked_flow *);
1183
int  ipsec_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1184
int  ipsec_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1185
int  ipsec_sa_update_addresses(struct iked *, struct iked_childsa *);
1186
int  ipsec_sa_delete(struct iked *, struct iked_childsa *);
1187
int  ipsec_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1188
int  ipsec_sa_rpl(struct iked *, struct iked_childsa *, uint32_t *);
1189
int  ipsec_sa_lifetimes(struct iked *, struct iked_childsa *, struct iked_lifetime *,
1190
       struct iked_lifetime *, struct iked_lifetime *);
1191
int  ipsec_flush(struct iked *);
1192
int  ipsec_socket(struct iked *);
1193
void   ipsec_init(struct iked *, int fd);
1194
1195
/* ca.c */
1196
void   caproc(struct privsep *, struct privsep_proc *);
1197
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
1198
      uint8_t, uint8_t, uint8_t *, size_t, enum privsep_procid);
1199
int  ca_setcert(struct iked *, struct iked_sahdr *, struct iked_id *,
1200
      uint8_t, uint8_t *, size_t, enum privsep_procid);
1201
int  ca_setauth(struct iked *, struct iked_sa *,
1202
      struct ibuf *, enum privsep_procid);
1203
void   ca_getkey(struct privsep *, struct iked_id *, enum imsg_type);
1204
int  ca_certbundle_add(struct ibuf *, struct iked_id *);
1205
int  ca_privkey_serialize(EVP_PKEY *, struct iked_id *);
1206
int  ca_pubkey_serialize(EVP_PKEY *, struct iked_id *);
1207
void   ca_sslinit(void);
1208
void   ca_sslerror(const char *);
1209
char  *ca_asn1_name(uint8_t *, size_t);
1210
void  *ca_x509_name_parse(char *);
1211
void   ca_cert_info(const char *, X509 *);
1212
1213
/* timer.c */
1214
void   timer_set(struct iked *, struct iked_timer *,
1215
      void (*)(struct iked *, void *), void *);
1216
void   timer_add(struct iked *, struct iked_timer *, int);
1217
void   timer_del(struct iked *, struct iked_timer *);
1218
1219
/* proc.c */
1220
void   proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
1221
      int, char **, enum privsep_procid);
1222
void   proc_kill(struct privsep *);
1223
void   proc_connect(struct privsep *);
1224
void   proc_dispatch(int, short event, void *);
1225
void   proc_run(struct privsep *, struct privsep_proc *,
1226
      struct privsep_proc *, unsigned int,
1227
      void (*)(struct privsep *, struct privsep_proc *, void *), void *);
1228
void   imsg_event_add(struct imsgev *);
1229
int  imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
1230
      pid_t, int, void *, uint16_t);
1231
int  imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
1232
      pid_t, int, const struct iovec *, int);
1233
int  proc_compose_imsg(struct privsep *, enum privsep_procid, int,
1234
      uint16_t, uint32_t, int, void *, uint16_t);
1235
int  proc_compose(struct privsep *, enum privsep_procid,
1236
      uint16_t, void *, uint16_t);
1237
int  proc_composev_imsg(struct privsep *, enum privsep_procid, int,
1238
      uint16_t, uint32_t, int, const struct iovec *, int);
1239
int  proc_composev(struct privsep *, enum privsep_procid,
1240
      uint16_t, const struct iovec *, int);
1241
int  proc_forward_imsg(struct privsep *, struct imsg *,
1242
      enum privsep_procid, int);
1243
struct imsgbuf *
1244
   proc_ibuf(struct privsep *, enum privsep_procid, int);
1245
struct imsgev *
1246
   proc_iev(struct privsep *, enum privsep_procid, int);
1247
enum privsep_procid
1248
   proc_getid(struct privsep_proc *, unsigned int, const char *);
1249
int  proc_flush_imsg(struct privsep *, enum privsep_procid, int);
1250
1251
/* util.c */
1252
int  socket_af(struct sockaddr *, in_port_t);
1253
in_port_t
1254
   socket_getport(struct sockaddr *);
1255
int  socket_setport(struct sockaddr *, in_port_t);
1256
int  socket_getaddr(int, struct sockaddr_storage *);
1257
int  socket_bypass(int, struct sockaddr *);
1258
int  udp_bind(struct sockaddr *, in_port_t);
1259
ssize_t  sendtofrom(int, void *, size_t, int, struct sockaddr *,
1260
      socklen_t, struct sockaddr *, socklen_t);
1261
ssize_t  recvfromto(int, void *, size_t, int, struct sockaddr *,
1262
      socklen_t *, struct sockaddr *, socklen_t *);
1263
const char *
1264
   print_spi(uint64_t, int);
1265
const char *
1266
   print_map(unsigned int, struct iked_constmap *);
1267
void   lc_idtype(char *);
1268
void   print_hex(const uint8_t *, off_t, size_t);
1269
void   print_hexval(const uint8_t *, off_t, size_t);
1270
void   print_hexbuf(struct ibuf *);
1271
const char *
1272
   print_bits(unsigned short, unsigned char *);
1273
int  sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
1274
uint8_t mask2prefixlen(struct sockaddr *);
1275
uint8_t mask2prefixlen6(struct sockaddr *);
1276
struct in6_addr *
1277
   prefixlen2mask6(uint8_t, uint32_t *);
1278
uint32_t
1279
   prefixlen2mask(uint8_t);
1280
const char *
1281
   print_addr(void *);
1282
char  *get_string(uint8_t *, size_t);
1283
const char *
1284
   print_proto(uint8_t);
1285
int  expand_string(char *, size_t, const char *, const char *);
1286
uint8_t *string2unicode(const char *, size_t *);
1287
void   print_debug(const char *, ...)
1288
      __attribute__((format(printf, 1, 2)));
1289
void   print_verbose(const char *, ...)
1290
      __attribute__((format(printf, 1, 2)));
1291
1292
/* imsg_util.c */
1293
struct ibuf *
1294
   ibuf_new(const void *, size_t);
1295
struct ibuf *
1296
   ibuf_static(void);
1297
size_t   ibuf_length(struct ibuf *);
1298
int  ibuf_setsize(struct ibuf *, size_t);
1299
struct ibuf *
1300
   ibuf_getdata(struct ibuf *, size_t);
1301
struct ibuf *
1302
   ibuf_dup(struct ibuf *);
1303
struct ibuf *
1304
   ibuf_random(size_t);
1305
1306
/* log.c */
1307
void  log_init(int, int);
1308
void  log_procinit(const char *);
1309
void  log_setverbose(int);
1310
int log_getverbose(void);
1311
void  log_warn(const char *, ...)
1312
      __attribute__((__format__ (printf, 1, 2)));
1313
void  log_warnx(const char *, ...)
1314
      __attribute__((__format__ (printf, 1, 2)));
1315
void  log_info(const char *, ...)
1316
      __attribute__((__format__ (printf, 1, 2)));
1317
void  log_debug(const char *, ...)
1318
      __attribute__((__format__ (printf, 1, 2)));
1319
void  logit(int, const char *, ...)
1320
      __attribute__((__format__ (printf, 2, 3)));
1321
void  vlog(int, const char *, va_list)
1322
      __attribute__((__format__ (printf, 2, 0)));
1323
__dead void fatal(const char *, ...)
1324
      __attribute__((__format__ (printf, 1, 2)));
1325
__dead void fatalx(const char *, ...)
1326
      __attribute__((__format__ (printf, 1, 2)));
1327
1328
/* ocsp.c */
1329
int  ocsp_connect(struct iked *, struct imsg *);
1330
int  ocsp_receive_fd(struct iked *, struct imsg *);
1331
int  ocsp_validate_cert(struct iked *, void *, size_t, struct iked_sahdr,
1332
    uint8_t, X509 *);
1333
1334
/* parse.y */
1335
int  parse_config(const char *, struct iked *);
1336
int  cmdline_symset(char *);
1337
extern const struct ipsec_xf authxfs[];
1338
extern const struct ipsec_xf prfxfs[];
1339
extern const struct ipsec_xf *encxfs;
1340
extern const struct ipsec_xf ikeencxfs[];
1341
extern const struct ipsec_xf ipsecencxfs[];
1342
extern const struct ipsec_xf groupxfs[];
1343
extern const struct ipsec_xf esnxfs[];
1344
extern const struct ipsec_xf methodxfs[];
1345
extern const struct ipsec_xf saxfs[];
1346
extern const struct ipsec_xf cpxfs[];
1347
size_t   keylength_xf(unsigned int, unsigned int, unsigned int);
1348
size_t   noncelength_xf(unsigned int, unsigned int);
1349
int  encxf_noauth(unsigned int);
1350
1351
/* print.c */
1352
void   print_user(struct iked_user *);
1353
void   print_policy(struct iked_policy *);
1354
const char *print_xf(unsigned int, unsigned int, const struct ipsec_xf *);
1355
1356
#endif /* IKED_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/iked.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: iked.h,v 1.224 2023/08/11 11:24:55 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019-2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/tree.h>
22
#include <sys/queue.h>
23
#include <arpa/inet.h>
24
#include <limits.h>
25
#include <imsg.h>
26
27
#include <openssl/evp.h>
28
29
#include "openbsd-compat.h"
30
31
#include "types.h"
32
#include "dh.h"
33
34
#define MAXIMUM(a,b) (((a)>(b))?(a):(b))
35
#define MINIMUM(a,b) (((a)<(b))?(a):(b))
36
#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
37
38
#ifndef IKED_H
39
#define IKED_H
40
41
/*
42
 * Common IKEv1/IKEv2 header
43
 */
44
45
struct ike_header {
46
  uint64_t   ike_ispi;    /* Initiator cookie */
47
  uint64_t   ike_rspi;    /* Responder cookie */
48
  uint8_t    ike_nextpayload; /* Next payload type */
49
  uint8_t    ike_version;   /* Major/Minor version number */
50
  uint8_t    ike_exchange;    /* Exchange type */
51
  uint8_t    ike_flags;   /* Message options */
52
  uint32_t   ike_msgid;   /* Message identifier */
53
  uint32_t   ike_length;    /* Total message length */
54
} __packed;
55
56
/*
57
 * Common daemon infrastructure, local imsg etc.
58
 */
59
60
struct imsgev {
61
  struct imsgbuf     ibuf;
62
  void      (*handler)(int, short, void *);
63
  struct event     ev;
64
  struct privsep_proc *proc;
65
  void      *data;
66
  short      events;
67
  const char    *name;
68
};
69
70
#define IMSG_SIZE_CHECK(imsg, p) do {       \
71
  if (IMSG_DATA_SIZE(imsg) < sizeof(*p))      \
72
    fatalx("bad length imsg received");   \
73
} while (0)
74
#define IMSG_DATA_SIZE(imsg)  ((imsg)->hdr.len - IMSG_HEADER_SIZE)
75
76
#define IKED_ADDR_EQ(_a, _b)            \
77
  ((_a)->addr_mask == (_b)->addr_mask &&        \
78
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
79
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) == 0)
80
81
#define IKED_ADDR_NEQ(_a, _b)           \
82
  ((_a)->addr_mask != (_b)->addr_mask ||        \
83
  sockaddr_cmp((struct sockaddr *)&(_a)->addr,      \
84
  (struct sockaddr *)&(_b)->addr, (_a)->addr_mask) != 0)
85
86
/* initially control.h */
87
struct control_sock {
88
  const char  *cs_name;
89
  struct event   cs_ev;
90
  struct event   cs_evt;
91
  int    cs_fd;
92
  int    cs_restricted;
93
  void    *cs_env;
94
95
  TAILQ_ENTRY(control_sock) cs_entry;
96
};
97
TAILQ_HEAD(control_socks, control_sock);
98
99
struct ctl_conn {
100
  TAILQ_ENTRY(ctl_conn)  entry;
101
  uint8_t      flags;
102
#define CTL_CONN_NOTIFY    0x01
103
  struct imsgev    iev;
104
};
105
TAILQ_HEAD(ctl_connlist, ctl_conn);
106
107
extern enum privsep_procid privsep_process;
108
109
/*
110
 * Runtime structures
111
 */
112
113
struct iked_timer {
114
  struct event   tmr_ev;
115
  struct iked *tmr_env;
116
  void    (*tmr_cb)(struct iked *, void *);
117
  void    *tmr_cbarg;
118
};
119
120
struct iked_spi {
121
  uint64_t   spi;
122
  uint8_t    spi_size;
123
  uint8_t    spi_protoid;
124
};
125
126
struct iked_proposal {
127
  uint8_t        prop_id;
128
  uint8_t        prop_protoid;
129
130
  struct iked_spi      prop_localspi;
131
  struct iked_spi      prop_peerspi;
132
133
  struct iked_transform   *prop_xforms;
134
  unsigned int       prop_nxforms;
135
136
  TAILQ_ENTRY(iked_proposal)   prop_entry;
137
};
138
TAILQ_HEAD(iked_proposals, iked_proposal);
139
140
struct iked_addr {
141
  int        addr_af;
142
  struct sockaddr_storage    addr;
143
  uint8_t        addr_mask;
144
  int        addr_net;
145
  in_port_t      addr_port;
146
};
147
148
struct iked_ts {
149
  struct iked_addr     ts_addr;
150
  uint8_t        ts_ipproto;
151
  TAILQ_ENTRY(iked_ts)     ts_entry;
152
};
153
TAILQ_HEAD(iked_tss, iked_ts);
154
155
struct iked_flow {
156
  struct iked_addr     flow_src;
157
  struct iked_addr     flow_dst;
158
  unsigned int       flow_dir;  /* in/out */
159
  int        flow_rdomain;
160
  struct iked_addr     flow_prenat;
161
  int        flow_fixed;
162
163
  unsigned int       flow_loaded; /* pfkey done */
164
165
  uint8_t        flow_saproto;
166
  uint8_t        flow_ipproto;
167
168
  struct iked_addr    *flow_local;  /* outer source */
169
  struct iked_addr    *flow_peer; /* outer dest */
170
  struct iked_sa      *flow_ikesa;  /* parent SA */
171
172
  int        flow_transport;
173
174
  RB_ENTRY(iked_flow)    flow_node;
175
  TAILQ_ENTRY(iked_flow)     flow_entry;
176
};
177
RB_HEAD(iked_flows, iked_flow);
178
TAILQ_HEAD(iked_saflows, iked_flow);
179
180
struct iked_childsa {
181
  uint8_t        csa_saproto; /* IPsec protocol */
182
  unsigned int       csa_dir; /* in/out */
183
184
  uint64_t       csa_peerspi; /* peer relation */
185
  uint8_t        csa_loaded;  /* pfkey done */
186
  uint8_t        csa_rekey; /* will be deleted */
187
  uint8_t        csa_allocated; /* from the kernel */
188
  uint8_t        csa_persistent;/* do not rekey */
189
  uint8_t        csa_esn; /* use ESN */
190
  uint8_t        csa_transport; /* transport mode */
191
192
  struct iked_spi      csa_spi;
193
194
  struct ibuf     *csa_encrkey; /* encryption key */
195
  uint16_t       csa_encrid;  /* encryption xform id */
196
197
  struct ibuf     *csa_integrkey; /* auth key */
198
  uint16_t       csa_integrid;  /* auth xform id */
199
200
  struct iked_addr    *csa_local; /* outer source */
201
  struct iked_addr    *csa_peer;  /* outer dest */
202
  struct iked_sa      *csa_ikesa; /* parent SA */
203
204
  struct iked_childsa   *csa_peersa;  /* peer */
205
206
  struct iked_childsa   *csa_bundled; /* IPCOMP */
207
208
  uint16_t       csa_pfsgrpid;  /* pfs group id */
209
210
  RB_ENTRY(iked_childsa)     csa_node;
211
  TAILQ_ENTRY(iked_childsa)  csa_entry;
212
};
213
RB_HEAD(iked_activesas, iked_childsa);
214
TAILQ_HEAD(iked_childsas, iked_childsa);
215
216
217
struct iked_static_id {
218
  uint8_t   id_type;
219
  uint8_t   id_length;
220
  uint8_t   id_offset;
221
  uint8_t   id_data[IKED_ID_SIZE];
222
};
223
224
struct iked_auth {
225
  uint8_t   auth_method;
226
  uint8_t   auth_eap;     /* optional EAP */
227
  uint8_t   auth_length;      /* zero if EAP */
228
  uint8_t   auth_data[IKED_PSK_SIZE];
229
};
230
231
struct iked_cfg {
232
  uint8_t        cfg_action;
233
  uint16_t       cfg_type;
234
  union {
235
    struct iked_addr   address;
236
  } cfg;
237
};
238
239
TAILQ_HEAD(iked_sapeers, iked_sa);
240
241
struct iked_lifetime {
242
  uint64_t       lt_bytes;
243
  uint64_t       lt_seconds;
244
};
245
246
struct iked_policy {
247
  unsigned int       pol_id;
248
  char         pol_name[IKED_ID_SIZE];
249
  unsigned int       pol_iface;
250
251
#define IKED_SKIP_FLAGS      0
252
#define IKED_SKIP_AF       1
253
#define IKED_SKIP_SRC_ADDR     2
254
#define IKED_SKIP_DST_ADDR     3
255
#define IKED_SKIP_COUNT      4
256
  struct iked_policy    *pol_skip[IKED_SKIP_COUNT];
257
258
  uint8_t        pol_flags;
259
#define IKED_POLICY_PASSIVE    0x00
260
#define IKED_POLICY_DEFAULT    0x01
261
#define IKED_POLICY_ACTIVE     0x02
262
#define IKED_POLICY_REFCNT     0x04
263
#define IKED_POLICY_QUICK    0x08
264
#define IKED_POLICY_SKIP     0x10
265
#define IKED_POLICY_IPCOMP     0x20
266
0
#define IKED_POLICY_TRANSPORT    0x40
267
#define IKED_POLICY_ROUTING    0x80
268
269
  int        pol_refcnt;
270
271
  uint8_t        pol_certreqtype;
272
273
  int        pol_af;
274
  int        pol_rdomain;
275
  uint8_t        pol_saproto;
276
  unsigned int       pol_ipproto[IKED_IPPROTO_MAX];
277
  unsigned int       pol_nipproto;
278
279
  struct iked_addr     pol_peer;
280
  struct iked_static_id    pol_peerid;
281
  uint32_t       pol_peerdh;
282
283
  struct iked_addr     pol_local;
284
  struct iked_static_id    pol_localid;
285
286
  struct iked_auth     pol_auth;
287
288
  char         pol_tag[IKED_TAG_SIZE];
289
  unsigned int       pol_tap;
290
291
  struct iked_proposals    pol_proposals;
292
  size_t         pol_nproposals;
293
294
  struct iked_flows    pol_flows;
295
  size_t         pol_nflows;
296
  struct iked_tss      pol_tssrc; /* Traffic Selectors Initiator*/
297
  size_t         pol_tssrc_count;
298
  struct iked_tss      pol_tsdst; /* Traffic Selectors Responder*/
299
  size_t         pol_tsdst_count;
300
301
  struct iked_cfg      pol_cfg[IKED_CFG_MAX];
302
  unsigned int       pol_ncfg;
303
304
  uint32_t       pol_rekey; /* ike SA lifetime */
305
  struct iked_lifetime     pol_lifetime;  /* child SA lifetime */
306
307
  struct iked_sapeers    pol_sapeers;
308
309
  TAILQ_ENTRY(iked_policy)   pol_entry;
310
};
311
TAILQ_HEAD(iked_policies, iked_policy);
312
313
struct iked_hash {
314
  uint8_t    hash_type; /* PRF or INTEGR */
315
  uint16_t   hash_id; /* IKE PRF/INTEGR hash id */
316
  const void  *hash_priv; /* Identifying the hash alg */
317
  void    *hash_ctx;  /* Context of the current invocation */
318
  int    hash_fixedkey; /* Requires fixed key length */
319
  struct ibuf *hash_key;  /* MAC key derived from key seed */
320
  size_t     hash_length; /* Output length */
321
  size_t     hash_trunc;  /* Truncate the output length */
322
  struct iked_hash *hash_prf; /* PRF pointer */
323
  int    hash_isaead;
324
};
325
326
struct iked_cipher {
327
  uint8_t    encr_type; /* ENCR */
328
  uint16_t   encr_id; /* IKE ENCR hash id */
329
  const void  *encr_priv; /* Identifying the hash alg */
330
  void    *encr_ctx;  /* Context of the current invocation */
331
  int    encr_fixedkey; /* Requires fixed key length */
332
  struct ibuf *encr_key;  /* MAC key derived from key seed */
333
  struct ibuf *encr_iv; /* Initialization Vector */
334
  uint64_t   encr_civ;  /* Counter IV for GCM */
335
  size_t     encr_ivlength; /* IV length */
336
  size_t     encr_length; /* Block length */
337
  size_t     encr_saltlength; /* IV salt length */
338
  uint16_t   encr_authid; /* ID of associated authentication */
339
};
340
341
struct iked_dsa {
342
  uint8_t    dsa_method;  /* AUTH method */
343
  const void  *dsa_priv;  /* PRF or signature hash function */
344
  void    *dsa_ctx; /* PRF or signature hash ctx */
345
  struct ibuf *dsa_keydata; /* public, private or shared key */
346
  void    *dsa_key; /* parsed public or private key */
347
  int    dsa_hmac;  /* HMAC or public/private key */
348
  int    dsa_sign;  /* Sign or verify operation */
349
  uint32_t   dsa_flags; /* State flags */
350
};
351
352
struct iked_id {
353
  uint8_t    id_type;
354
  uint8_t    id_offset;
355
  struct ibuf *id_buf;
356
};
357
358
#define IKED_REQ_CERT   0x0001  /* get local certificate (if required) */
359
#define IKED_REQ_CERTVALID  0x0002  /* validated the peer cert */
360
#define IKED_REQ_CERTREQ  0x0004  /* CERTREQ has been received */
361
#define IKED_REQ_AUTH   0x0008  /* AUTH payload */
362
#define IKED_REQ_AUTHVALID  0x0010  /* AUTH payload has been verified */
363
#define IKED_REQ_SA   0x0020  /* SA available */
364
#define IKED_REQ_EAPVALID 0x0040  /* EAP payload has been verified */
365
#define IKED_REQ_CHILDSA  0x0080  /* Child SA initiated */
366
#define IKED_REQ_INF    0x0100  /* Informational exchange initiated */
367
368
#define IKED_REQ_BITS \
369
    "\20\01CERT\02CERTVALID\03CERTREQ\04AUTH\05AUTHVALID\06SA\07EAPVALID" \
370
    "\10CHILDSA\11INF"
371
372
TAILQ_HEAD(iked_msgqueue, iked_msg_retransmit);
373
TAILQ_HEAD(iked_msg_fragqueue, iked_message);
374
375
struct iked_sahdr {
376
  uint64_t       sh_ispi; /* Initiator SPI */
377
  uint64_t       sh_rspi; /* Responder SPI */
378
  unsigned int       sh_initiator;  /* Is initiator? */
379
} __packed;
380
381
struct iked_kex {
382
  struct ibuf     *kex_inonce;  /* Ni */
383
  struct ibuf     *kex_rnonce;  /* Nr */
384
385
  struct dh_group     *kex_dhgroup; /* DH group */
386
  struct ibuf     *kex_dhiexchange;
387
  struct ibuf     *kex_dhrexchange;
388
  struct ibuf     *kex_dhpeer;  /* pointer to i or r */
389
};
390
391
struct iked_frag_entry {
392
  uint8_t *frag_data;
393
  size_t   frag_size;
394
};
395
396
struct iked_frag {
397
  struct iked_frag_entry  **frag_arr; /* list of fragment buffers */
398
  size_t        frag_count; /* number of fragments received */
399
0
#define IKED_FRAG_TOTAL_MAX   111    /* upper limit (64kB / 576B) */
400
  size_t        frag_total; /* total numbe of fragments */
401
  size_t        frag_total_size;
402
  uint8_t       frag_nextpayload;
403
404
};
405
406
struct iked_ipcomp {
407
  uint16_t       ic_cpi_out;  /* outgoing CPI */
408
  uint16_t       ic_cpi_in; /* incoming CPI */
409
  uint8_t        ic_transform;  /* transform */
410
};
411
412
struct iked_sa {
413
  struct iked_sahdr    sa_hdr;
414
  uint32_t       sa_msgid;  /* Last request rcvd */
415
  int        sa_msgid_set;  /* msgid initialized */
416
  uint32_t       sa_msgid_current;  /* Current requested rcvd */
417
  uint32_t       sa_reqid;  /* Next request sent */
418
419
  int        sa_type;
420
#define IKED_SATYPE_LOOKUP     0    /* Used for lookup */
421
#define IKED_SATYPE_LOCAL    1    /* Local SA */
422
423
  struct iked_addr     sa_peer;
424
  struct iked_addr     sa_peer_loaded;/* MOBIKE */
425
  struct iked_addr     sa_local;
426
  int        sa_fd;
427
428
  struct iked_frag     sa_fragments;
429
430
  int        sa_natt; /* for IKE messages */
431
  int        sa_udpencap; /* for pfkey */
432
  int        sa_usekeepalive;/* NAT-T keepalive */
433
434
  int        sa_state;
435
  unsigned int       sa_stateflags;
436
  unsigned int       sa_stateinit;  /* SA_INIT */
437
  unsigned int       sa_statevalid; /* IKE_AUTH */
438
439
  int        sa_cp;   /* XXX */
440
  struct iked_addr    *sa_cp_addr;  /* requested address */
441
  struct iked_addr    *sa_cp_addr6; /* requested address */
442
  struct iked_addr    *sa_cp_dns; /* requested dns */
443
444
  struct iked_policy    *sa_policy;
445
  struct timeval       sa_timecreated;
446
  struct timeval       sa_timeused;
447
448
  char        *sa_tag;
449
  const char      *sa_reason; /* reason for close */
450
451
  struct iked_kex      sa_kex;
452
/* XXX compat defines until everything is converted */
453
#define sa_inonce   sa_kex.kex_inonce
454
#define sa_rnonce   sa_kex.kex_rnonce
455
#define sa_dhgroup    sa_kex.kex_dhgroup
456
#define sa_dhiexchange    sa_kex.kex_dhiexchange
457
#define sa_dhrexchange    sa_kex.kex_dhrexchange
458
#define sa_dhpeer   sa_kex.kex_dhpeer
459
460
  struct iked_hash    *sa_prf;  /* PRF alg */
461
  struct iked_hash    *sa_integr; /* integrity alg */
462
  struct iked_cipher    *sa_encr; /* encryption alg */
463
464
  struct ibuf     *sa_key_d;  /* SK_d */
465
  struct ibuf     *sa_key_iauth;  /* SK_ai */
466
  struct ibuf     *sa_key_rauth;  /* SK_ar */
467
  struct ibuf     *sa_key_iencr;  /* SK_ei */
468
  struct ibuf     *sa_key_rencr;  /* SK_er */
469
  struct ibuf     *sa_key_iprf; /* SK_pi */
470
  struct ibuf     *sa_key_rprf; /* SK_pr */
471
472
  struct ibuf     *sa_1stmsg; /* for initiator AUTH */
473
  struct ibuf     *sa_2ndmsg; /* for responder AUTH */
474
  struct iked_id       sa_localauth;  /* local AUTH message */
475
  struct iked_id       sa_peerauth; /* peer AUTH message */
476
  int        sa_sigsha2;  /* use SHA2 for signatures */
477
109k
#define IKED_SCERT_MAX  3 /* max # of supplemental cert payloads */
478
479
  struct iked_id       sa_iid;  /* initiator id */
480
  struct iked_id       sa_rid;  /* responder id */
481
  struct iked_id       sa_icert;  /* initiator cert */
482
  struct iked_id       sa_rcert;  /* responder cert */
483
  struct iked_id       sa_scert[IKED_SCERT_MAX]; /* supplemental certs */
484
#define IKESA_SRCID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_iid : &(x)->sa_rid)
485
#define IKESA_DSTID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_rid : &(x)->sa_iid)
486
487
  char        *sa_eapid;  /* EAP identity */
488
  struct iked_id       sa_eap;  /* EAP challenge */
489
  struct ibuf     *sa_eapmsk; /* EAK session key */
490
491
  struct iked_proposals    sa_proposals;  /* SA proposals */
492
  struct iked_childsas     sa_childsas; /* IPsec Child SAs */
493
  struct iked_saflows    sa_flows;  /* IPsec flows */
494
495
  struct iked_sa      *sa_nexti;  /* initiated IKE SA */
496
  struct iked_sa      *sa_previ;  /* matching back pointer */
497
  struct iked_sa      *sa_nextr;  /* simultaneous rekey */
498
  struct iked_sa      *sa_prevr;  /* matching back pointer */
499
  uint64_t       sa_rekeyspi; /* peerspi CSA rekey */
500
  struct ibuf     *sa_simult; /* simultaneous rekey */
501
502
  struct iked_ipcomp     sa_ipcompi;  /* IPcomp initator */
503
  struct iked_ipcomp     sa_ipcompr;  /* IPcomp responder */
504
505
  int        sa_mobike; /* MOBIKE */
506
  int        sa_frag; /* fragmentation */
507
508
  int        sa_use_transport_mode; /* peer requested */
509
  int        sa_used_transport_mode; /* we enabled */
510
511
  struct iked_timer    sa_timer;  /* SA timeouts */
512
#define IKED_IKE_SA_EXCHANGE_TIMEOUT   300    /* 5 minutes */
513
#define IKED_IKE_SA_REKEY_TIMEOUT  120    /* 2 minutes */
514
#define IKED_IKE_SA_DELETE_TIMEOUT   120    /* 2 minutes */
515
#define IKED_IKE_SA_ALIVE_TIMEOUT  60   /* 1 minute */
516
517
  struct iked_timer    sa_keepalive;  /* keepalive timer */
518
#define IKED_IKE_SA_KEEPALIVE_TIMEOUT  20
519
520
  struct iked_timer    sa_rekey;  /* rekey timeout */
521
  int        sa_tmpfail;
522
523
  struct iked_msgqueue     sa_requests; /* request queue */
524
#define IKED_RETRANSMIT_TIMEOUT    2    /* 2 seconds */
525
526
  struct iked_msgqueue     sa_responses;  /* response queue */
527
#define IKED_RESPONSE_TIMEOUT    120    /* 2 minutes */
528
529
  TAILQ_ENTRY(iked_sa)     sa_peer_entry;
530
  RB_ENTRY(iked_sa)    sa_entry;  /* all SAs */
531
532
  RB_ENTRY(iked_sa)    sa_dstid_entry;  /* SAs by DSTID */
533
  int        sa_dstid_entry_valid;    /* sa_dstid_entry valid */
534
535
  struct iked_addr    *sa_addrpool; /* address from pool */
536
  RB_ENTRY(iked_sa)    sa_addrpool_entry; /* pool entries */
537
538
  struct iked_addr    *sa_addrpool6;  /* address from pool */
539
  RB_ENTRY(iked_sa)    sa_addrpool6_entry;  /* pool entries */
540
  time_t         sa_last_recvd;
541
#define IKED_IKE_SA_LAST_RECVD_TIMEOUT   300    /* 5 minutes */
542
};
543
RB_HEAD(iked_sas, iked_sa);
544
RB_HEAD(iked_dstid_sas, iked_sa);
545
RB_HEAD(iked_addrpool, iked_sa);
546
RB_HEAD(iked_addrpool6, iked_sa);
547
548
/* stats */
549
550
struct iked_stats {
551
  uint64_t  ikes_sa_created;
552
  uint64_t  ikes_sa_established_total;
553
  uint64_t  ikes_sa_established_current;  /* gauge */
554
  uint64_t  ikes_sa_established_failures;
555
  uint64_t  ikes_sa_proposals_negotiate_failures;
556
  uint64_t  ikes_sa_rekeyed;
557
  uint64_t  ikes_sa_removed;
558
  uint64_t  ikes_csa_created;
559
  uint64_t  ikes_csa_removed;
560
  uint64_t  ikes_msg_sent;
561
  uint64_t  ikes_msg_send_failures;
562
  uint64_t  ikes_msg_rcvd;
563
  uint64_t  ikes_msg_rcvd_busy;
564
  uint64_t  ikes_msg_rcvd_dropped;
565
  uint64_t  ikes_retransmit_request;
566
  uint64_t  ikes_retransmit_response;
567
  uint64_t  ikes_retransmit_limit;
568
  uint64_t  ikes_frag_sent;
569
  uint64_t  ikes_frag_send_failures;
570
  uint64_t  ikes_frag_rcvd;
571
  uint64_t  ikes_frag_rcvd_drop;
572
  uint64_t  ikes_frag_reass_ok;
573
  uint64_t  ikes_frag_reass_drop;
574
  uint64_t  ikes_update_addresses_sent;
575
  uint64_t  ikes_dpd_sent;
576
  uint64_t  ikes_keepalive_sent;
577
};
578
579
0
#define ikestat_add(env, c, n)  do { env->sc_stats.c += (n); } while(0)
580
0
#define ikestat_inc(env, c) ikestat_add(env, c, 1)
581
#define ikestat_dec(env, c) ikestat_add(env, c, -1)
582
583
struct iked_certreq {
584
  struct ibuf     *cr_data;
585
  uint8_t        cr_type;
586
  SIMPLEQ_ENTRY(iked_certreq)  cr_entry;
587
};
588
SIMPLEQ_HEAD(iked_certreqs, iked_certreq);
589
590
#define EAP_STATE_IDENTITY    (1)
591
#define EAP_STATE_MSCHAPV2_CHALLENGE  (2)
592
#define EAP_STATE_MSCHAPV2_SUCCESS  (3)
593
#define EAP_STATE_SUCCESS   (4)
594
595
struct eap_msg {
596
  char    *eam_identity;
597
  char    *eam_user;
598
  int    eam_type;
599
  uint8_t    eam_id;
600
  uint8_t    eam_msrid;
601
  int    eam_success;
602
  int    eam_found;
603
  int    eam_response;
604
  uint8_t    eam_challenge[16];
605
  uint8_t    eam_ntresponse[24];
606
  uint32_t   eam_state;
607
};
608
609
struct iked_message {
610
  struct ibuf   *msg_data;
611
  size_t       msg_offset;
612
613
  struct sockaddr_storage  msg_local;
614
  socklen_t    msg_locallen;
615
616
  struct sockaddr_storage  msg_peer;
617
  socklen_t    msg_peerlen;
618
619
  struct iked_socket  *msg_sock;
620
621
  int      msg_fd;
622
  int      msg_response;
623
  int      msg_responded;
624
  int      msg_valid;
625
  int      msg_natt;
626
  int      msg_natt_rcvd;
627
  int      msg_nat_detected;
628
  int      msg_error;
629
  int      msg_e;
630
  struct iked_message *msg_parent;
631
632
  /* Associated policy and SA */
633
  struct iked_policy  *msg_policy;
634
  struct iked_sa    *msg_sa;
635
636
  uint32_t     msg_msgid;
637
  uint8_t      msg_exchange;
638
639
  /* Parsed information */
640
  struct iked_proposals  msg_proposals;
641
  struct iked_certreqs   msg_certreqs;
642
  struct iked_spi    msg_rekey;
643
  struct ibuf   *msg_nonce; /* dh NONCE */
644
  uint16_t     msg_dhgroup; /* dh group */
645
  struct ibuf   *msg_ke;  /* dh key exchange */
646
  struct iked_id     msg_auth;  /* AUTH payload */
647
  struct iked_id     msg_peerid;
648
  struct iked_id     msg_localid;
649
  struct iked_id     msg_cert;
650
  struct iked_id     msg_scert[IKED_SCERT_MAX]; /* supplemental certs */
651
  struct ibuf   *msg_cookie;
652
  uint16_t     msg_group;
653
  uint16_t     msg_cpi;
654
  uint8_t      msg_transform;
655
  uint16_t     msg_flags;
656
  struct eap_msg     msg_eap;
657
  size_t       msg_del_spisize;
658
  size_t       msg_del_cnt;
659
  struct ibuf   *msg_del_buf;
660
  int      msg_del_protoid;
661
  int      msg_cp;
662
  struct iked_addr  *msg_cp_addr; /* requested address */
663
  struct iked_addr  *msg_cp_addr6;  /* requested address */
664
  struct iked_addr  *msg_cp_dns;  /* requested dns */
665
666
  /* MOBIKE */
667
  int      msg_update_sa_addresses;
668
  struct ibuf   *msg_cookie2;
669
670
  /* Parse stack */
671
  struct iked_proposal  *msg_prop;
672
  uint16_t     msg_attrlength;
673
674
  /* Retransmit queue */
675
  TAILQ_ENTRY(iked_message)
676
         msg_entry;
677
};
678
679
struct iked_msg_retransmit {
680
  struct iked_msg_fragqueue       mrt_frags;
681
  TAILQ_ENTRY(iked_msg_retransmit)      mrt_entry;
682
  struct iked_timer         mrt_timer;
683
  int             mrt_tries;
684
#define IKED_RETRANSMIT_TRIES  5    /* try 5 times */
685
};
686
687
3.05k
#define IKED_MSG_NAT_SRC_IP       0x01
688
19.9k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
136
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
73
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
241
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
131
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
128
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
239
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
348
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
36
#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN   0x0400
701
702
703
struct iked_user {
704
  char       usr_name[LOGIN_NAME_MAX];
705
  char       usr_pass[IKED_PASSWORD_SIZE];
706
  RB_ENTRY(iked_user)  usr_entry;
707
};
708
RB_HEAD(iked_users, iked_user);
709
710
struct privsep_pipes {
711
  int       *pp_pipes[PROC_MAX];
712
};
713
714
struct privsep {
715
  struct privsep_pipes    *ps_pipes[PROC_MAX];
716
  struct privsep_pipes    *ps_pp;
717
718
  struct imsgev     *ps_ievs[PROC_MAX];
719
  const char      *ps_title[PROC_MAX];
720
  pid_t        ps_pid[PROC_MAX];
721
  struct passwd     *ps_pw;
722
  int        ps_noaction;
723
724
  struct control_sock    ps_csock;
725
  struct control_socks     ps_rcsocks;
726
727
  unsigned int       ps_instances[PROC_MAX];
728
  unsigned int       ps_ninstances;
729
  unsigned int       ps_instance;
730
731
  /* Event and signal handlers */
732
  struct event       ps_evsigint;
733
  struct event       ps_evsigterm;
734
  struct event       ps_evsigchld;
735
  struct event       ps_evsighup;
736
  struct event       ps_evsigpipe;
737
  struct event       ps_evsigusr1;
738
739
  struct iked     *ps_env;
740
};
741
742
struct privsep_proc {
743
  const char    *p_title;
744
  enum privsep_procid  p_id;
745
  int     (*p_cb)(int, struct privsep_proc *,
746
            struct imsg *);
747
  void      (*p_init)(struct privsep *,
748
            struct privsep_proc *);
749
  const char    *p_chroot;
750
  struct passwd   *p_pw;
751
  struct privsep    *p_ps;
752
  void      (*p_shutdown)(void);
753
};
754
755
struct privsep_fd {
756
  enum privsep_procid    pf_procid;
757
  unsigned int       pf_instance;
758
};
759
760
#define PROC_PARENT_SOCK_FILENO 3
761
#define PROC_MAX_INSTANCES      32
762
763
struct iked_ocsp_entry {
764
  TAILQ_ENTRY(iked_ocsp_entry) ioe_entry; /* next request */
765
  void      *ioe_ocsp;  /* private ocsp request data */
766
};
767
TAILQ_HEAD(iked_ocsp_requests, iked_ocsp_entry);
768
769
/*
770
 * Daemon configuration
771
 */
772
773
enum natt_mode {
774
  NATT_DEFAULT, /* send/recv with both :500 and NAT-T port */
775
  NATT_DISABLE, /* send/recv with only :500 */
776
  NATT_FORCE, /* send/recv with only NAT-T port */
777
};
778
779
struct iked_static {
780
  uint64_t     st_alive_timeout;
781
  int      st_enforcesingleikesa;
782
  uint8_t      st_frag; /* fragmentation */
783
  uint8_t      st_mobike; /* MOBIKE */
784
  in_port_t    st_nattport;
785
  int      st_stickyaddress; /* addr per DSTID  */
786
  int      st_vendorid;
787
};
788
789
struct iked {
790
  char         sc_conffile[PATH_MAX];
791
792
  uint32_t       sc_opts;
793
  enum natt_mode       sc_nattmode;
794
  uint8_t        sc_passive;
795
  uint8_t        sc_decoupled;
796
797
  struct iked_static     sc_static;
798
799
#define sc_alive_timeout  sc_static.st_alive_timeout
800
#define sc_enforcesingleikesa sc_static.st_enforcesingleikesa
801
#define sc_frag     sc_static.st_frag
802
#define sc_mobike   sc_static.st_mobike
803
#define sc_nattport   sc_static.st_nattport
804
#define sc_stickyaddress  sc_static.st_stickyaddress
805
#define sc_vendorid   sc_static.st_vendorid
806
807
  struct iked_policies     sc_policies;
808
  struct iked_policy    *sc_defaultcon;
809
810
  struct iked_sas      sc_sas;
811
  struct iked_dstid_sas    sc_dstid_sas;
812
  struct iked_activesas    sc_activesas;
813
  struct iked_flows    sc_activeflows;
814
  struct iked_users    sc_users;
815
816
  struct iked_stats    sc_stats;
817
818
  void        *sc_priv; /* per-process */
819
820
  int        sc_pfkey;  /* ike process */
821
  struct event       sc_pfkeyev;
822
  struct event       sc_routeev;
823
  uint8_t        sc_certreqtype;
824
  struct ibuf     *sc_certreq;
825
  void        *sc_vroute;
826
827
  struct iked_socket    *sc_sock4[2];
828
  struct iked_socket    *sc_sock6[2];
829
830
  struct iked_timer    sc_inittmr;
831
#define IKED_INITIATOR_INITIAL     2
832
#define IKED_INITIATOR_INTERVAL    60
833
834
  struct privsep       sc_ps;
835
836
  struct iked_ocsp_requests  sc_ocsp;
837
  char        *sc_ocsp_url;
838
  long         sc_ocsp_tolerate;
839
  long         sc_ocsp_maxage;
840
841
  struct iked_addrpool     sc_addrpool;
842
  struct iked_addrpool6    sc_addrpool6;
843
844
  int        sc_cert_partial_chain;
845
#ifdef WITH_APPARMOR
846
  int        sc_apparmor;
847
#endif
848
};
849
850
struct iked_socket {
851
  int      sock_fd;
852
  struct event     sock_ev;
853
  struct iked   *sock_env;
854
  struct sockaddr_storage  sock_addr;
855
};
856
857
struct ipsec_xf {
858
  const char  *name;
859
  unsigned int   id;
860
  unsigned int   length;
861
  unsigned int   keylength;
862
  unsigned int   nonce;
863
  unsigned int   noauth;
864
};
865
866
struct ipsec_transforms {
867
  const struct ipsec_xf **authxf;
868
  unsigned int      nauthxf;
869
  const struct ipsec_xf **prfxf;
870
  unsigned int      nprfxf;
871
  const struct ipsec_xf **encxf;
872
  unsigned int      nencxf;
873
  const struct ipsec_xf **groupxf;
874
  unsigned int      ngroupxf;
875
  const struct ipsec_xf **esnxf;
876
  unsigned int      nesnxf;
877
};
878
879
struct ipsec_mode {
880
  struct ipsec_transforms **xfs;
881
  unsigned int      nxfs;
882
};
883
884
/* iked.c */
885
void   parent_reload(struct iked *, int, const char *);
886
887
extern struct iked  *iked_env;
888
889
/* control.c */
890
void   control(struct privsep *, struct privsep_proc *);
891
int  control_init(struct privsep *, struct control_sock *);
892
int  control_listen(struct control_sock *);
893
894
/* config.c */
895
struct iked_policy *
896
   config_new_policy(struct iked *);
897
void   config_free_kex(struct iked_kex *);
898
void   config_free_fragments(struct iked_frag *);
899
void   config_free_sa(struct iked *, struct iked_sa *);
900
struct iked_sa *
901
   config_new_sa(struct iked *, int);
902
struct iked_user *
903
   config_new_user(struct iked *, struct iked_user *);
904
uint64_t
905
   config_getspi(void);
906
struct iked_transform *
907
   config_findtransform(struct iked_proposals *, uint8_t, unsigned int);
908
struct iked_transform *
909
   config_findtransform_ext(struct iked_proposals *, uint8_t,int, unsigned int);
910
void   config_free_policy(struct iked *, struct iked_policy *);
911
struct iked_proposal *
912
   config_add_proposal(struct iked_proposals *, unsigned int,
913
      unsigned int);
914
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
915
void   config_free_proposals(struct iked_proposals *, unsigned int);
916
void   config_free_flows(struct iked *, struct iked_flows *);
917
void   config_free_childsas(struct iked *, struct iked_childsas *,
918
      struct iked_spi *, struct iked_spi *);
919
int  config_add_transform(struct iked_proposal *,
920
      unsigned int, unsigned int, unsigned int, unsigned int);
921
int  config_setcoupled(struct iked *, unsigned int);
922
int  config_getcoupled(struct iked *, unsigned int);
923
int  config_setmode(struct iked *, unsigned int);
924
int  config_getmode(struct iked *, unsigned int);
925
int  config_setreset(struct iked *, unsigned int, enum privsep_procid);
926
int  config_getreset(struct iked *, struct imsg *);
927
int  config_doreset(struct iked *, unsigned int);
928
int  config_setpolicy(struct iked *, struct iked_policy *,
929
      enum privsep_procid);
930
int  config_getpolicy(struct iked *, struct imsg *);
931
int  config_setflow(struct iked *, struct iked_policy *,
932
      enum privsep_procid);
933
int  config_getflow(struct iked *, struct imsg *);
934
int  config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t,
935
      enum privsep_procid, int);
936
int  config_getsocket(struct iked *env, struct imsg *,
937
      void (*cb)(int, short, void *));
938
int  config_setpfkey(struct iked *);
939
int  config_getpfkey(struct iked *, struct imsg *);
940
int  config_setuser(struct iked *, struct iked_user *, enum privsep_procid);
941
int  config_getuser(struct iked *, struct imsg *);
942
int  config_setcompile(struct iked *, enum privsep_procid);
943
int  config_getcompile(struct iked *);
944
int  config_setocsp(struct iked *);
945
int  config_getocsp(struct iked *, struct imsg *);
946
int  config_setkeys(struct iked *);
947
int  config_getkey(struct iked *, struct imsg *);
948
int  config_setstatic(struct iked *);
949
int  config_getstatic(struct iked *, struct imsg *);
950
int  config_setcertpartialchain(struct iked *);
951
int  config_getcertpartialchain(struct iked *, struct imsg *);
952
953
/* policy.c */
954
void   policy_init(struct iked *);
955
int  policy_lookup(struct iked *, struct iked_message *,
956
      struct iked_proposals *, struct iked_flows *, int);
957
int  policy_lookup_sa(struct iked *, struct iked_sa *);
958
struct iked_policy *
959
   policy_test(struct iked *, struct iked_policy *);
960
int  policy_generate_ts(struct iked_policy *);
961
void   policy_calc_skip_steps(struct iked_policies *);
962
void   policy_ref(struct iked *, struct iked_policy *);
963
void   policy_unref(struct iked *, struct iked_policy *);
964
void   sa_state(struct iked *, struct iked_sa *, int);
965
void   sa_stateflags(struct iked_sa *, unsigned int);
966
int  sa_stateok(const struct iked_sa *, int);
967
struct iked_sa *
968
   sa_new(struct iked *, uint64_t, uint64_t, unsigned int,
969
      struct iked_policy *);
970
void   sa_free(struct iked *, struct iked_sa *);
971
void   sa_free_flows(struct iked *, struct iked_saflows *);
972
int  sa_configure_iface(struct iked *, struct iked_sa *, int);
973
int  sa_address(struct iked_sa *, struct iked_addr *, struct sockaddr *);
974
void   childsa_free(struct iked_childsa *);
975
struct iked_childsa *
976
   childsa_lookup(struct iked_sa *, uint64_t, uint8_t);
977
void   flow_free(struct iked_flow *);
978
int  flow_equal(struct iked_flow *, struct iked_flow *);
979
struct iked_sa *
980
   sa_lookup(struct iked *, uint64_t, uint64_t, unsigned int);
981
struct iked_user *
982
   user_lookup(struct iked *, const char *);
983
struct iked_sa *
984
   sa_dstid_lookup(struct iked *, struct iked_sa *);
985
struct iked_sa *
986
   sa_dstid_insert(struct iked *, struct iked_sa *);
987
void   sa_dstid_remove(struct iked *, struct iked_sa *);
988
int  proposals_negotiate(struct iked_proposals *, struct iked_proposals *,
989
      struct iked_proposals *, int, int);
990
RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
991
RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
992
RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
993
RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
994
RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
995
RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
996
RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
997
998
/* crypto.c */
999
struct iked_hash *
1000
   hash_new(uint8_t, uint16_t);
1001
struct ibuf *
1002
   hash_setkey(struct iked_hash *, void *, size_t);
1003
void   hash_free(struct iked_hash *);
1004
void   hash_init(struct iked_hash *);
1005
void   hash_update(struct iked_hash *, void *, size_t);
1006
void   hash_final(struct iked_hash *, void *, size_t *);
1007
size_t   hash_keylength(struct iked_hash *);
1008
size_t   hash_length(struct iked_hash *);
1009
1010
struct iked_cipher *
1011
   cipher_new(uint8_t, uint16_t, uint16_t);
1012
struct ibuf *
1013
   cipher_setkey(struct iked_cipher *, const void *, size_t);
1014
struct ibuf *
1015
   cipher_setiv(struct iked_cipher *, const void *, size_t);
1016
int  cipher_settag(struct iked_cipher *, uint8_t *, size_t);
1017
int  cipher_gettag(struct iked_cipher *, uint8_t *, size_t);
1018
void   cipher_free(struct iked_cipher *);
1019
int  cipher_init(struct iked_cipher *, int);
1020
int  cipher_init_encrypt(struct iked_cipher *);
1021
int  cipher_init_decrypt(struct iked_cipher *);
1022
void   cipher_aad(struct iked_cipher *, const void *, size_t, size_t *);
1023
int  cipher_update(struct iked_cipher *, const void *, size_t, void *, size_t *);
1024
int  cipher_final(struct iked_cipher *);
1025
size_t   cipher_length(struct iked_cipher *);
1026
size_t   cipher_keylength(struct iked_cipher *);
1027
size_t   cipher_ivlength(struct iked_cipher *);
1028
size_t   cipher_outlength(struct iked_cipher *, size_t);
1029
1030
struct iked_dsa *
1031
   dsa_new(uint8_t, struct iked_hash *, int);
1032
struct iked_dsa *
1033
   dsa_sign_new(uint8_t, struct iked_hash *);
1034
struct iked_dsa *
1035
   dsa_verify_new(uint8_t, struct iked_hash *);
1036
struct ibuf *
1037
   dsa_setkey(struct iked_dsa *, void *, size_t, uint8_t);
1038
void   dsa_free(struct iked_dsa *);
1039
int  dsa_init(struct iked_dsa *, const void *, size_t);
1040
size_t   dsa_prefix(struct iked_dsa *);
1041
size_t   dsa_length(struct iked_dsa *);
1042
int  dsa_update(struct iked_dsa *, const void *, size_t);
1043
ssize_t  dsa_sign_final(struct iked_dsa *, void *, size_t);
1044
ssize_t  dsa_verify_final(struct iked_dsa *, void *, size_t);
1045
1046
/* vroute.c */
1047
void vroute_init(struct iked *);
1048
int vroute_setaddr(struct iked *, int, struct sockaddr *, int, unsigned int);
1049
void vroute_cleanup(struct iked *);
1050
int vroute_getaddr(struct iked *, struct imsg *);
1051
int vroute_setdns(struct iked *, int, struct sockaddr *, unsigned int);
1052
int vroute_getdns(struct iked *, struct imsg *);
1053
int vroute_setaddroute(struct iked *, uint8_t, struct sockaddr *,
1054
    uint8_t, struct sockaddr *);
1055
int vroute_setcloneroute(struct iked *, uint8_t, struct sockaddr *,
1056
    uint8_t, struct sockaddr *);
1057
int vroute_setdelroute(struct iked *, uint8_t, struct sockaddr *,
1058
    uint8_t, struct sockaddr *);
1059
int vroute_getroute(struct iked *, struct imsg *);
1060
int vroute_getcloneroute(struct iked *, struct imsg *);
1061
1062
/* ikev2.c */
1063
void   ikev2(struct privsep *, struct privsep_proc *);
1064
void   ikev2_recv(struct iked *, struct iked_message *);
1065
void   ikev2_init_ike_sa(struct iked *, void *);
1066
int  ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
1067
int  ikev2_childsa_enable(struct iked *, struct iked_sa *);
1068
int  ikev2_childsa_delete(struct iked *, struct iked_sa *,
1069
      uint8_t, uint64_t, uint64_t *, int);
1070
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
1071
void   ikev2_ike_sa_timeout(struct iked *env, void *);
1072
void   ikev2_ike_sa_setreason(struct iked_sa *, char *);
1073
void   ikev2_reset_alive_timer(struct iked *);
1074
int  ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
1075
1076
struct ibuf *
1077
   ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
1078
      size_t);
1079
ssize_t  ikev2_psk(struct iked_sa *, uint8_t *, size_t, uint8_t **);
1080
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
1081
      void *, size_t, unsigned int, int);
1082
void   ikev2_enable_natt(struct iked *, struct iked_sa *,
1083
      struct iked_message *, int);
1084
int  ikev2_send_informational(struct iked *, struct iked_message *);
1085
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
1086
      uint8_t, uint8_t, int);
1087
struct ike_header *
1088
   ikev2_add_header(struct ibuf *, struct iked_sa *,
1089
      uint32_t, uint8_t, uint8_t, uint8_t);
1090
int  ikev2_set_header(struct ike_header *, size_t);
1091
struct ikev2_payload *
1092
   ikev2_add_payload(struct ibuf *);
1093
int  ikev2_next_payload(struct ikev2_payload *, size_t,
1094
      uint8_t);
1095
int  ikev2_child_sa_acquire(struct iked *, struct iked_flow *);
1096
int  ikev2_child_sa_drop(struct iked *, struct iked_spi *);
1097
int  ikev2_child_sa_rekey(struct iked *, struct iked_spi *);
1098
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
1099
int  ikev2_print_id(struct iked_id *, char *, size_t);
1100
int  ikev2_print_static_id(struct iked_static_id *, char *, size_t);
1101
1102
const char  *ikev2_ikesa_info(uint64_t, const char *msg);
1103
#define SPI_IH(hdr)      ikev2_ikesa_info(betoh64((hdr)->ike_ispi), NULL)
1104
7.69k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.69k
#define SPI_SA(sa, f)    SPI_SH(&(sa)->sa_hdr, (f))
1106
1107
/* ikev2_msg.c */
1108
void   ikev2_msg_cb(int, short, void *);
1109
struct ibuf *
1110
   ikev2_msg_init(struct iked *, struct iked_message *,
1111
      struct sockaddr_storage *, socklen_t,
1112
      struct sockaddr_storage *, socklen_t, int);
1113
struct iked_message *
1114
   ikev2_msg_copy(struct iked *, struct iked_message *);
1115
void   ikev2_msg_cleanup(struct iked *, struct iked_message *);
1116
uint32_t
1117
   ikev2_msg_id(struct iked *, struct iked_sa *);
1118
struct ibuf
1119
  *ikev2_msg_auth(struct iked *, struct iked_sa *, int);
1120
int  ikev2_msg_authsign(struct iked *, struct iked_sa *,
1121
      struct iked_auth *, struct ibuf *);
1122
int  ikev2_msg_authverify(struct iked *, struct iked_sa *,
1123
      struct iked_auth *, uint8_t *, size_t, struct ibuf *);
1124
int  ikev2_msg_valid_ike_sa(struct iked *, struct ike_header *,
1125
      struct iked_message *);
1126
int  ikev2_msg_send(struct iked *, struct iked_message *);
1127
int  ikev2_msg_send_encrypt(struct iked *, struct iked_sa *,
1128
      struct ibuf **, uint8_t, uint8_t, int);
1129
struct ibuf
1130
  *ikev2_msg_encrypt(struct iked *, struct iked_sa *, struct ibuf *,
1131
      struct ibuf *);
1132
struct ibuf *
1133
   ikev2_msg_decrypt(struct iked *, struct iked_sa *,
1134
      struct ibuf *, struct ibuf *);
1135
int  ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
1136
int  ikev2_msg_frompeer(struct iked_message *);
1137
struct iked_socket *
1138
   ikev2_msg_getsocket(struct iked *, int, int);
1139
int  ikev2_msg_enqueue(struct iked *, struct iked_msgqueue *,
1140
      struct iked_message *, int);
1141
int  ikev2_msg_retransmit_response(struct iked *, struct iked_sa *,
1142
      struct iked_message *, uint8_t);
1143
void   ikev2_msg_prevail(struct iked *, struct iked_msgqueue *,
1144
      struct iked_message *);
1145
void   ikev2_msg_dispose(struct iked *, struct iked_msgqueue *,
1146
      struct iked_msg_retransmit *);
1147
void   ikev2_msg_flushqueue(struct iked *, struct iked_msgqueue *);
1148
struct iked_msg_retransmit *
1149
   ikev2_msg_lookup(struct iked *, struct iked_msgqueue *,
1150
      struct iked_message *, uint8_t);
1151
1152
/* ikev2_pld.c */
1153
int  ikev2_pld_parse(struct iked *, struct ike_header *,
1154
      struct iked_message *, size_t);
1155
1156
/* eap.c */
1157
int  eap_parse(struct iked *, const struct iked_sa *, struct iked_message*,
1158
      void *, int);
1159
int  eap_success(struct iked *, struct iked_sa *, int);
1160
int  eap_identity_request(struct iked *, struct iked_sa *);
1161
int  eap_mschap_challenge(struct iked *, struct iked_sa *, int, int,
1162
      uint8_t *, size_t);
1163
int  eap_mschap_success(struct iked *, struct iked_sa *, int);
1164
int  eap_challenge_request(struct iked *, struct iked_sa *, int);
1165
1166
/* pfkey.c */
1167
int  pfkey_couple(struct iked *, struct iked_sas *, int);
1168
int  pfkey_flow_add(struct iked *, struct iked_flow *);
1169
int  pfkey_flow_delete(struct iked *, struct iked_flow *);
1170
int  pfkey_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1171
int  pfkey_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1172
int  pfkey_sa_update_addresses(struct iked *, struct iked_childsa *);
1173
int  pfkey_sa_delete(struct iked *, struct iked_childsa *);
1174
int  pfkey_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1175
int  pfkey_flush(struct iked *);
1176
int  pfkey_socket(struct iked *);
1177
void   pfkey_init(struct iked *, int fd);
1178
1179
/* ipsec.c */
1180
int  ipsec_couple(struct iked *, struct iked_sas *, int);
1181
int  ipsec_flow_add(struct iked *, struct iked_flow *);
1182
int  ipsec_flow_delete(struct iked *, struct iked_flow *);
1183
int  ipsec_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
1184
int  ipsec_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
1185
int  ipsec_sa_update_addresses(struct iked *, struct iked_childsa *);
1186
int  ipsec_sa_delete(struct iked *, struct iked_childsa *);
1187
int  ipsec_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
1188
int  ipsec_sa_rpl(struct iked *, struct iked_childsa *, uint32_t *);
1189
int  ipsec_sa_lifetimes(struct iked *, struct iked_childsa *, struct iked_lifetime *,
1190
       struct iked_lifetime *, struct iked_lifetime *);
1191
int  ipsec_flush(struct iked *);
1192
int  ipsec_socket(struct iked *);
1193
void   ipsec_init(struct iked *, int fd);
1194
1195
/* ca.c */
1196
void   caproc(struct privsep *, struct privsep_proc *);
1197
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
1198
      uint8_t, uint8_t, uint8_t *, size_t, enum privsep_procid);
1199
int  ca_setcert(struct iked *, struct iked_sahdr *, struct iked_id *,
1200
      uint8_t, uint8_t *, size_t, enum privsep_procid);
1201
int  ca_setauth(struct iked *, struct iked_sa *,
1202
      struct ibuf *, enum privsep_procid);
1203
void   ca_getkey(struct privsep *, struct iked_id *, enum imsg_type);
1204
int  ca_certbundle_add(struct ibuf *, struct iked_id *);
1205
int  ca_privkey_serialize(EVP_PKEY *, struct iked_id *);
1206
int  ca_pubkey_serialize(EVP_PKEY *, struct iked_id *);
1207
void   ca_sslinit(void);
1208
void   ca_sslerror(const char *);
1209
char  *ca_asn1_name(uint8_t *, size_t);
1210
void  *ca_x509_name_parse(char *);
1211
void   ca_cert_info(const char *, X509 *);
1212
1213
/* timer.c */
1214
void   timer_set(struct iked *, struct iked_timer *,
1215
      void (*)(struct iked *, void *), void *);
1216
void   timer_add(struct iked *, struct iked_timer *, int);
1217
void   timer_del(struct iked *, struct iked_timer *);
1218
1219
/* proc.c */
1220
void   proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
1221
      int, char **, enum privsep_procid);
1222
void   proc_kill(struct privsep *);
1223
void   proc_connect(struct privsep *);
1224
void   proc_dispatch(int, short event, void *);
1225
void   proc_run(struct privsep *, struct privsep_proc *,
1226
      struct privsep_proc *, unsigned int,
1227
      void (*)(struct privsep *, struct privsep_proc *, void *), void *);
1228
void   imsg_event_add(struct imsgev *);
1229
int  imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
1230
      pid_t, int, void *, uint16_t);
1231
int  imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
1232
      pid_t, int, const struct iovec *, int);
1233
int  proc_compose_imsg(struct privsep *, enum privsep_procid, int,
1234
      uint16_t, uint32_t, int, void *, uint16_t);
1235
int  proc_compose(struct privsep *, enum privsep_procid,
1236
      uint16_t, void *, uint16_t);
1237
int  proc_composev_imsg(struct privsep *, enum privsep_procid, int,
1238
      uint16_t, uint32_t, int, const struct iovec *, int);
1239
int  proc_composev(struct privsep *, enum privsep_procid,
1240
      uint16_t, const struct iovec *, int);
1241
int  proc_forward_imsg(struct privsep *, struct imsg *,
1242
      enum privsep_procid, int);
1243
struct imsgbuf *
1244
   proc_ibuf(struct privsep *, enum privsep_procid, int);
1245
struct imsgev *
1246
   proc_iev(struct privsep *, enum privsep_procid, int);
1247
enum privsep_procid
1248
   proc_getid(struct privsep_proc *, unsigned int, const char *);
1249
int  proc_flush_imsg(struct privsep *, enum privsep_procid, int);
1250
1251
/* util.c */
1252
int  socket_af(struct sockaddr *, in_port_t);
1253
in_port_t
1254
   socket_getport(struct sockaddr *);
1255
int  socket_setport(struct sockaddr *, in_port_t);
1256
int  socket_getaddr(int, struct sockaddr_storage *);
1257
int  socket_bypass(int, struct sockaddr *);
1258
int  udp_bind(struct sockaddr *, in_port_t);
1259
ssize_t  sendtofrom(int, void *, size_t, int, struct sockaddr *,
1260
      socklen_t, struct sockaddr *, socklen_t);
1261
ssize_t  recvfromto(int, void *, size_t, int, struct sockaddr *,
1262
      socklen_t *, struct sockaddr *, socklen_t *);
1263
const char *
1264
   print_spi(uint64_t, int);
1265
const char *
1266
   print_map(unsigned int, struct iked_constmap *);
1267
void   lc_idtype(char *);
1268
void   print_hex(const uint8_t *, off_t, size_t);
1269
void   print_hexval(const uint8_t *, off_t, size_t);
1270
void   print_hexbuf(struct ibuf *);
1271
const char *
1272
   print_bits(unsigned short, unsigned char *);
1273
int  sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
1274
uint8_t mask2prefixlen(struct sockaddr *);
1275
uint8_t mask2prefixlen6(struct sockaddr *);
1276
struct in6_addr *
1277
   prefixlen2mask6(uint8_t, uint32_t *);
1278
uint32_t
1279
   prefixlen2mask(uint8_t);
1280
const char *
1281
   print_addr(void *);
1282
char  *get_string(uint8_t *, size_t);
1283
const char *
1284
   print_proto(uint8_t);
1285
int  expand_string(char *, size_t, const char *, const char *);
1286
uint8_t *string2unicode(const char *, size_t *);
1287
void   print_debug(const char *, ...)
1288
      __attribute__((format(printf, 1, 2)));
1289
void   print_verbose(const char *, ...)
1290
      __attribute__((format(printf, 1, 2)));
1291
1292
/* imsg_util.c */
1293
struct ibuf *
1294
   ibuf_new(const void *, size_t);
1295
struct ibuf *
1296
   ibuf_static(void);
1297
size_t   ibuf_length(struct ibuf *);
1298
int  ibuf_setsize(struct ibuf *, size_t);
1299
struct ibuf *
1300
   ibuf_getdata(struct ibuf *, size_t);
1301
struct ibuf *
1302
   ibuf_dup(struct ibuf *);
1303
struct ibuf *
1304
   ibuf_random(size_t);
1305
1306
/* log.c */
1307
void  log_init(int, int);
1308
void  log_procinit(const char *);
1309
void  log_setverbose(int);
1310
int log_getverbose(void);
1311
void  log_warn(const char *, ...)
1312
      __attribute__((__format__ (printf, 1, 2)));
1313
void  log_warnx(const char *, ...)
1314
      __attribute__((__format__ (printf, 1, 2)));
1315
void  log_info(const char *, ...)
1316
      __attribute__((__format__ (printf, 1, 2)));
1317
void  log_debug(const char *, ...)
1318
      __attribute__((__format__ (printf, 1, 2)));
1319
void  logit(int, const char *, ...)
1320
      __attribute__((__format__ (printf, 2, 3)));
1321
void  vlog(int, const char *, va_list)
1322
      __attribute__((__format__ (printf, 2, 0)));
1323
__dead void fatal(const char *, ...)
1324
      __attribute__((__format__ (printf, 1, 2)));
1325
__dead void fatalx(const char *, ...)
1326
      __attribute__((__format__ (printf, 1, 2)));
1327
1328
/* ocsp.c */
1329
int  ocsp_connect(struct iked *, struct imsg *);
1330
int  ocsp_receive_fd(struct iked *, struct imsg *);
1331
int  ocsp_validate_cert(struct iked *, void *, size_t, struct iked_sahdr,
1332
    uint8_t, X509 *);
1333
1334
/* parse.y */
1335
int  parse_config(const char *, struct iked *);
1336
int  cmdline_symset(char *);
1337
extern const struct ipsec_xf authxfs[];
1338
extern const struct ipsec_xf prfxfs[];
1339
extern const struct ipsec_xf *encxfs;
1340
extern const struct ipsec_xf ikeencxfs[];
1341
extern const struct ipsec_xf ipsecencxfs[];
1342
extern const struct ipsec_xf groupxfs[];
1343
extern const struct ipsec_xf esnxfs[];
1344
extern const struct ipsec_xf methodxfs[];
1345
extern const struct ipsec_xf saxfs[];
1346
extern const struct ipsec_xf cpxfs[];
1347
size_t   keylength_xf(unsigned int, unsigned int, unsigned int);
1348
size_t   noncelength_xf(unsigned int, unsigned int);
1349
int  encxf_noauth(unsigned int);
1350
1351
/* print.c */
1352
void   print_user(struct iked_user *);
1353
void   print_policy(struct iked_policy *);
1354
const char *print_xf(unsigned int, unsigned int, const struct ipsec_xf *);
1355
1356
#endif /* IKED_H */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2.h.html index 293bf0209..0dc40f7c0 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/ikev2.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2.h,v 1.35 2023/06/28 14:10:24 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_IKEV2_H
21
#define IKED_IKEV2_H
22
23
#include "openbsd-compat.h"
24
25
#define IKEV2_VERSION   0x20  /* IKE version 2.0 */
26
#define IKEV1_VERSION   0x10  /* IKE version 1.0 */
27
28
#define IKEV2_KEYPAD    "Key Pad for IKEv2" /* don't change! */
29
30
/*
31
 * IKEv2 pseudo states
32
 */
33
34
#define IKEV2_STATE_INIT    0 /* new IKE SA */
35
#define IKEV2_STATE_COOKIE    1 /* cookie requested */
36
#define IKEV2_STATE_SA_INIT   2 /* init IKE SA */
37
#define IKEV2_STATE_EAP     3 /* EAP requested */
38
#define IKEV2_STATE_EAP_SUCCESS   4 /* EAP succeeded */
39
#define IKEV2_STATE_AUTH_REQUEST  5 /* auth received */
40
#define IKEV2_STATE_AUTH_SUCCESS  6 /* authenticated */
41
141
#define IKEV2_STATE_VALID   7  /* authenticated AND validated certs */
42
#define IKEV2_STATE_EAP_VALID   8 /* EAP validated */
43
#define IKEV2_STATE_ESTABLISHED   9 /* active IKE SA */
44
#define IKEV2_STATE_CLOSING   10  /* expect delete for this SA */
45
#define IKEV2_STATE_CLOSED    11  /* delete this SA */
46
47
extern struct iked_constmap ikev2_state_map[];
48
49
/*
50
 * "IKEv2 Parameters" based on the official RFC-based assignments by IANA
51
 * (http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.txt)
52
 */
53
54
/*
55
 * IKEv2 definitions of the IKE header
56
 */
57
58
/* IKEv2 exchange types */
59
#define IKEV2_EXCHANGE_IKE_SA_INIT    34  /* Initial Exchange */
60
#define IKEV2_EXCHANGE_IKE_AUTH     35  /* Authentication */
61
#define IKEV2_EXCHANGE_CREATE_CHILD_SA    36  /* Create Child SA */
62
#define IKEV2_EXCHANGE_INFORMATIONAL    37  /* Informational */
63
#define IKEV2_EXCHANGE_IKE_SESSION_RESUME 38  /* RFC5723 */
64
65
extern struct iked_constmap ikev2_exchange_map[];
66
67
/* IKEv2 message flags */
68
#define IKEV2_FLAG_INITIATOR    0x08  /* Sent by the initiator */
69
#define IKEV2_FLAG_OLDVERSION   0x10  /* Supports a higher IKE version */
70
#define IKEV2_FLAG_RESPONSE   0x20  /* Message is a response */
71
72
extern struct iked_constmap ikev2_flag_map[];
73
74
/*
75
 * IKEv2 payloads
76
 */
77
78
struct ikev2_payload {
79
  uint8_t    pld_nextpayload; /* Next payload type */
80
  uint8_t    pld_reserved;    /* Contains the critical bit */
81
  uint16_t   pld_length;    /* Payload length with header */
82
} __packed;
83
84
struct ikev2_frag_payload {
85
  uint16_t   frag_num;    /* current fragment message number */
86
  uint16_t   frag_total;    /* total number of fragment messages */
87
} __packed;
88
89
224k
#define IKEV2_CRITICAL_PAYLOAD  0x01  /* First bit in the reserved field */
90
91
/* IKEv2 payload types */
92
#define IKEV2_PAYLOAD_NONE  0 /* No payload */
93
28.1k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
8.28k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
12.9k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
19.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.80k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
12.1k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
8.17k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
242
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
32.0k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
7.11k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.64k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
18.0k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
224k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
9.77k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
17.0k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
224k
#define IKEV2_PAYLOAD_SKF 53  /* RFC7383 Encrypted Fragment Payload */
111
112
extern struct iked_constmap ikev2_payload_map[];
113
114
/*
115
 * SA payload
116
 */
117
118
struct ikev2_sa_proposal {
119
  uint8_t    sap_more;    /* Last proposal or more */
120
  uint8_t    sap_reserved;    /* Must be set to zero */
121
  uint16_t   sap_length;    /* Proposal length */
122
  uint8_t    sap_proposalnr;  /* Proposal number */
123
  uint8_t    sap_protoid;   /* Protocol Id */
124
  uint8_t    sap_spisize;   /* SPI size */
125
  uint8_t    sap_transforms;  /* Number of transforms */
126
  /* Followed by variable-length SPI */
127
  /* Followed by variable-length transforms */
128
} __packed;
129
130
#define IKEV2_SAP_LAST  0
131
#define IKEV2_SAP_MORE  2
132
133
#define IKEV2_SAPROTO_NONE    0 /* None */
134
#define IKEV2_SAPROTO_IKE   1 /* IKEv2 */
135
#define IKEV2_SAPROTO_AH    2 /* AH */
136
#define IKEV2_SAPROTO_ESP   3 /* ESP */
137
#define IKEV2_SAPROTO_FC_ESP_HEADER 4 /* RFC4595 */
138
#define IKEV2_SAPROTO_FC_CT_AUTH  5 /* RFC4595 */
139
#define IKEV2_SAPROTO_IPCOMP    204 /* private, should be 4 */
140
141
extern struct iked_constmap ikev2_saproto_map[];
142
143
struct ikev2_transform {
144
  uint8_t   xfrm_more;    /* Last transform or more */
145
  uint8_t   xfrm_reserved;    /* Must be set to zero */
146
  uint16_t  xfrm_length;    /* Transform length */
147
  uint8_t   xfrm_type;    /* Transform type */
148
  uint8_t   xfrm_reserved1;   /* Must be set to zero */
149
  uint16_t  xfrm_id;    /* Transform Id */
150
  /* Followed by variable-length transform attributes */
151
} __packed;
152
153
#define IKEV2_XFORM_LAST    0
154
3.09k
#define IKEV2_XFORM_MORE    3
155
156
1.07k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
777
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
567
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
1.00k
#define IKEV2_XFORMTYPE_ESN   5  /* Extended Sequence Numbers */
161
#define IKEV2_XFORMTYPE_MAX   6
162
163
extern struct iked_constmap ikev2_xformtype_map[];
164
165
#define IKEV2_XFORMENCR_NONE    0 /* None */
166
#define IKEV2_XFORMENCR_DES_IV64  1 /* RFC1827 */
167
#define IKEV2_XFORMENCR_DES   2 /* RFC2405 */
168
#define IKEV2_XFORMENCR_3DES    3 /* RFC2451 */
169
#define IKEV2_XFORMENCR_RC5   4 /* RFC2451 */
170
#define IKEV2_XFORMENCR_IDEA    5 /* RFC2451 */
171
#define IKEV2_XFORMENCR_CAST    6 /* RFC2451 */
172
#define IKEV2_XFORMENCR_BLOWFISH  7 /* RFC2451 */
173
#define IKEV2_XFORMENCR_3IDEA   8 /* RFC2451 */
174
#define IKEV2_XFORMENCR_DES_IV32  9 /* DESIV32 */
175
#define IKEV2_XFORMENCR_RC4   10  /* RFC2451 */
176
#define IKEV2_XFORMENCR_NULL    11  /* RFC2410 */
177
#define IKEV2_XFORMENCR_AES_CBC   12  /* RFC3602 */
178
#define IKEV2_XFORMENCR_AES_CTR   13  /* RFC3664 */
179
#define IKEV2_XFORMENCR_AES_CCM_8 14  /* RFC5282 */
180
#define IKEV2_XFORMENCR_AES_CCM_12  15  /* RFC5282 */
181
#define IKEV2_XFORMENCR_AES_CCM_16  16  /* RFC5282 */
182
#define IKEV2_XFORMENCR_AES_GCM_8 18  /* RFC5282 */
183
#define IKEV2_XFORMENCR_AES_GCM_12  19  /* RFC5282 */
184
#define IKEV2_XFORMENCR_AES_GCM_16  20  /* RFC5282 */
185
#define IKEV2_XFORMENCR_NULL_AES_GMAC 21  /* RFC4543 */
186
#define IKEV2_XFORMENCR_XTS_AES   22  /* IEEE P1619 */
187
#define IKEV2_XFORMENCR_CAMELLIA_CBC  23  /* RFC5529 */
188
#define IKEV2_XFORMENCR_CAMELLIA_CTR  24  /* RFC5529 */
189
#define IKEV2_XFORMENCR_CAMELLIA_CCM_8  25  /* RFC5529 */
190
#define IKEV2_XFORMENCR_CAMELLIA_CCM_12 26  /* RFC5529 */
191
#define IKEV2_XFORMENCR_CAMELLIA_CCM_16 27  /* RFC5529 */
192
#define IKEV2_XFORMENCR_CHACHA20_POLY1305 28  /* RFC7634 */
193
194
extern struct iked_constmap ikev2_xformencr_map[];
195
196
#define IKEV2_IPCOMP_OUI    1 /* UNSPECIFIED */
197
#define IKEV2_IPCOMP_DEFLATE    2 /* RFC2394 */
198
#define IKEV2_IPCOMP_LZS    3 /* RFC2395 */
199
#define IKEV2_IPCOMP_LZJH   4 /* RFC3051 */
200
201
extern struct iked_constmap ikev2_ipcomp_map[];
202
203
#define IKEV2_XFORMPRF_HMAC_MD5   1 /* RFC2104 */
204
#define IKEV2_XFORMPRF_HMAC_SHA1  2 /* RFC2104 */
205
#define IKEV2_XFORMPRF_HMAC_TIGER 3 /* RFC2104 */
206
#define IKEV2_XFORMPRF_AES128_XCBC  4 /* RFC3664 */
207
#define IKEV2_XFORMPRF_HMAC_SHA2_256  5 /* RFC4868 */
208
#define IKEV2_XFORMPRF_HMAC_SHA2_384  6 /* RFC4868 */
209
#define IKEV2_XFORMPRF_HMAC_SHA2_512  7 /* RFC4868 */
210
#define IKEV2_XFORMPRF_AES128_CMAC  8 /* RFC4615 */
211
212
extern struct iked_constmap ikev2_xformprf_map[];
213
214
#define IKEV2_XFORMAUTH_NONE    0 /* No Authentication */
215
#define IKEV2_XFORMAUTH_HMAC_MD5_96 1 /* RFC2403 */
216
#define IKEV2_XFORMAUTH_HMAC_SHA1_96  2 /* RFC2404 */
217
#define IKEV2_XFORMAUTH_DES_MAC   3 /* DES-MAC */
218
#define IKEV2_XFORMAUTH_KPDK_MD5  4 /* RFC1826 */
219
#define IKEV2_XFORMAUTH_AES_XCBC_96 5 /* RFC3566 */
220
#define IKEV2_XFORMAUTH_HMAC_MD5_128  6 /* RFC4595 */
221
#define IKEV2_XFORMAUTH_HMAC_SHA1_160 7 /* RFC4595 */
222
#define IKEV2_XFORMAUTH_AES_CMAC_96 8 /* RFC4494 */
223
#define IKEV2_XFORMAUTH_AES_128_GMAC  9 /* RFC4543 */
224
#define IKEV2_XFORMAUTH_AES_192_GMAC  10  /* RFC4543 */
225
#define IKEV2_XFORMAUTH_AES_256_GMAC  11  /* RFC4543 */
226
#define IKEV2_XFORMAUTH_HMAC_SHA2_256_128 12  /* RFC4868 */
227
#define IKEV2_XFORMAUTH_HMAC_SHA2_384_192 13  /* RFC4868 */
228
#define IKEV2_XFORMAUTH_HMAC_SHA2_512_256 14  /* RFC4868 */
229
230
/* Placeholders for AEAD ciphers (only used internally) */
231
#define IKEV2_XFORMAUTH_AES_GCM_8 2018  /* internal */
232
#define IKEV2_XFORMAUTH_AES_GCM_12  2019  /* internal */
233
#define IKEV2_XFORMAUTH_AES_GCM_16  2020  /* internal */
234
235
extern struct iked_constmap ikev2_xformauth_map[];
236
237
#define IKEV2_XFORMDH_NONE    0 /* No DH */
238
#define IKEV2_XFORMDH_MODP_768    1 /* DH Group 1 */
239
#define IKEV2_XFORMDH_MODP_1024   2 /* DH Group 2 */
240
#define IKEV2_XFORMDH_MODP_1536   5 /* DH Group 5 */
241
#define IKEV2_XFORMDH_MODP_2048   14  /* DH Group 14 */
242
#define IKEV2_XFORMDH_MODP_3072   15  /* DH Group 15 */
243
#define IKEV2_XFORMDH_MODP_4096   16  /* DH Group 16 */
244
#define IKEV2_XFORMDH_MODP_6144   17  /* DH Group 17 */
245
#define IKEV2_XFORMDH_MODP_8192   18  /* DH Group 18 */
246
#define IKEV2_XFORMDH_ECP_256   19  /* RFC5114 */
247
#define IKEV2_XFORMDH_ECP_384   20  /* RFC5114 */
248
#define IKEV2_XFORMDH_ECP_521   21  /* RFC5114 */
249
#define IKEV2_XFORMDH_ECP_192   25  /* RFC5114 */
250
#define IKEV2_XFORMDH_ECP_224   26  /* RFC5114 */
251
#define IKEV2_XFORMDH_BRAINPOOL_P224R1  27  /* RFC6954 */
252
#define IKEV2_XFORMDH_BRAINPOOL_P256R1  28  /* RFC6954 */
253
#define IKEV2_XFORMDH_BRAINPOOL_P384R1  29  /* RFC6954 */
254
#define IKEV2_XFORMDH_BRAINPOOL_P512R1  30  /* RFC6954 */
255
#define IKEV2_XFORMDH_CURVE25519  31  /* RFC8031 */
256
#define IKEV2_XFORMDH_X_SNTRUP761X25519 1035  /* private */
257
258
extern struct iked_constmap ikev2_xformdh_map[];
259
260
#define IKEV2_IPV4_OVERHEAD   (20 + 8 + 28) /* IPv4 + UDP + IKE_HDR*/
261
#define IKEV2_MAXLEN_IPV4_FRAG    (576 - IKEV2_IPV4_OVERHEAD)
262
#define IKEV2_IPV6_OVERHEAD   (40 + 8 + 28) /* IPv6 + UDP + IKE_HDR*/
263
#define IKEV2_MAXLEN_IPV6_FRAG    (1280 - IKEV2_IPV6_OVERHEAD)
264
265
#define IKEV2_MAXNUM_TSS    255 /* 8 bit Number of TSs field */
266
267
#define IKEV2_XFORMESN_NONE   0 /* No ESN */
268
#define IKEV2_XFORMESN_ESN    1 /* ESN */
269
270
extern struct iked_constmap ikev2_xformesn_map[];
271
272
struct ikev2_attribute {
273
  uint16_t  attr_type;  /* Attribute type */
274
  uint16_t  attr_length;  /* Attribute length or value */
275
  /* Followed by variable length (TLV) */
276
} __packed;
277
278
#define IKEV2_ATTRAF_TLV    0x0000  /* Type-Length-Value format */
279
57.2k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
22.1k
#define IKEV2_ATTRTYPE_KEY_LENGTH 14  /* Key length */
282
283
extern struct iked_constmap ikev2_attrtype_map[];
284
285
/*
286
 * KE Payload
287
 */
288
289
struct ikev2_keyexchange {
290
  uint16_t   kex_dhgroup;   /* DH Group # */
291
  uint16_t   kex_reserved;    /* Reserved */
292
} __packed;
293
294
/*
295
 * N payload
296
 */
297
298
struct ikev2_notify {
299
  uint8_t    n_protoid;   /* Protocol Id */
300
  uint8_t    n_spisize;   /* SPI size */
301
  uint16_t   n_type;    /* Notify message type */
302
  /* Followed by variable length SPI */
303
  /* Followed by variable length notification data */
304
} __packed;
305
306
#define IKEV2_N_UNSUPPORTED_CRITICAL_PAYLOAD  1 /* RFC7296 */
307
#define IKEV2_N_INVALID_IKE_SPI     4 /* RFC7296 */
308
#define IKEV2_N_INVALID_MAJOR_VERSION   5 /* RFC7296 */
309
#define IKEV2_N_INVALID_SYNTAX      7 /* RFC7296 */
310
#define IKEV2_N_INVALID_MESSAGE_ID    9 /* RFC7296 */
311
#define IKEV2_N_INVALID_SPI     11  /* RFC7296 */
312
36
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
135
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
6
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
241
#define IKEV2_N_NO_ADDITIONAL_SAS   35  /* RFC7296 */
317
#define IKEV2_N_INTERNAL_ADDRESS_FAILURE  36  /* RFC7296 */
318
#define IKEV2_N_FAILED_CP_REQUIRED    37  /* RFC7296 */
319
#define IKEV2_N_TS_UNACCEPTABLE     38  /* RFC7296 */
320
#define IKEV2_N_INVALID_SELECTORS   39  /* RFC7296 */
321
#define IKEV2_N_UNACCEPTABLE_ADDRESSES    40  /* RFC4555 */
322
#define IKEV2_N_UNEXPECTED_NAT_DETECTED   41  /* RFC4555 */
323
#define IKEV2_N_USE_ASSIGNED_HoA    42  /* RFC5026 */
324
348
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
73
#define IKEV2_N_CHILD_SA_NOT_FOUND    44  /* RFC7296 */
326
#define IKEV2_N_INITIAL_CONTACT     16384 /* RFC7296 */
327
#define IKEV2_N_SET_WINDOW_SIZE     16385 /* RFC7296 */
328
#define IKEV2_N_ADDITIONAL_TS_POSSIBLE    16386 /* RFC7296 */
329
255
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
25.6k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
22.6k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
316
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
75
#define IKEV2_N_REKEY_SA      16393  /* RFC7296 */
336
#define IKEV2_N_ESP_TFC_PADDING_NOT_SUPPORTED 16394 /* RFC7296 */
337
#define IKEV2_N_NON_FIRST_FRAGMENTS_ALSO  16395 /* RFC7296 */
338
267
#define IKEV2_N_MOBIKE_SUPPORTED    16396  /* RFC4555 */
339
#define IKEV2_N_ADDITIONAL_IP4_ADDRESS    16397 /* RFC4555 */
340
#define IKEV2_N_ADDITIONAL_IP6_ADDRESS    16398 /* RFC4555 */
341
#define IKEV2_N_NO_ADDITIONAL_ADDRESSES   16399 /* RFC4555 */
342
388
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
202
#define IKEV2_N_COOKIE2       16401  /* RFC4555 */
344
#define IKEV2_N_NO_NATS_ALLOWED     16402 /* RFC4555 */
345
#define IKEV2_N_AUTH_LIFETIME     16403 /* RFC4478 */
346
#define IKEV2_N_MULTIPLE_AUTH_SUPPORTED   16404 /* RFC4739 */
347
#define IKEV2_N_ANOTHER_AUTH_FOLLOWS    16405 /* RFC4739 */
348
#define IKEV2_N_REDIRECT_SUPPORTED    16406 /* RFC5685 */
349
#define IKEV2_N_REDIRECT      16407 /* RFC5685 */
350
#define IKEV2_N_REDIRECTED_FROM     16408 /* RFC5685 */
351
#define IKEV2_N_TICKET_LT_OPAQUE    16409 /* RFC5723 */
352
#define IKEV2_N_TICKET_REQUEST      16410 /* RFC5723 */
353
#define IKEV2_N_TICKET_ACK      16411 /* RFC5723 */
354
#define IKEV2_N_TICKET_NACK     16412 /* RFC5723 */
355
#define IKEV2_N_TICKET_OPAQUE     16413 /* RFC5723 */
356
#define IKEV2_N_LINK_ID       16414 /* RFC5739 */
357
#define IKEV2_N_USE_WESP_MODE     16415 /* RFC5415 */
358
#define IKEV2_N_ROHC_SUPPORTED      16416 /* RFC5857 */
359
#define IKEV2_N_EAP_ONLY_AUTHENTICATION   16417 /* RFC5998 */
360
#define IKEV2_N_CHILDLESS_IKEV2_SUPPORTED 16418 /* RFC6023 */
361
#define IKEV2_N_QUICK_CRASH_DETECTION   16419 /* RFC6290 */
362
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC_SUPPORTED 16420 /* RFC6311 */
363
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC_SUPPORTED 16421 /* RFC6311 */
364
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC   16422 /* RFC6311 */
365
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC   16423 /* RFC6311 */
366
#define IKEV2_N_SECURE_PASSWORD_METHODS   16424 /* RFC6467 */
367
#define IKEV2_N_PSK_PERSIST     16425 /* RFC6631 */
368
#define IKEV2_N_PSK_CONFIRM     16426 /* RFC6631 */
369
#define IKEV2_N_ERX_SUPPORTED     16427 /* RFC6867 */
370
#define IKEV2_N_IFOM_CAPABILITY     16428 /* OA3GPP */
371
14
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
7
#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431  /* RFC7427 */
373
374
extern struct iked_constmap ikev2_n_map[];
375
376
/*
377
 * DELETE payload
378
 */
379
380
struct ikev2_delete {
381
  uint8_t    del_protoid;   /* Protocol Id */
382
  uint8_t    del_spisize;   /* SPI size */
383
  uint16_t   del_nspi;    /* Number of SPIs */
384
  /* Followed by variable length SPIs */
385
} __packed;
386
387
/*
388
 * ID payload
389
 */
390
391
struct ikev2_id {
392
  uint8_t    id_type;   /* Id type */
393
  uint8_t    id_reserved[3];  /* Reserved */
394
  /* Followed by the identification data */
395
} __packed;
396
397
11.8k
#define IKEV2_ID_NONE   0  /* No ID */
398
#define IKEV2_ID_IPV4   1 /* RFC7296 (ID_IPV4_ADDR) */
399
#define IKEV2_ID_FQDN   2 /* RFC7296 */
400
#define IKEV2_ID_UFQDN    3 /* RFC7296 (ID_RFC822_ADDR) */
401
#define IKEV2_ID_IPV6   5 /* RFC7296 (ID_IPV6_ADDR) */
402
#define IKEV2_ID_ASN1_DN  9 /* RFC7296 */
403
#define IKEV2_ID_ASN1_GN  10  /* RFC7296 */
404
#define IKEV2_ID_KEY_ID   11  /* RFC7296 */
405
#define IKEV2_ID_FC_NAME  12  /* RFC4595 */
406
407
extern struct iked_constmap ikev2_id_map[];
408
409
/*
410
 * CERT/CERTREQ payloads
411
 */
412
413
struct ikev2_cert {
414
  uint8_t   cert_type;  /* Encoding */
415
  /* Followed by the certificate data */
416
} __packed;
417
418
4.34k
#define IKEV2_CERT_NONE     0  /* None */
419
#define IKEV2_CERT_X509_PKCS7   1 /* UNSPECIFIED */
420
#define IKEV2_CERT_PGP      2 /* UNSPECIFIED */
421
#define IKEV2_CERT_DNS_SIGNED_KEY 3 /* UNSPECIFIED */
422
1.18k
#define IKEV2_CERT_X509_CERT    4  /* RFC7296 */
423
#define IKEV2_CERT_KERBEROS_TOKEN 6 /* UNSPECIFIED */
424
#define IKEV2_CERT_CRL      7 /* RFC7296 */
425
#define IKEV2_CERT_ARL      8 /* UNSPECIFIED */
426
#define IKEV2_CERT_SPKI     9 /* UNSPECIFIED */
427
#define IKEV2_CERT_X509_ATTR    10  /* UNSPECIFIED */
428
#define IKEV2_CERT_RSA_KEY    11  /* RFC7296 */
429
#define IKEV2_CERT_HASHURL_X509   12  /* RFC7296 */
430
#define IKEV2_CERT_HASHURL_X509_BUNDLE  13  /* RFC7296 */
431
#define IKEV2_CERT_OCSP     14  /* RFC4806 */
432
/*
433
 * As of November 2014, work was still in progress to add a more generic
434
 * format for raw public keys (RFC7296), so we use a number in IANA's private
435
 * use range (201-255, same RFC) for ECDSA.
436
 */
437
#define IKEV2_CERT_ECDSA    201 /* Private */
438
1.94k
#define IKEV2_CERT_BUNDLE   254  /* Private */
439
440
extern struct iked_constmap ikev2_cert_map[];
441
442
/*
443
 * TSi/TSr payloads
444
 */
445
446
struct ikev2_tsp {
447
  uint8_t   tsp_count;    /* Number of TSs */
448
  uint8_t   tsp_reserved[3];  /* Reserved */
449
  /* Followed by the traffic selectors */
450
} __packed;
451
452
struct ikev2_ts {
453
  uint8_t   ts_type;    /* TS type */
454
  uint8_t   ts_protoid;   /* Protocol Id */
455
  uint16_t  ts_length;    /* Length */
456
  uint16_t  ts_startport;   /* Start port */
457
  uint16_t  ts_endport;   /* End port */
458
} __packed;
459
460
6.12k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.35k
#define IKEV2_TS_IPV6_ADDR_RANGE  8  /* RFC7296 */
462
#define IKEV2_TS_FC_ADDR_RANGE    9 /* RFC4595 */
463
464
extern struct iked_constmap ikev2_ts_map[];
465
466
/*
467
 * AUTH payload
468
 */
469
470
struct ikev2_auth {
471
  uint8_t   auth_method;    /* Signature type */
472
  uint8_t   auth_reserved[3]; /* Reserved */
473
  /* Followed by the signature */
474
} __packed;
475
476
#define IKEV2_AUTH_NONE     0 /* None */
477
#define IKEV2_AUTH_RSA_SIG    1 /* RFC7296 */
478
#define IKEV2_AUTH_SHARED_KEY_MIC 2 /* RFC7296 */
479
#define IKEV2_AUTH_DSS_SIG    3 /* RFC7296 */
480
#define IKEV2_AUTH_ECDSA_256    9 /* RFC4754 */
481
#define IKEV2_AUTH_ECDSA_384    10  /* RFC4754 */
482
#define IKEV2_AUTH_ECDSA_521    11  /* RFC4754 */
483
#define IKEV2_AUTH_GSPM     12  /* RFC6467 */
484
#define IKEV2_AUTH_NULL     13  /* RFC7619 */
485
#define IKEV2_AUTH_SIG      14  /* RFC7427 */
486
#define IKEV2_AUTH_SIG_ANY    255 /* Internal (any signature) */
487
/*
488
 * AUTH_SIG also serves as an indication that a given policy has
489
 * been configured to accept RSA or ECDSA payloads, as long as it
490
 * successfully authenticates against a configured CA.
491
 */
492
493
extern struct iked_constmap ikev2_auth_map[];
494
495
/* Notifications used together with IKEV2_AUTH_SIG */
496
497
#define IKEV2_SIGHASH_RESERVED    0 /* RFC7427 */
498
#define IKEV2_SIGHASH_SHA1    1 /* RFC7427 */
499
0
#define IKEV2_SIGHASH_SHA2_256    2  /* RFC7427 */
500
#define IKEV2_SIGHASH_SHA2_384    3 /* RFC7427 */
501
#define IKEV2_SIGHASH_SHA2_512    4 /* RFC7427 */
502
503
extern struct iked_constmap ikev2_sighash_map[];
504
505
/*
506
 * CP payload
507
 */
508
509
struct ikev2_cp {
510
  uint8_t   cp_type;
511
  uint8_t   cp_reserved[3];
512
  /* Followed by the attributes */
513
} __packed;
514
515
#define IKEV2_CP_REQUEST  1 /* CFG-Request */
516
#define IKEV2_CP_REPLY    2 /* CFG-Reply */
517
#define IKEV2_CP_SET    3 /* CFG-SET */
518
#define IKEV2_CP_ACK    4 /* CFG-ACK */
519
520
extern struct iked_constmap ikev2_cp_map[];
521
522
struct ikev2_cfg {
523
  uint16_t  cfg_type; /* first bit must be set to zero */
524
  uint16_t  cfg_length;
525
  /* Followed by variable-length data */
526
} __packed;
527
528
1.31k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.65k
#define IKEV2_CFG_INTERNAL_IP4_DNS    3  /* RFC7296 */
531
#define IKEV2_CFG_INTERNAL_IP4_NBNS   4 /* RFC7296 */
532
#define IKEV2_CFG_INTERNAL_ADDRESS_EXPIRY 5 /* RFC4306 */
533
#define IKEV2_CFG_INTERNAL_IP4_DHCP   6 /* RFC7296 */
534
#define IKEV2_CFG_APPLICATION_VERSION   7 /* RFC7296 */
535
2.37k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
3.10k
#define IKEV2_CFG_INTERNAL_IP6_DNS    10  /* RFC7296 */
537
#define IKEV2_CFG_INTERNAL_IP6_NBNS   11  /* RFC4306 */
538
#define IKEV2_CFG_INTERNAL_IP6_DHCP   12  /* RFC7296 */
539
#define IKEV2_CFG_INTERNAL_IP4_SUBNET   13  /* RFC7296 */
540
#define IKEV2_CFG_SUPPORTED_ATTRIBUTES    14  /* RFC7296 */
541
#define IKEV2_CFG_INTERNAL_IP6_SUBNET   15  /* RFC7296 */
542
#define IKEV2_CFG_MIP6_HOME_PREFIX    16  /* RFC5026 */
543
#define IKEV2_CFG_INTERNAL_IP6_LINK   17  /* RFC5739 */
544
#define IKEV2_CFG_INTERNAL_IP6_PREFIX   18  /* RFC5739 */
545
#define IKEV2_CFG_HOME_AGENT_ADDRESS    19  /* http://www.3gpp.org/ftp/Specs/html-info/24302.htm */
546
#define IKEV2_CFG_INTERNAL_IP4_SERVER   23456 /* MS-IKEE */
547
#define IKEV2_CFG_INTERNAL_IP6_SERVER   23457 /* MS-IKEE */
548
549
extern struct iked_constmap ikev2_cfg_map[];
550
551
/* IKEv1 payload types */
552
#define IKEV1_PAYLOAD_NONE  0 /* No payload */
553
#define IKEV1_PAYLOAD_PROPOSAL  2 /* Proposal */
554
555
#endif /* IKED_IKEV2_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/ikev2.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2.h,v 1.35 2023/06/28 14:10:24 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_IKEV2_H
21
#define IKED_IKEV2_H
22
23
#include "openbsd-compat.h"
24
25
#define IKEV2_VERSION   0x20  /* IKE version 2.0 */
26
#define IKEV1_VERSION   0x10  /* IKE version 1.0 */
27
28
#define IKEV2_KEYPAD    "Key Pad for IKEv2" /* don't change! */
29
30
/*
31
 * IKEv2 pseudo states
32
 */
33
34
#define IKEV2_STATE_INIT    0 /* new IKE SA */
35
#define IKEV2_STATE_COOKIE    1 /* cookie requested */
36
#define IKEV2_STATE_SA_INIT   2 /* init IKE SA */
37
#define IKEV2_STATE_EAP     3 /* EAP requested */
38
#define IKEV2_STATE_EAP_SUCCESS   4 /* EAP succeeded */
39
#define IKEV2_STATE_AUTH_REQUEST  5 /* auth received */
40
#define IKEV2_STATE_AUTH_SUCCESS  6 /* authenticated */
41
141
#define IKEV2_STATE_VALID   7  /* authenticated AND validated certs */
42
#define IKEV2_STATE_EAP_VALID   8 /* EAP validated */
43
#define IKEV2_STATE_ESTABLISHED   9 /* active IKE SA */
44
#define IKEV2_STATE_CLOSING   10  /* expect delete for this SA */
45
#define IKEV2_STATE_CLOSED    11  /* delete this SA */
46
47
extern struct iked_constmap ikev2_state_map[];
48
49
/*
50
 * "IKEv2 Parameters" based on the official RFC-based assignments by IANA
51
 * (http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.txt)
52
 */
53
54
/*
55
 * IKEv2 definitions of the IKE header
56
 */
57
58
/* IKEv2 exchange types */
59
#define IKEV2_EXCHANGE_IKE_SA_INIT    34  /* Initial Exchange */
60
#define IKEV2_EXCHANGE_IKE_AUTH     35  /* Authentication */
61
#define IKEV2_EXCHANGE_CREATE_CHILD_SA    36  /* Create Child SA */
62
#define IKEV2_EXCHANGE_INFORMATIONAL    37  /* Informational */
63
#define IKEV2_EXCHANGE_IKE_SESSION_RESUME 38  /* RFC5723 */
64
65
extern struct iked_constmap ikev2_exchange_map[];
66
67
/* IKEv2 message flags */
68
#define IKEV2_FLAG_INITIATOR    0x08  /* Sent by the initiator */
69
#define IKEV2_FLAG_OLDVERSION   0x10  /* Supports a higher IKE version */
70
#define IKEV2_FLAG_RESPONSE   0x20  /* Message is a response */
71
72
extern struct iked_constmap ikev2_flag_map[];
73
74
/*
75
 * IKEv2 payloads
76
 */
77
78
struct ikev2_payload {
79
  uint8_t    pld_nextpayload; /* Next payload type */
80
  uint8_t    pld_reserved;    /* Contains the critical bit */
81
  uint16_t   pld_length;    /* Payload length with header */
82
} __packed;
83
84
struct ikev2_frag_payload {
85
  uint16_t   frag_num;    /* current fragment message number */
86
  uint16_t   frag_total;    /* total number of fragment messages */
87
} __packed;
88
89
225k
#define IKEV2_CRITICAL_PAYLOAD  0x01  /* First bit in the reserved field */
90
91
/* IKEv2 payload types */
92
#define IKEV2_PAYLOAD_NONE  0 /* No payload */
93
28.2k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
8.28k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
13.0k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
19.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.80k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
12.1k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
8.17k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
242
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
32.4k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
7.11k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.65k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
18.1k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
224k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
9.77k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
17.1k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
224k
#define IKEV2_PAYLOAD_SKF 53  /* RFC7383 Encrypted Fragment Payload */
111
112
extern struct iked_constmap ikev2_payload_map[];
113
114
/*
115
 * SA payload
116
 */
117
118
struct ikev2_sa_proposal {
119
  uint8_t    sap_more;    /* Last proposal or more */
120
  uint8_t    sap_reserved;    /* Must be set to zero */
121
  uint16_t   sap_length;    /* Proposal length */
122
  uint8_t    sap_proposalnr;  /* Proposal number */
123
  uint8_t    sap_protoid;   /* Protocol Id */
124
  uint8_t    sap_spisize;   /* SPI size */
125
  uint8_t    sap_transforms;  /* Number of transforms */
126
  /* Followed by variable-length SPI */
127
  /* Followed by variable-length transforms */
128
} __packed;
129
130
#define IKEV2_SAP_LAST  0
131
#define IKEV2_SAP_MORE  2
132
133
#define IKEV2_SAPROTO_NONE    0 /* None */
134
#define IKEV2_SAPROTO_IKE   1 /* IKEv2 */
135
#define IKEV2_SAPROTO_AH    2 /* AH */
136
#define IKEV2_SAPROTO_ESP   3 /* ESP */
137
#define IKEV2_SAPROTO_FC_ESP_HEADER 4 /* RFC4595 */
138
#define IKEV2_SAPROTO_FC_CT_AUTH  5 /* RFC4595 */
139
#define IKEV2_SAPROTO_IPCOMP    204 /* private, should be 4 */
140
141
extern struct iked_constmap ikev2_saproto_map[];
142
143
struct ikev2_transform {
144
  uint8_t   xfrm_more;    /* Last transform or more */
145
  uint8_t   xfrm_reserved;    /* Must be set to zero */
146
  uint16_t  xfrm_length;    /* Transform length */
147
  uint8_t   xfrm_type;    /* Transform type */
148
  uint8_t   xfrm_reserved1;   /* Must be set to zero */
149
  uint16_t  xfrm_id;    /* Transform Id */
150
  /* Followed by variable-length transform attributes */
151
} __packed;
152
153
#define IKEV2_XFORM_LAST    0
154
3.10k
#define IKEV2_XFORM_MORE    3
155
156
1.07k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
777
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
567
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
1.00k
#define IKEV2_XFORMTYPE_ESN   5  /* Extended Sequence Numbers */
161
#define IKEV2_XFORMTYPE_MAX   6
162
163
extern struct iked_constmap ikev2_xformtype_map[];
164
165
#define IKEV2_XFORMENCR_NONE    0 /* None */
166
#define IKEV2_XFORMENCR_DES_IV64  1 /* RFC1827 */
167
#define IKEV2_XFORMENCR_DES   2 /* RFC2405 */
168
#define IKEV2_XFORMENCR_3DES    3 /* RFC2451 */
169
#define IKEV2_XFORMENCR_RC5   4 /* RFC2451 */
170
#define IKEV2_XFORMENCR_IDEA    5 /* RFC2451 */
171
#define IKEV2_XFORMENCR_CAST    6 /* RFC2451 */
172
#define IKEV2_XFORMENCR_BLOWFISH  7 /* RFC2451 */
173
#define IKEV2_XFORMENCR_3IDEA   8 /* RFC2451 */
174
#define IKEV2_XFORMENCR_DES_IV32  9 /* DESIV32 */
175
#define IKEV2_XFORMENCR_RC4   10  /* RFC2451 */
176
#define IKEV2_XFORMENCR_NULL    11  /* RFC2410 */
177
#define IKEV2_XFORMENCR_AES_CBC   12  /* RFC3602 */
178
#define IKEV2_XFORMENCR_AES_CTR   13  /* RFC3664 */
179
#define IKEV2_XFORMENCR_AES_CCM_8 14  /* RFC5282 */
180
#define IKEV2_XFORMENCR_AES_CCM_12  15  /* RFC5282 */
181
#define IKEV2_XFORMENCR_AES_CCM_16  16  /* RFC5282 */
182
#define IKEV2_XFORMENCR_AES_GCM_8 18  /* RFC5282 */
183
#define IKEV2_XFORMENCR_AES_GCM_12  19  /* RFC5282 */
184
#define IKEV2_XFORMENCR_AES_GCM_16  20  /* RFC5282 */
185
#define IKEV2_XFORMENCR_NULL_AES_GMAC 21  /* RFC4543 */
186
#define IKEV2_XFORMENCR_XTS_AES   22  /* IEEE P1619 */
187
#define IKEV2_XFORMENCR_CAMELLIA_CBC  23  /* RFC5529 */
188
#define IKEV2_XFORMENCR_CAMELLIA_CTR  24  /* RFC5529 */
189
#define IKEV2_XFORMENCR_CAMELLIA_CCM_8  25  /* RFC5529 */
190
#define IKEV2_XFORMENCR_CAMELLIA_CCM_12 26  /* RFC5529 */
191
#define IKEV2_XFORMENCR_CAMELLIA_CCM_16 27  /* RFC5529 */
192
#define IKEV2_XFORMENCR_CHACHA20_POLY1305 28  /* RFC7634 */
193
194
extern struct iked_constmap ikev2_xformencr_map[];
195
196
#define IKEV2_IPCOMP_OUI    1 /* UNSPECIFIED */
197
#define IKEV2_IPCOMP_DEFLATE    2 /* RFC2394 */
198
#define IKEV2_IPCOMP_LZS    3 /* RFC2395 */
199
#define IKEV2_IPCOMP_LZJH   4 /* RFC3051 */
200
201
extern struct iked_constmap ikev2_ipcomp_map[];
202
203
#define IKEV2_XFORMPRF_HMAC_MD5   1 /* RFC2104 */
204
#define IKEV2_XFORMPRF_HMAC_SHA1  2 /* RFC2104 */
205
#define IKEV2_XFORMPRF_HMAC_TIGER 3 /* RFC2104 */
206
#define IKEV2_XFORMPRF_AES128_XCBC  4 /* RFC3664 */
207
#define IKEV2_XFORMPRF_HMAC_SHA2_256  5 /* RFC4868 */
208
#define IKEV2_XFORMPRF_HMAC_SHA2_384  6 /* RFC4868 */
209
#define IKEV2_XFORMPRF_HMAC_SHA2_512  7 /* RFC4868 */
210
#define IKEV2_XFORMPRF_AES128_CMAC  8 /* RFC4615 */
211
212
extern struct iked_constmap ikev2_xformprf_map[];
213
214
#define IKEV2_XFORMAUTH_NONE    0 /* No Authentication */
215
#define IKEV2_XFORMAUTH_HMAC_MD5_96 1 /* RFC2403 */
216
#define IKEV2_XFORMAUTH_HMAC_SHA1_96  2 /* RFC2404 */
217
#define IKEV2_XFORMAUTH_DES_MAC   3 /* DES-MAC */
218
#define IKEV2_XFORMAUTH_KPDK_MD5  4 /* RFC1826 */
219
#define IKEV2_XFORMAUTH_AES_XCBC_96 5 /* RFC3566 */
220
#define IKEV2_XFORMAUTH_HMAC_MD5_128  6 /* RFC4595 */
221
#define IKEV2_XFORMAUTH_HMAC_SHA1_160 7 /* RFC4595 */
222
#define IKEV2_XFORMAUTH_AES_CMAC_96 8 /* RFC4494 */
223
#define IKEV2_XFORMAUTH_AES_128_GMAC  9 /* RFC4543 */
224
#define IKEV2_XFORMAUTH_AES_192_GMAC  10  /* RFC4543 */
225
#define IKEV2_XFORMAUTH_AES_256_GMAC  11  /* RFC4543 */
226
#define IKEV2_XFORMAUTH_HMAC_SHA2_256_128 12  /* RFC4868 */
227
#define IKEV2_XFORMAUTH_HMAC_SHA2_384_192 13  /* RFC4868 */
228
#define IKEV2_XFORMAUTH_HMAC_SHA2_512_256 14  /* RFC4868 */
229
230
/* Placeholders for AEAD ciphers (only used internally) */
231
#define IKEV2_XFORMAUTH_AES_GCM_8 2018  /* internal */
232
#define IKEV2_XFORMAUTH_AES_GCM_12  2019  /* internal */
233
#define IKEV2_XFORMAUTH_AES_GCM_16  2020  /* internal */
234
235
extern struct iked_constmap ikev2_xformauth_map[];
236
237
#define IKEV2_XFORMDH_NONE    0 /* No DH */
238
#define IKEV2_XFORMDH_MODP_768    1 /* DH Group 1 */
239
#define IKEV2_XFORMDH_MODP_1024   2 /* DH Group 2 */
240
#define IKEV2_XFORMDH_MODP_1536   5 /* DH Group 5 */
241
#define IKEV2_XFORMDH_MODP_2048   14  /* DH Group 14 */
242
#define IKEV2_XFORMDH_MODP_3072   15  /* DH Group 15 */
243
#define IKEV2_XFORMDH_MODP_4096   16  /* DH Group 16 */
244
#define IKEV2_XFORMDH_MODP_6144   17  /* DH Group 17 */
245
#define IKEV2_XFORMDH_MODP_8192   18  /* DH Group 18 */
246
#define IKEV2_XFORMDH_ECP_256   19  /* RFC5114 */
247
#define IKEV2_XFORMDH_ECP_384   20  /* RFC5114 */
248
#define IKEV2_XFORMDH_ECP_521   21  /* RFC5114 */
249
#define IKEV2_XFORMDH_ECP_192   25  /* RFC5114 */
250
#define IKEV2_XFORMDH_ECP_224   26  /* RFC5114 */
251
#define IKEV2_XFORMDH_BRAINPOOL_P224R1  27  /* RFC6954 */
252
#define IKEV2_XFORMDH_BRAINPOOL_P256R1  28  /* RFC6954 */
253
#define IKEV2_XFORMDH_BRAINPOOL_P384R1  29  /* RFC6954 */
254
#define IKEV2_XFORMDH_BRAINPOOL_P512R1  30  /* RFC6954 */
255
#define IKEV2_XFORMDH_CURVE25519  31  /* RFC8031 */
256
#define IKEV2_XFORMDH_X_SNTRUP761X25519 1035  /* private */
257
258
extern struct iked_constmap ikev2_xformdh_map[];
259
260
#define IKEV2_IPV4_OVERHEAD   (20 + 8 + 28) /* IPv4 + UDP + IKE_HDR*/
261
#define IKEV2_MAXLEN_IPV4_FRAG    (576 - IKEV2_IPV4_OVERHEAD)
262
#define IKEV2_IPV6_OVERHEAD   (40 + 8 + 28) /* IPv6 + UDP + IKE_HDR*/
263
#define IKEV2_MAXLEN_IPV6_FRAG    (1280 - IKEV2_IPV6_OVERHEAD)
264
265
#define IKEV2_MAXNUM_TSS    255 /* 8 bit Number of TSs field */
266
267
#define IKEV2_XFORMESN_NONE   0 /* No ESN */
268
#define IKEV2_XFORMESN_ESN    1 /* ESN */
269
270
extern struct iked_constmap ikev2_xformesn_map[];
271
272
struct ikev2_attribute {
273
  uint16_t  attr_type;  /* Attribute type */
274
  uint16_t  attr_length;  /* Attribute length or value */
275
  /* Followed by variable length (TLV) */
276
} __packed;
277
278
#define IKEV2_ATTRAF_TLV    0x0000  /* Type-Length-Value format */
279
57.2k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
22.1k
#define IKEV2_ATTRTYPE_KEY_LENGTH 14  /* Key length */
282
283
extern struct iked_constmap ikev2_attrtype_map[];
284
285
/*
286
 * KE Payload
287
 */
288
289
struct ikev2_keyexchange {
290
  uint16_t   kex_dhgroup;   /* DH Group # */
291
  uint16_t   kex_reserved;    /* Reserved */
292
} __packed;
293
294
/*
295
 * N payload
296
 */
297
298
struct ikev2_notify {
299
  uint8_t    n_protoid;   /* Protocol Id */
300
  uint8_t    n_spisize;   /* SPI size */
301
  uint16_t   n_type;    /* Notify message type */
302
  /* Followed by variable length SPI */
303
  /* Followed by variable length notification data */
304
} __packed;
305
306
#define IKEV2_N_UNSUPPORTED_CRITICAL_PAYLOAD  1 /* RFC7296 */
307
#define IKEV2_N_INVALID_IKE_SPI     4 /* RFC7296 */
308
#define IKEV2_N_INVALID_MAJOR_VERSION   5 /* RFC7296 */
309
#define IKEV2_N_INVALID_SYNTAX      7 /* RFC7296 */
310
#define IKEV2_N_INVALID_MESSAGE_ID    9 /* RFC7296 */
311
#define IKEV2_N_INVALID_SPI     11  /* RFC7296 */
312
36
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
135
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
6
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
241
#define IKEV2_N_NO_ADDITIONAL_SAS   35  /* RFC7296 */
317
#define IKEV2_N_INTERNAL_ADDRESS_FAILURE  36  /* RFC7296 */
318
#define IKEV2_N_FAILED_CP_REQUIRED    37  /* RFC7296 */
319
#define IKEV2_N_TS_UNACCEPTABLE     38  /* RFC7296 */
320
#define IKEV2_N_INVALID_SELECTORS   39  /* RFC7296 */
321
#define IKEV2_N_UNACCEPTABLE_ADDRESSES    40  /* RFC4555 */
322
#define IKEV2_N_UNEXPECTED_NAT_DETECTED   41  /* RFC4555 */
323
#define IKEV2_N_USE_ASSIGNED_HoA    42  /* RFC5026 */
324
348
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
73
#define IKEV2_N_CHILD_SA_NOT_FOUND    44  /* RFC7296 */
326
#define IKEV2_N_INITIAL_CONTACT     16384 /* RFC7296 */
327
#define IKEV2_N_SET_WINDOW_SIZE     16385 /* RFC7296 */
328
#define IKEV2_N_ADDITIONAL_TS_POSSIBLE    16386 /* RFC7296 */
329
255
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
26.0k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
23.0k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
316
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
75
#define IKEV2_N_REKEY_SA      16393  /* RFC7296 */
336
#define IKEV2_N_ESP_TFC_PADDING_NOT_SUPPORTED 16394 /* RFC7296 */
337
#define IKEV2_N_NON_FIRST_FRAGMENTS_ALSO  16395 /* RFC7296 */
338
267
#define IKEV2_N_MOBIKE_SUPPORTED    16396  /* RFC4555 */
339
#define IKEV2_N_ADDITIONAL_IP4_ADDRESS    16397 /* RFC4555 */
340
#define IKEV2_N_ADDITIONAL_IP6_ADDRESS    16398 /* RFC4555 */
341
#define IKEV2_N_NO_ADDITIONAL_ADDRESSES   16399 /* RFC4555 */
342
388
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
202
#define IKEV2_N_COOKIE2       16401  /* RFC4555 */
344
#define IKEV2_N_NO_NATS_ALLOWED     16402 /* RFC4555 */
345
#define IKEV2_N_AUTH_LIFETIME     16403 /* RFC4478 */
346
#define IKEV2_N_MULTIPLE_AUTH_SUPPORTED   16404 /* RFC4739 */
347
#define IKEV2_N_ANOTHER_AUTH_FOLLOWS    16405 /* RFC4739 */
348
#define IKEV2_N_REDIRECT_SUPPORTED    16406 /* RFC5685 */
349
#define IKEV2_N_REDIRECT      16407 /* RFC5685 */
350
#define IKEV2_N_REDIRECTED_FROM     16408 /* RFC5685 */
351
#define IKEV2_N_TICKET_LT_OPAQUE    16409 /* RFC5723 */
352
#define IKEV2_N_TICKET_REQUEST      16410 /* RFC5723 */
353
#define IKEV2_N_TICKET_ACK      16411 /* RFC5723 */
354
#define IKEV2_N_TICKET_NACK     16412 /* RFC5723 */
355
#define IKEV2_N_TICKET_OPAQUE     16413 /* RFC5723 */
356
#define IKEV2_N_LINK_ID       16414 /* RFC5739 */
357
#define IKEV2_N_USE_WESP_MODE     16415 /* RFC5415 */
358
#define IKEV2_N_ROHC_SUPPORTED      16416 /* RFC5857 */
359
#define IKEV2_N_EAP_ONLY_AUTHENTICATION   16417 /* RFC5998 */
360
#define IKEV2_N_CHILDLESS_IKEV2_SUPPORTED 16418 /* RFC6023 */
361
#define IKEV2_N_QUICK_CRASH_DETECTION   16419 /* RFC6290 */
362
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC_SUPPORTED 16420 /* RFC6311 */
363
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC_SUPPORTED 16421 /* RFC6311 */
364
#define IKEV2_N_IKEV2_MESSAGE_ID_SYNC   16422 /* RFC6311 */
365
#define IKEV2_N_IPSEC_REPLAY_CTR_SYNC   16423 /* RFC6311 */
366
#define IKEV2_N_SECURE_PASSWORD_METHODS   16424 /* RFC6467 */
367
#define IKEV2_N_PSK_PERSIST     16425 /* RFC6631 */
368
#define IKEV2_N_PSK_CONFIRM     16426 /* RFC6631 */
369
#define IKEV2_N_ERX_SUPPORTED     16427 /* RFC6867 */
370
#define IKEV2_N_IFOM_CAPABILITY     16428 /* OA3GPP */
371
14
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
7
#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431  /* RFC7427 */
373
374
extern struct iked_constmap ikev2_n_map[];
375
376
/*
377
 * DELETE payload
378
 */
379
380
struct ikev2_delete {
381
  uint8_t    del_protoid;   /* Protocol Id */
382
  uint8_t    del_spisize;   /* SPI size */
383
  uint16_t   del_nspi;    /* Number of SPIs */
384
  /* Followed by variable length SPIs */
385
} __packed;
386
387
/*
388
 * ID payload
389
 */
390
391
struct ikev2_id {
392
  uint8_t    id_type;   /* Id type */
393
  uint8_t    id_reserved[3];  /* Reserved */
394
  /* Followed by the identification data */
395
} __packed;
396
397
11.8k
#define IKEV2_ID_NONE   0  /* No ID */
398
#define IKEV2_ID_IPV4   1 /* RFC7296 (ID_IPV4_ADDR) */
399
#define IKEV2_ID_FQDN   2 /* RFC7296 */
400
#define IKEV2_ID_UFQDN    3 /* RFC7296 (ID_RFC822_ADDR) */
401
#define IKEV2_ID_IPV6   5 /* RFC7296 (ID_IPV6_ADDR) */
402
#define IKEV2_ID_ASN1_DN  9 /* RFC7296 */
403
#define IKEV2_ID_ASN1_GN  10  /* RFC7296 */
404
#define IKEV2_ID_KEY_ID   11  /* RFC7296 */
405
#define IKEV2_ID_FC_NAME  12  /* RFC4595 */
406
407
extern struct iked_constmap ikev2_id_map[];
408
409
/*
410
 * CERT/CERTREQ payloads
411
 */
412
413
struct ikev2_cert {
414
  uint8_t   cert_type;  /* Encoding */
415
  /* Followed by the certificate data */
416
} __packed;
417
418
4.34k
#define IKEV2_CERT_NONE     0  /* None */
419
#define IKEV2_CERT_X509_PKCS7   1 /* UNSPECIFIED */
420
#define IKEV2_CERT_PGP      2 /* UNSPECIFIED */
421
#define IKEV2_CERT_DNS_SIGNED_KEY 3 /* UNSPECIFIED */
422
1.18k
#define IKEV2_CERT_X509_CERT    4  /* RFC7296 */
423
#define IKEV2_CERT_KERBEROS_TOKEN 6 /* UNSPECIFIED */
424
#define IKEV2_CERT_CRL      7 /* RFC7296 */
425
#define IKEV2_CERT_ARL      8 /* UNSPECIFIED */
426
#define IKEV2_CERT_SPKI     9 /* UNSPECIFIED */
427
#define IKEV2_CERT_X509_ATTR    10  /* UNSPECIFIED */
428
#define IKEV2_CERT_RSA_KEY    11  /* RFC7296 */
429
#define IKEV2_CERT_HASHURL_X509   12  /* RFC7296 */
430
#define IKEV2_CERT_HASHURL_X509_BUNDLE  13  /* RFC7296 */
431
#define IKEV2_CERT_OCSP     14  /* RFC4806 */
432
/*
433
 * As of November 2014, work was still in progress to add a more generic
434
 * format for raw public keys (RFC7296), so we use a number in IANA's private
435
 * use range (201-255, same RFC) for ECDSA.
436
 */
437
#define IKEV2_CERT_ECDSA    201 /* Private */
438
1.94k
#define IKEV2_CERT_BUNDLE   254  /* Private */
439
440
extern struct iked_constmap ikev2_cert_map[];
441
442
/*
443
 * TSi/TSr payloads
444
 */
445
446
struct ikev2_tsp {
447
  uint8_t   tsp_count;    /* Number of TSs */
448
  uint8_t   tsp_reserved[3];  /* Reserved */
449
  /* Followed by the traffic selectors */
450
} __packed;
451
452
struct ikev2_ts {
453
  uint8_t   ts_type;    /* TS type */
454
  uint8_t   ts_protoid;   /* Protocol Id */
455
  uint16_t  ts_length;    /* Length */
456
  uint16_t  ts_startport;   /* Start port */
457
  uint16_t  ts_endport;   /* End port */
458
} __packed;
459
460
6.22k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.36k
#define IKEV2_TS_IPV6_ADDR_RANGE  8  /* RFC7296 */
462
#define IKEV2_TS_FC_ADDR_RANGE    9 /* RFC4595 */
463
464
extern struct iked_constmap ikev2_ts_map[];
465
466
/*
467
 * AUTH payload
468
 */
469
470
struct ikev2_auth {
471
  uint8_t   auth_method;    /* Signature type */
472
  uint8_t   auth_reserved[3]; /* Reserved */
473
  /* Followed by the signature */
474
} __packed;
475
476
#define IKEV2_AUTH_NONE     0 /* None */
477
#define IKEV2_AUTH_RSA_SIG    1 /* RFC7296 */
478
#define IKEV2_AUTH_SHARED_KEY_MIC 2 /* RFC7296 */
479
#define IKEV2_AUTH_DSS_SIG    3 /* RFC7296 */
480
#define IKEV2_AUTH_ECDSA_256    9 /* RFC4754 */
481
#define IKEV2_AUTH_ECDSA_384    10  /* RFC4754 */
482
#define IKEV2_AUTH_ECDSA_521    11  /* RFC4754 */
483
#define IKEV2_AUTH_GSPM     12  /* RFC6467 */
484
#define IKEV2_AUTH_NULL     13  /* RFC7619 */
485
#define IKEV2_AUTH_SIG      14  /* RFC7427 */
486
#define IKEV2_AUTH_SIG_ANY    255 /* Internal (any signature) */
487
/*
488
 * AUTH_SIG also serves as an indication that a given policy has
489
 * been configured to accept RSA or ECDSA payloads, as long as it
490
 * successfully authenticates against a configured CA.
491
 */
492
493
extern struct iked_constmap ikev2_auth_map[];
494
495
/* Notifications used together with IKEV2_AUTH_SIG */
496
497
#define IKEV2_SIGHASH_RESERVED    0 /* RFC7427 */
498
#define IKEV2_SIGHASH_SHA1    1 /* RFC7427 */
499
0
#define IKEV2_SIGHASH_SHA2_256    2  /* RFC7427 */
500
#define IKEV2_SIGHASH_SHA2_384    3 /* RFC7427 */
501
#define IKEV2_SIGHASH_SHA2_512    4 /* RFC7427 */
502
503
extern struct iked_constmap ikev2_sighash_map[];
504
505
/*
506
 * CP payload
507
 */
508
509
struct ikev2_cp {
510
  uint8_t   cp_type;
511
  uint8_t   cp_reserved[3];
512
  /* Followed by the attributes */
513
} __packed;
514
515
#define IKEV2_CP_REQUEST  1 /* CFG-Request */
516
#define IKEV2_CP_REPLY    2 /* CFG-Reply */
517
#define IKEV2_CP_SET    3 /* CFG-SET */
518
#define IKEV2_CP_ACK    4 /* CFG-ACK */
519
520
extern struct iked_constmap ikev2_cp_map[];
521
522
struct ikev2_cfg {
523
  uint16_t  cfg_type; /* first bit must be set to zero */
524
  uint16_t  cfg_length;
525
  /* Followed by variable-length data */
526
} __packed;
527
528
1.31k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.65k
#define IKEV2_CFG_INTERNAL_IP4_DNS    3  /* RFC7296 */
531
#define IKEV2_CFG_INTERNAL_IP4_NBNS   4 /* RFC7296 */
532
#define IKEV2_CFG_INTERNAL_ADDRESS_EXPIRY 5 /* RFC4306 */
533
#define IKEV2_CFG_INTERNAL_IP4_DHCP   6 /* RFC7296 */
534
#define IKEV2_CFG_APPLICATION_VERSION   7 /* RFC7296 */
535
2.37k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
3.10k
#define IKEV2_CFG_INTERNAL_IP6_DNS    10  /* RFC7296 */
537
#define IKEV2_CFG_INTERNAL_IP6_NBNS   11  /* RFC4306 */
538
#define IKEV2_CFG_INTERNAL_IP6_DHCP   12  /* RFC7296 */
539
#define IKEV2_CFG_INTERNAL_IP4_SUBNET   13  /* RFC7296 */
540
#define IKEV2_CFG_SUPPORTED_ATTRIBUTES    14  /* RFC7296 */
541
#define IKEV2_CFG_INTERNAL_IP6_SUBNET   15  /* RFC7296 */
542
#define IKEV2_CFG_MIP6_HOME_PREFIX    16  /* RFC5026 */
543
#define IKEV2_CFG_INTERNAL_IP6_LINK   17  /* RFC5739 */
544
#define IKEV2_CFG_INTERNAL_IP6_PREFIX   18  /* RFC5739 */
545
#define IKEV2_CFG_HOME_AGENT_ADDRESS    19  /* http://www.3gpp.org/ftp/Specs/html-info/24302.htm */
546
#define IKEV2_CFG_INTERNAL_IP4_SERVER   23456 /* MS-IKEE */
547
#define IKEV2_CFG_INTERNAL_IP6_SERVER   23457 /* MS-IKEE */
548
549
extern struct iked_constmap ikev2_cfg_map[];
550
551
/* IKEv1 payload types */
552
#define IKEV1_PAYLOAD_NONE  0 /* No payload */
553
#define IKEV1_PAYLOAD_PROPOSAL  2 /* Proposal */
554
555
#endif /* IKED_IKEV2_H */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2_pld.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2_pld.c.html index 43e51451a..dddcaa0de 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2_pld.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/ikev2_pld.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/ikev2_pld.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2_pld.c,v 1.133 2023/09/02 18:36:30 tobhe Exp $ */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2014 Hans-Joerg Hoexer
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <string.h>
32
#include <signal.h>
33
#include <endian.h>
34
#include <errno.h>
35
#include <err.h>
36
#include <event.h>
37
38
#include <openssl/sha.h>
39
#include <openssl/evp.h>
40
41
#include "iked.h"
42
#include "ikev2.h"
43
#include "eap.h"
44
#include "dh.h"
45
46
int  ikev2_validate_pld(struct iked_message *, size_t, size_t,
47
      struct ikev2_payload *);
48
int  ikev2_pld_payloads(struct iked *, struct iked_message *,
49
      size_t, size_t, unsigned int);
50
int  ikev2_validate_sa(struct iked_message *, size_t, size_t,
51
      struct ikev2_sa_proposal *);
52
int  ikev2_pld_sa(struct iked *, struct ikev2_payload *,
53
      struct iked_message *, size_t, size_t);
54
int  ikev2_validate_xform(struct iked_message *, size_t, size_t,
55
      struct ikev2_transform *);
56
int  ikev2_pld_xform(struct iked *, struct iked_message *,
57
      size_t, size_t);
58
int  ikev2_validate_attr(struct iked_message *, size_t, size_t,
59
      struct ikev2_attribute *);
60
int  ikev2_pld_attr(struct iked *, struct ikev2_transform *,
61
      struct iked_message *, size_t, size_t);
62
int  ikev2_validate_ke(struct iked_message *, size_t, size_t,
63
      struct ikev2_keyexchange *);
64
int  ikev2_pld_ke(struct iked *, struct ikev2_payload *,
65
      struct iked_message *, size_t, size_t);
66
int  ikev2_validate_id(struct iked_message *, size_t, size_t,
67
      struct ikev2_id *);
68
int  ikev2_pld_id(struct iked *, struct ikev2_payload *,
69
      struct iked_message *, size_t, size_t, unsigned int);
70
int  ikev2_validate_cert(struct iked_message *, size_t, size_t,
71
      struct ikev2_cert *);
72
int  ikev2_pld_cert(struct iked *, struct ikev2_payload *,
73
      struct iked_message *, size_t, size_t);
74
int  ikev2_validate_certreq(struct iked_message *, size_t, size_t,
75
      struct ikev2_cert *);
76
int  ikev2_pld_certreq(struct iked *, struct ikev2_payload *,
77
      struct iked_message *, size_t, size_t);
78
int  ikev2_pld_nonce(struct iked *, struct ikev2_payload *,
79
      struct iked_message *, size_t, size_t);
80
int  ikev2_validate_notify(struct iked_message *, size_t, size_t,
81
      struct ikev2_notify *);
82
int  ikev2_pld_notify(struct iked *, struct ikev2_payload *,
83
      struct iked_message *, size_t, size_t);
84
int  ikev2_validate_delete(struct iked_message *, size_t, size_t,
85
      struct ikev2_delete *);
86
int  ikev2_pld_delete(struct iked *, struct ikev2_payload *,
87
      struct iked_message *, size_t, size_t);
88
int  ikev2_validate_tss(struct iked_message *, size_t, size_t,
89
      struct ikev2_tsp *);
90
int  ikev2_pld_tss(struct iked *, struct ikev2_payload *,
91
      struct iked_message *, size_t, size_t);
92
int  ikev2_validate_ts(struct iked_message *, size_t, size_t,
93
      struct ikev2_ts *);
94
int  ikev2_pld_ts(struct iked *, struct ikev2_payload *,
95
      struct iked_message *, size_t, size_t, unsigned int);
96
int  ikev2_validate_auth(struct iked_message *, size_t, size_t,
97
      struct ikev2_auth *);
98
int  ikev2_pld_auth(struct iked *, struct ikev2_payload *,
99
      struct iked_message *, size_t, size_t);
100
int  ikev2_pld_e(struct iked *, struct ikev2_payload *,
101
      struct iked_message *, size_t, size_t);
102
int  ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
103
      struct iked_message *msg, size_t offset, size_t left);
104
int  ikev2_frags_reassemble(struct iked *env,
105
      struct ikev2_payload *pld, struct iked_message *msg);
106
int  ikev2_validate_cp(struct iked_message *, size_t, size_t,
107
      struct ikev2_cp *);
108
int  ikev2_pld_cp(struct iked *, struct ikev2_payload *,
109
      struct iked_message *, size_t, size_t);
110
int  ikev2_validate_eap(struct iked_message *, size_t, size_t,
111
      struct eap_header *);
112
int  ikev2_pld_eap(struct iked *, struct ikev2_payload *,
113
      struct iked_message *, size_t, size_t);
114
115
int
116
ikev2_pld_parse(struct iked *env, struct ike_header *hdr,
117
    struct iked_message *msg, size_t offset)
118
13.0k
{
119
13.0k
  log_debug("%s: header ispi %s rspi %s"
120
13.0k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
13.0k
      " msgid %d length %u response %d", __func__,
122
13.0k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
13.0k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
13.0k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
13.0k
      hdr->ike_version,
126
13.0k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
13.0k
      hdr->ike_flags,
128
13.0k
      betoh32(hdr->ike_msgid),
129
13.0k
      betoh32(hdr->ike_length),
130
13.0k
      msg->msg_response);
131
132
13.0k
  if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) {
133
4
    log_debug("%s: short message", __func__);
134
4
    return (-1);
135
4
  }
136
137
13.0k
  offset += sizeof(*hdr);
138
139
13.0k
  return (ikev2_pld_payloads(env, msg, offset,
140
13.0k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
13.0k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
234k
{
147
234k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
234k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
234k
  if (left < sizeof(*pld)) {
152
1.71k
    log_debug("%s: malformed payload: too short for generic "
153
1.71k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.71k
    return (-1);
155
1.71k
  }
156
232k
  memcpy(pld, msgbuf + offset, sizeof(*pld));
157
158
  /*
159
   * We need at least the specified number of bytes.
160
   * pld_length is the full size of the payload including
161
   * the generic payload header.
162
   */
163
232k
  pld_length = betoh16(pld->pld_length);
164
232k
  if (left < pld_length) {
165
5.81k
    log_debug("%s: malformed payload: shorter than specified "
166
5.81k
        "(%zu < %zu)", __func__, left, pld_length);
167
5.81k
    return (-1);
168
5.81k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
227k
  if (pld_length < sizeof(*pld)) {
174
2.33k
    log_debug("%s: malformed payload: shorter than minimum "
175
2.33k
        "header size (%zu < %zu)", __func__, pld_length,
176
2.33k
        sizeof(*pld));
177
2.33k
    return (-1);
178
2.33k
  }
179
180
224k
  return (0);
181
227k
}
182
183
int
184
ikev2_pld_payloads(struct iked *env, struct iked_message *msg,
185
    size_t offset, size_t length, unsigned int payload)
186
13.0k
{
187
13.0k
  struct ikev2_payload   pld;
188
13.0k
  unsigned int     e;
189
13.0k
  int      ret;
190
13.0k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
13.0k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
13.0k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
13.0k
  total = length - offset;
198
199
237k
  while (payload != 0 && offset < length) {
200
234k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
9.86k
      return (-1);
202
203
224k
    log_debug("%s: %spayload %s"
204
224k
        " nextpayload %s critical 0x%02x length %d",
205
224k
        __func__, e ? "decrypted " : "",
206
224k
        print_map(payload, ikev2_payload_map),
207
224k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
224k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
224k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
224k
    offset += sizeof(pld);
213
224k
    total -= sizeof(pld);
214
224k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
224k
    ret = 0;
216
217
224k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
28.1k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
28.1k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
28.1k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
8.28k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
8.28k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
8.28k
      break;
226
12.8k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
19.4k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
19.4k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
19.4k
          payload);
230
19.4k
      break;
231
5.80k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.80k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.80k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
12.1k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
12.1k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
12.1k
      break;
238
8.17k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
8.17k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
8.17k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
242
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
242
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
242
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
32.0k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
32.0k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
32.0k
      break;
249
7.11k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
7.11k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
7.11k
      break;
252
4.64k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
18.0k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
18.0k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
18.0k
      break;
256
0
    case IKEV2_PAYLOAD_SK:
257
0
      ret = ikev2_pld_e(env, &pld, msg, offset, left);
258
0
      break;
259
0
    case IKEV2_PAYLOAD_SKF:
260
0
      ret = ikev2_pld_ef(env, &pld, msg, offset, left);
261
0
      break;
262
9.77k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
9.77k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
9.77k
      break;
265
17.0k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
17.0k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
17.0k
      break;
268
58.3k
    default:
269
58.3k
      print_hex(msgbuf, offset,
270
58.3k
          betoh16(pld.pld_length) - sizeof(pld));
271
58.3k
      break;
272
224k
    }
273
274
224k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
722
      (void)ikev2_send_informational(env, msg);
276
722
      return (-1);
277
722
    }
278
279
    /* Encrypted payloads must appear last */
280
224k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
224k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
224k
    payload = pld.pld_nextpayload;
285
224k
    offset += left;
286
224k
    total -= left;
287
224k
  }
288
289
2.45k
  return (0);
290
13.0k
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
32.5k
{
296
32.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
32.5k
  size_t     sap_length;
298
299
32.5k
  if (left < sizeof(*sap)) {
300
13.8k
    log_debug("%s: malformed payload: too short for header "
301
13.8k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.8k
    return (-1);
303
13.8k
  }
304
18.6k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.6k
  sap_length = betoh16(sap->sap_length);
307
18.6k
  if (sap_length < sizeof(*sap)) {
308
5.01k
    log_debug("%s: malformed payload: shorter than minimum header "
309
5.01k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
5.01k
    return (-1);
311
5.01k
  }
312
13.6k
  if (left < sap_length) {
313
2.30k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.30k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.30k
    return (-1);
316
2.30k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
11.3k
  if (!sap->sap_more && left != sap_length) {
322
30
    log_debug("%s: malformed payload: SA payload length mismatches "
323
30
        "single proposal substructure length (%zu != %zu)",
324
30
        __func__, left, sap_length);
325
30
    return (-1);
326
30
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
11.3k
  if (sap->sap_more && left <= sap_length) {
332
839
    log_debug("%s: malformed payload: SA payload too small for "
333
839
        "further proposals (%zu <= %zu)", __func__,
334
839
        left, sap_length);
335
839
    return (-1);
336
839
  }
337
10.5k
  return (0);
338
11.3k
}
339
340
int
341
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
342
    struct iked_message *msg, size_t offset, size_t left)
343
28.1k
{
344
28.1k
  struct ikev2_sa_proposal   sap;
345
28.1k
  struct iked_proposal    *prop = NULL;
346
28.1k
  uint32_t       spi32;
347
28.1k
  uint64_t       spi = 0, spi64;
348
28.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
28.1k
  int        r;
350
28.1k
  struct iked_proposals   *props;
351
28.1k
  size_t         total;
352
353
32.5k
  do {
354
32.5k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
22.0k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.5k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.5k
    props = &msg->msg_parent->msg_proposals;
361
362
10.5k
    offset += sizeof(sap);
363
10.5k
    left -= sizeof(sap);
364
365
10.5k
    if (sap.sap_spisize) {
366
1.40k
      if (left < sap.sap_spisize) {
367
646
        log_debug("%s: malformed payload: SPI larger than "
368
646
            "actual payload (%zu < %d)", __func__, left,
369
646
            sap.sap_spisize);
370
646
        return (-1);
371
646
      }
372
755
      if (total < sap.sap_spisize) {
373
135
        log_debug("%s: malformed payload: SPI larger than "
374
135
            "proposal (%zu < %d)", __func__, total,
375
135
            sap.sap_spisize);
376
135
        return (-1);
377
135
      }
378
620
      switch (sap.sap_spisize) {
379
290
      case 4:
380
290
        memcpy(&spi32, msgbuf + offset, 4);
381
290
        spi = betoh32(spi32);
382
290
        break;
383
200
      case 8:
384
200
        memcpy(&spi64, msgbuf + offset, 8);
385
200
        spi = betoh64(spi64);
386
200
        break;
387
130
      default:
388
130
        log_debug("%s: unsupported SPI size %d",
389
130
            __func__, sap.sap_spisize);
390
130
        return (-1);
391
620
      }
392
393
490
      offset += sap.sap_spisize;
394
490
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
490
      total -= sap.sap_spisize;
398
490
    }
399
400
    /*
401
     * As we verified sanity of packet headers, this check will
402
     * be always false, but just to be sure we keep it.
403
     */
404
9.59k
    if (left < total) {
405
0
      log_debug("%s: malformed payload: too long for payload "
406
0
          "(%zu < %zu)", __func__, left, total);
407
0
      return (-1);
408
0
    }
409
410
9.59k
    log_debug("%s: more %d reserved %d length %d"
411
9.59k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.59k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.59k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.59k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.59k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.59k
    if (ikev2_msg_frompeer(msg)) {
418
69
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
69
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
69
        log_debug("%s: invalid proposal", __func__);
421
69
        return (-1);
422
69
      }
423
0
      prop = msg->msg_parent->msg_prop;
424
0
      prop->prop_peerspi.spi = spi;
425
0
      prop->prop_peerspi.spi_protoid = sap.sap_protoid;
426
0
      prop->prop_peerspi.spi_size = sap.sap_spisize;
427
428
0
      prop->prop_localspi.spi_protoid = sap.sap_protoid;
429
0
      prop->prop_localspi.spi_size = sap.sap_spisize;
430
0
    }
431
432
    /*
433
     * Parse the attached transforms
434
     */
435
9.52k
    if (sap.sap_transforms) {
436
5.44k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.44k
      if ((r == -2) && ikev2_msg_frompeer(msg)) {
438
0
        log_debug("%s: invalid proposal transform",
439
0
            __func__);
440
441
        /* cleanup and ignore proposal */
442
0
        config_free_proposal(props, prop);
443
0
        prop = msg->msg_parent->msg_prop = NULL;
444
5.44k
      } else if (r != 0) {
445
4.37k
        log_debug("%s: invalid proposal transforms",
446
4.37k
            __func__);
447
4.37k
        return (-1);
448
4.37k
      }
449
5.44k
    }
450
451
5.14k
    offset += total;
452
5.14k
    left -= total;
453
5.14k
  } while (sap.sap_more);
454
455
747
  return (0);
456
28.1k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
7.29k
{
462
7.29k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
7.29k
  size_t     xfrm_length;
464
465
7.29k
  if (total < sizeof(*xfrm)) {
466
625
    log_debug("%s: malformed payload: too short for header "
467
625
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
625
    return (-1);
469
625
  }
470
6.67k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.67k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.67k
  if (xfrm_length < sizeof(*xfrm)) {
474
1.12k
    log_debug("%s: malformed payload: shorter than minimum header "
475
1.12k
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
1.12k
    return (-1);
477
1.12k
  }
478
5.54k
  if (total < xfrm_length) {
479
644
    log_debug("%s: malformed payload: too long for payload size "
480
644
        "(%zu < %zu)", __func__, total, xfrm_length);
481
644
    return (-1);
482
644
  }
483
484
4.90k
  return (0);
485
5.54k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
7.29k
{
491
7.29k
  struct ikev2_transform     xfrm;
492
7.29k
  char         id[BUFSIZ];
493
7.29k
  int        ret = 0;
494
7.29k
  int        r;
495
7.29k
  size_t         xfrm_length;
496
497
7.29k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.39k
    return (-1);
499
500
4.90k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.90k
  switch (xfrm.xfrm_type) {
503
1.07k
  case IKEV2_XFORMTYPE_ENCR:
504
1.07k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.07k
        ikev2_xformencr_map), sizeof(id));
506
1.07k
    break;
507
777
  case IKEV2_XFORMTYPE_PRF:
508
777
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
777
        ikev2_xformprf_map), sizeof(id));
510
777
    break;
511
154
  case IKEV2_XFORMTYPE_INTEGR:
512
154
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
154
        ikev2_xformauth_map), sizeof(id));
514
154
    break;
515
567
  case IKEV2_XFORMTYPE_DH:
516
567
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
567
        ikev2_xformdh_map), sizeof(id));
518
567
    break;
519
1.00k
  case IKEV2_XFORMTYPE_ESN:
520
1.00k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
1.00k
        ikev2_xformesn_map), sizeof(id));
522
1.00k
    break;
523
1.32k
  default:
524
1.32k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.32k
    break;
526
4.90k
  }
527
528
4.90k
  log_debug("%s: more %d reserved %d length %zu"
529
4.90k
      " type %s id %s",
530
4.90k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.90k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.90k
  msg->msg_attrlength = 0;
537
4.90k
  if (xfrm_length > sizeof(xfrm)) {
538
2.34k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.34k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.80k
      return (-1);
541
1.80k
    }
542
2.34k
  }
543
544
3.09k
  if (ikev2_msg_frompeer(msg)) {
545
0
    r = config_add_transform(msg->msg_parent->msg_prop,
546
0
        xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
547
0
        msg->msg_attrlength, msg->msg_attrlength);
548
0
    if (r == -1) {
549
0
      log_debug("%s: failed to add transform: alloc error",
550
0
          __func__);
551
0
      return (r);
552
0
    } else if (r == -2) {
553
0
      log_debug("%s: failed to add transform: unknown type",
554
0
          __func__);
555
0
      return (r);
556
0
    }
557
0
  }
558
559
  /* Next transform */
560
3.09k
  offset += xfrm_length;
561
3.09k
  total -= xfrm_length;
562
3.09k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.85k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.24k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
177
    log_debug("%s: less data than specified, %zu bytes left",
567
177
        __func__, total);
568
177
    ret = -1;
569
177
  }
570
571
3.09k
  return (ret);
572
3.09k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
29.4k
{
578
29.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
29.4k
  if (total < sizeof(*attr)) {
581
817
    log_debug("%s: malformed payload: too short for header "
582
817
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
817
    return (-1);
584
817
  }
585
28.6k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.6k
  return (0);
588
29.4k
}
589
590
int
591
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
592
    struct iked_message *msg, size_t offset, size_t total)
593
29.4k
{
594
29.4k
  struct ikev2_attribute     attr;
595
29.4k
  unsigned int       type;
596
29.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
29.4k
  int        ret = 0;
598
29.4k
  size_t         attr_length;
599
600
29.4k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
817
    return (-1);
602
603
28.6k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.6k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.6k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.6k
      betoh16(attr.attr_length), total);
608
609
28.6k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
22.1k
    offset += sizeof(attr);
612
22.1k
    total -= sizeof(attr);
613
614
22.1k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
47
      msg->msg_attrlength = betoh16(attr.attr_length);
616
22.1k
  } else {
617
    /* Type-Length-Value attribute */
618
6.49k
    attr_length = betoh16(attr.attr_length);
619
6.49k
    if (attr_length < sizeof(attr)) {
620
543
      log_debug("%s: malformed payload: shorter than "
621
543
          "minimum header size (%zu < %zu)", __func__,
622
543
          attr_length, sizeof(attr));
623
543
      return (-1);
624
543
    }
625
5.94k
    if (total < attr_length) {
626
443
      log_debug("%s: malformed payload: attribute larger "
627
443
          "than actual payload (%zu < %zu)", __func__,
628
443
          total, attr_length);
629
443
      return (-1);
630
443
    }
631
5.50k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.50k
        attr_length - sizeof(attr));
633
5.50k
    offset += attr_length;
634
5.50k
    total -= attr_length;
635
5.50k
  }
636
637
27.6k
  if (total > 0) {
638
    /* Next attribute */
639
27.0k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
27.0k
  }
641
642
27.6k
  return (ret);
643
28.6k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
8.28k
{
649
8.28k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
8.28k
  if (left < sizeof(*kex)) {
652
5.11k
    log_debug("%s: malformed payload: too short for header "
653
5.11k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
5.11k
    return (-1);
655
5.11k
  }
656
3.16k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
3.16k
  return (0);
659
8.28k
}
660
661
int
662
ikev2_pld_ke(struct iked *env, struct ikev2_payload *pld,
663
    struct iked_message *msg, size_t offset, size_t left)
664
8.28k
{
665
8.28k
  struct ikev2_keyexchange   kex;
666
8.28k
  uint8_t       *buf;
667
8.28k
  size_t         len;
668
8.28k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
8.28k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
5.11k
    return (-1);
672
673
3.16k
  log_debug("%s: dh group %s reserved %d", __func__,
674
3.16k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
3.16k
      betoh16(kex.kex_reserved));
676
677
3.16k
  buf = msgbuf + offset + sizeof(kex);
678
3.16k
  len = left - sizeof(kex);
679
680
3.16k
  if (len == 0) {
681
1.41k
    log_debug("%s: malformed payload: no KE data given", __func__);
682
1.41k
    return (-1);
683
1.41k
  }
684
685
1.75k
  print_hex(buf, 0, len);
686
687
1.75k
  if (ikev2_msg_frompeer(msg)) {
688
27
    if (msg->msg_parent->msg_ke != NULL) {
689
4
      log_info("%s: duplicate KE payload", __func__);
690
4
      return (-1);
691
4
    }
692
23
    if ((msg->msg_parent->msg_ke = ibuf_new(buf, len)) == NULL) {
693
0
      log_debug("%s: failed to get exchange", __func__);
694
0
      return (-1);
695
0
    }
696
23
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
23
  }
698
699
1.74k
  return (0);
700
1.75k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
19.4k
{
706
19.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
19.4k
  if (left < sizeof(*id)) {
709
7.62k
    log_debug("%s: malformed payload: too short for header "
710
7.62k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.62k
    return (-1);
712
7.62k
  }
713
11.8k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.8k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.46k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.46k
        __func__);
718
6.46k
    return (-1);
719
6.46k
  }
720
721
5.38k
  return (0);
722
11.8k
}
723
724
int
725
ikev2_pld_id(struct iked *env, struct ikev2_payload *pld,
726
    struct iked_message *msg, size_t offset, size_t left, unsigned int payload)
727
19.4k
{
728
19.4k
  uint8_t       *ptr;
729
19.4k
  struct ikev2_id      id;
730
19.4k
  size_t         len;
731
19.4k
  struct iked_id      *idp, idb;
732
19.4k
  const struct iked_sa    *sa = msg->msg_sa;
733
19.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
19.4k
  char         idstr[IKED_ID_SIZE];
735
736
19.4k
  if (ikev2_validate_id(msg, offset, left, &id))
737
14.0k
    return (-1);
738
739
5.38k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
5.38k
  ptr = msgbuf + offset;
743
5.38k
  len = left;
744
745
5.38k
  idb.id_type = id.id_type;
746
5.38k
  idb.id_offset = sizeof(id);
747
5.38k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
5.38k
  if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) {
751
0
    ibuf_free(idb.id_buf);
752
0
    log_debug("%s: malformed id", __func__);
753
0
    return (-1);
754
0
  }
755
756
5.38k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
5.38k
  if (!ikev2_msg_frompeer(msg)) {
759
5.28k
    ibuf_free(idb.id_buf);
760
5.28k
    return (0);
761
5.28k
  }
762
763
101
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
101
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
59
    idp = &msg->msg_parent->msg_peerid;
766
42
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
42
    idp = &msg->msg_parent->msg_localid;
768
0
  else {
769
0
    ibuf_free(idb.id_buf);
770
0
    log_debug("%s: unexpected id payload", __func__);
771
0
    return (0);
772
0
  }
773
774
101
  if (idp->id_type) {
775
16
    ibuf_free(idb.id_buf);
776
16
    log_debug("%s: duplicate id payload", __func__);
777
16
    return (-1);
778
16
  }
779
780
85
  idp->id_buf = idb.id_buf;
781
85
  idp->id_offset = idb.id_offset;
782
85
  idp->id_type = idb.id_type;
783
784
85
  return (0);
785
101
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
5.80k
{
791
5.80k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.80k
  if (left < sizeof(*cert)) {
794
1.46k
    log_debug("%s: malformed payload: too short for header "
795
1.46k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.46k
    return (-1);
797
1.46k
  }
798
4.34k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.34k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
982
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
982
    return (-1);
802
982
  }
803
804
3.36k
  return (0);
805
4.34k
}
806
807
int
808
ikev2_pld_cert(struct iked *env, struct ikev2_payload *pld,
809
    struct iked_message *msg, size_t offset, size_t left)
810
5.80k
{
811
5.80k
  struct ikev2_cert    cert;
812
5.80k
  uint8_t       *buf;
813
5.80k
  size_t         len;
814
5.80k
  struct iked_id      *certid;
815
5.80k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.80k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.80k
  int        i;
818
819
5.80k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.44k
    return (-1);
821
3.36k
  offset += sizeof(cert);
822
823
3.36k
  buf = msgbuf + offset;
824
3.36k
  len = left - sizeof(cert);
825
826
3.36k
  log_debug("%s: type %s length %zu",
827
3.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.36k
  print_hex(buf, 0, len);
830
831
3.36k
  if (!ikev2_msg_frompeer(msg))
832
1.41k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.94k
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
290
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
290
       SPI_SA(sa, __func__));
838
290
    return (0);
839
290
  }
840
841
1.65k
  certid = &msg->msg_parent->msg_cert;
842
1.65k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
4.10k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
3.35k
      certid = &msg->msg_parent->msg_scert[i];
846
3.35k
      if (!certid->id_type)
847
605
        break;
848
3.35k
    }
849
1.35k
    if (certid->id_type) {
850
748
      log_debug("%s: too many cert payloads, ignoring",
851
748
         SPI_SA(sa, __func__));
852
748
      return (0);
853
748
    }
854
1.35k
  }
855
856
911
  if ((certid->id_buf = ibuf_new(buf, len)) == NULL) {
857
0
    log_debug("%s: failed to save cert", __func__);
858
0
    return (-1);
859
0
  }
860
911
  certid->id_type = cert.cert_type;
861
911
  certid->id_offset = 0;
862
863
911
  return (0);
864
911
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
12.1k
{
870
12.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
12.1k
  if (left < sizeof(*cert)) {
873
2.65k
    log_debug("%s: malformed payload: too short for header "
874
2.65k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.65k
    return (-1);
876
2.65k
  }
877
9.48k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
9.48k
  return (0);
880
12.1k
}
881
882
int
883
ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
884
    struct iked_message *msg, size_t offset, size_t left)
885
12.1k
{
886
12.1k
  struct ikev2_cert    cert;
887
12.1k
  struct iked_certreq   *cr;
888
12.1k
  uint8_t       *buf;
889
12.1k
  ssize_t        len;
890
12.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
12.1k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.65k
    return (-1);
894
9.48k
  offset += sizeof(cert);
895
896
9.48k
  buf = msgbuf + offset;
897
9.48k
  len = left - sizeof(cert);
898
899
9.48k
  log_debug("%s: type %s length %zd",
900
9.48k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
9.48k
  print_hex(buf, 0, len);
903
904
9.48k
  if (!ikev2_msg_frompeer(msg))
905
8.30k
    return (0);
906
907
1.18k
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
321
    if (len == 0) {
909
279
      log_info("%s: invalid length 0", __func__);
910
279
      return (0);
911
279
    }
912
42
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
9
      log_info("%s: invalid certificate request",
914
9
          __func__);
915
9
      return (-1);
916
9
    }
917
42
  }
918
919
897
  if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) {
920
0
    log_info("%s: failed to allocate certreq.", __func__);
921
0
    return (-1);
922
0
  }
923
897
  if ((cr->cr_data = ibuf_new(buf, len)) == NULL) {
924
0
    log_info("%s: failed to allocate buffer.", __func__);
925
0
    free(cr);
926
0
    return (-1);
927
0
  }
928
897
  cr->cr_type = cert.cert_type;
929
897
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
897
  return (0);
932
897
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
8.17k
{
938
8.17k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
8.17k
  if (left < sizeof(*auth)) {
941
1.85k
    log_debug("%s: malformed payload: too short for header "
942
1.85k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.85k
    return (-1);
944
1.85k
  }
945
6.31k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.31k
  if (auth->auth_method == 0) {
948
3.36k
    log_info("%s: malformed payload: invalid auth method",
949
3.36k
        __func__);
950
3.36k
    return (-1);
951
3.36k
  }
952
953
2.95k
  return (0);
954
6.31k
}
955
956
int
957
ikev2_pld_auth(struct iked *env, struct ikev2_payload *pld,
958
    struct iked_message *msg, size_t offset, size_t left)
959
8.17k
{
960
8.17k
  struct ikev2_auth    auth;
961
8.17k
  struct iked_id      *idp;
962
8.17k
  uint8_t       *buf;
963
8.17k
  size_t         len;
964
8.17k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
8.17k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.21k
    return (-1);
968
2.95k
  offset += sizeof(auth);
969
970
2.95k
  buf = msgbuf + offset;
971
2.95k
  len = left - sizeof(auth);
972
973
2.95k
  log_debug("%s: method %s length %zu",
974
2.95k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.95k
  print_hex(buf, 0, len);
977
978
2.95k
  if (!ikev2_msg_frompeer(msg))
979
2.91k
    return (0);
980
981
42
  idp = &msg->msg_parent->msg_auth;
982
42
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
41
  ibuf_free(idp->id_buf);
988
41
  idp->id_type = auth.auth_method;
989
41
  idp->id_offset = 0;
990
41
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
41
  return (0);
994
41
}
995
996
int
997
ikev2_pld_nonce(struct iked *env, struct ikev2_payload *pld,
998
    struct iked_message *msg, size_t offset, size_t left)
999
242
{
1000
242
  size_t     len;
1001
242
  uint8_t   *buf;
1002
242
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
242
  buf = msgbuf + offset;
1005
242
  len = left;
1006
1007
242
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
160
  print_hex(buf, 0, len);
1013
1014
160
  if (ikev2_msg_frompeer(msg)) {
1015
61
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
42
    if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) {
1020
0
      log_debug("%s: failed to get peer nonce", __func__);
1021
0
      return (-1);
1022
0
    }
1023
42
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
42
  }
1025
1026
141
  return (0);
1027
160
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
32.0k
{
1033
32.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
32.0k
  if (left < sizeof(*n)) {
1036
3.51k
    log_debug("%s: malformed payload: too short for header "
1037
3.51k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.51k
    return (-1);
1039
3.51k
  }
1040
28.5k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
28.5k
  return (0);
1043
32.0k
}
1044
1045
int
1046
ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
1047
    struct iked_message *msg, size_t offset, size_t left)
1048
32.0k
{
1049
32.0k
  struct ikev2_notify  n;
1050
32.0k
  const struct iked_sa  *sa = msg->msg_sa;
1051
32.0k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
32.0k
  uint32_t     spi32;
1053
32.0k
  uint64_t     spi64;
1054
32.0k
  struct iked_spi   *rekey;
1055
32.0k
  uint16_t     type;
1056
32.0k
  uint16_t     signature_hash;
1057
1058
32.0k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.51k
    return (-1);
1060
28.5k
  type = betoh16(n.n_type);
1061
1062
28.5k
  log_debug("%s: protoid %s spisize %d type %s",
1063
28.5k
      __func__,
1064
28.5k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
28.5k
      print_map(type, ikev2_n_map));
1066
1067
28.5k
  left -= sizeof(n);
1068
28.5k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
28.5k
  print_hex(buf, 0, left);
1072
1073
28.5k
  if (!ikev2_msg_frompeer(msg))
1074
1.44k
    return (0);
1075
1076
27.0k
  switch (type) {
1077
3.05k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
22.6k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
22.6k
    if (left != sizeof(md)) {
1080
16
      log_debug("%s: malformed payload: hash size mismatch"
1081
16
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
16
      return (-1);
1083
16
    }
1084
22.6k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
22.6k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
22.6k
    if (memcmp(buf, md, left) != 0) {
1088
22.6k
      log_debug("%s: %s detected NAT", __func__,
1089
22.6k
          print_map(type, ikev2_n_map));
1090
22.6k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
3.04k
        msg->msg_parent->msg_nat_detected
1092
3.04k
            |= IKED_MSG_NAT_SRC_IP;
1093
19.5k
      else
1094
19.5k
        msg->msg_parent->msg_nat_detected
1095
19.5k
            |= IKED_MSG_NAT_DST_IP;
1096
22.6k
    }
1097
22.6k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
22.6k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
22.6k
    break;
1101
6
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
6
    if (!msg->msg_e) {
1103
0
      log_debug("%s: AUTHENTICATION_FAILED not encrypted",
1104
0
          __func__);
1105
0
      return (-1);
1106
0
    }
1107
    /*
1108
     * If we are the responder, then we only accept
1109
     * AUTHENTICATION_FAILED from authenticated peers.
1110
     * If we are the initiator, the peer cannot be authenticated.
1111
     */
1112
6
    if (!sa->sa_hdr.sh_initiator) {
1113
6
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
6
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
6
            " from unauthenticated initiator",
1116
6
            __func__);
1117
6
        return (-1);
1118
6
      }
1119
6
    } else {
1120
0
      if (sa_stateok(sa, IKEV2_STATE_VALID)) {
1121
0
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1122
0
            " from authenticated responder",
1123
0
            __func__);
1124
0
        return (-1);
1125
0
      }
1126
0
    }
1127
0
    msg->msg_parent->msg_flags
1128
0
        |= IKED_MSG_FLAGS_AUTHENTICATION_FAILED;
1129
0
    break;
1130
135
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
135
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
135
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
135
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
4
      log_debug("%s: malformed payload: group size mismatch"
1139
4
          " (%zu != %zu)", __func__, left,
1140
4
          sizeof(msg->msg_parent->msg_group));
1141
4
      return (-1);
1142
4
    }
1143
131
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
131
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
131
    break;
1146
241
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
241
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
241
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
241
    break;
1154
75
  case IKEV2_N_REKEY_SA:
1155
75
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
75
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
70
    rekey = &msg->msg_parent->msg_rekey;
1164
70
    if (rekey->spi != 0) {
1165
5
      log_debug("%s: rekeying of multiple SAs not supported",
1166
5
          __func__);
1167
5
      return (-1);
1168
5
    }
1169
65
    switch (n.n_spisize) {
1170
59
    case 4:
1171
59
      memcpy(&spi32, buf, left);
1172
59
      rekey->spi = betoh32(spi32);
1173
59
      break;
1174
3
    case 8:
1175
3
      memcpy(&spi64, buf, left);
1176
3
      rekey->spi = betoh64(spi64);
1177
3
      break;
1178
3
    default:
1179
3
      log_debug("%s: invalid spi size %d", __func__,
1180
3
          n.n_spisize);
1181
3
      return (-1);
1182
65
    }
1183
62
    rekey->spi_size = n.n_spisize;
1184
62
    rekey->spi_protoid = n.n_protoid;
1185
1186
62
    log_debug("%s: rekey %s spi %s", __func__,
1187
62
        print_map(n.n_protoid, ikev2_saproto_map),
1188
62
        print_spi(rekey->spi, n.n_spisize));
1189
62
    break;
1190
348
  case IKEV2_N_TEMPORARY_FAILURE:
1191
348
    if (!msg->msg_e) {
1192
0
      log_debug("%s: IKEV2_N_TEMPORARY_FAILURE not encrypted",
1193
0
          __func__);
1194
0
      return (-1);
1195
0
    }
1196
348
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
348
    break;
1198
255
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
255
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
255
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
255
        sizeof(msg->msg_parent->msg_transform)) {
1206
127
      log_debug("%s: ignoring malformed ipcomp notification",
1207
127
          __func__);
1208
127
      return (0);
1209
127
    }
1210
128
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
128
        sizeof(msg->msg_parent->msg_cpi));
1212
128
    memcpy(&msg->msg_parent->msg_transform,
1213
128
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
128
        sizeof(msg->msg_parent->msg_transform));
1215
1216
128
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
128
        msg->msg_parent->msg_response ? "res" : "req",
1218
128
        betoh16(msg->msg_parent->msg_cpi),
1219
128
        print_map(msg->msg_parent->msg_transform,
1220
128
        ikev2_ipcomp_map), left);
1221
1222
128
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
128
    break;
1224
73
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
73
    if (!msg->msg_e) {
1226
0
      log_debug("%s: N_CHILD_SA_NOT_FOUND not encrypted",
1227
0
          __func__);
1228
0
      return (-1);
1229
0
    }
1230
73
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
73
    break;
1232
36
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
36
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
36
    break;
1235
267
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
267
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
267
    if (left != 0) {
1242
131
      log_debug("%s: ignoring malformed mobike"
1243
131
          " notification: %zu", __func__, left);
1244
131
      return (0);
1245
131
    }
1246
136
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
136
    break;
1248
316
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
316
    if (!msg->msg_e) {
1250
0
      log_debug("%s: N_USE_TRANSPORT_MODE not encrypted",
1251
0
          __func__);
1252
0
      return (-1);
1253
0
    }
1254
316
    if (left != 0) {
1255
77
      log_debug("%s: ignoring malformed transport mode"
1256
77
          " notification: %zu", __func__, left);
1257
77
      return (0);
1258
77
    }
1259
239
    if (msg->msg_parent->msg_response) {
1260
0
      if (!(msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT)) {
1261
0
        log_debug("%s: ignoring transport mode"
1262
0
            " notification (policy)", __func__);
1263
0
        return (0);
1264
0
      }
1265
0
    }
1266
239
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
239
    break;
1268
388
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
388
    if (!msg->msg_e) {
1270
0
      log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted",
1271
0
          __func__);
1272
0
      return (-1);
1273
0
    }
1274
388
    if (!sa->sa_mobike) {
1275
388
      log_debug("%s: ignoring update sa addresses"
1276
388
          " notification w/o mobike: %zu", __func__, left);
1277
388
      return (0);
1278
388
    }
1279
0
    if (left != 0) {
1280
0
      log_debug("%s: ignoring malformed update sa addresses"
1281
0
          " notification: %zu", __func__, left);
1282
0
      return (0);
1283
0
    }
1284
0
    msg->msg_parent->msg_update_sa_addresses = 1;
1285
0
    break;
1286
202
  case IKEV2_N_COOKIE2:
1287
202
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
202
    if (!sa->sa_mobike) {
1293
202
      log_debug("%s: ignoring cookie2 notification"
1294
202
          " w/o mobike: %zu", __func__, left);
1295
202
      return (0);
1296
202
    }
1297
0
    if (left < IKED_COOKIE2_MIN || left > IKED_COOKIE2_MAX) {
1298
0
      log_debug("%s: ignoring malformed cookie2"
1299
0
          " notification: %zu", __func__, left);
1300
0
      return (0);
1301
0
    }
1302
0
    ibuf_free(msg->msg_cookie2);  /* should not happen */
1303
0
    if ((msg->msg_cookie2 = ibuf_new(buf, left)) == NULL) {
1304
0
      log_debug("%s: failed to get peer cookie2", __func__);
1305
0
      return (-1);
1306
0
    }
1307
0
    msg->msg_parent->msg_cookie2 = msg->msg_cookie2;
1308
0
    break;
1309
2
  case IKEV2_N_COOKIE:
1310
2
    if (msg->msg_e) {
1311
2
      log_debug("%s: N_COOKIE encrypted",
1312
2
          __func__);
1313
2
      return (-1);
1314
2
    }
1315
0
    if (left < IKED_COOKIE_MIN || left > IKED_COOKIE_MAX) {
1316
0
      log_debug("%s: ignoring malformed cookie"
1317
0
          " notification: %zu", __func__, left);
1318
0
      return (0);
1319
0
    }
1320
0
    log_debug("%s: received cookie, len %zu", __func__, left);
1321
0
    print_hex(buf, 0, left);
1322
1323
0
    ibuf_free(msg->msg_cookie);
1324
0
    if ((msg->msg_cookie = ibuf_new(buf, left)) == NULL) {
1325
0
      log_debug("%s: failed to get peer cookie", __func__);
1326
0
      return (-1);
1327
0
    }
1328
0
    msg->msg_parent->msg_cookie = msg->msg_cookie;
1329
0
    break;
1330
14
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
14
    if (msg->msg_e) {
1332
14
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
14
          __func__);
1334
14
      return (-1);
1335
14
    }
1336
0
    if (left != 0) {
1337
0
      log_debug("%s: ignoring malformed fragmentation"
1338
0
          " notification: %zu", __func__, left);
1339
0
      return (0);
1340
0
    }
1341
0
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_FRAGMENTATION;
1342
0
    break;
1343
7
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
7
    if (msg->msg_e) {
1345
7
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
7
          __func__);
1347
7
      return (-1);
1348
7
    }
1349
0
    if (sa == NULL) {
1350
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: no SA",
1351
0
          __func__);
1352
0
      return (-1);
1353
0
    }
1354
0
    if (sa->sa_sigsha2) {
1355
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: "
1356
0
          "duplicate notify", __func__);
1357
0
      return (0);
1358
0
    }
1359
0
    if (left < sizeof(signature_hash) ||
1360
0
        left % sizeof(signature_hash)) {
1361
0
      log_debug("%s: malformed signature hash notification"
1362
0
          "(%zu bytes)", __func__, left);
1363
0
      return (0);
1364
0
    }
1365
0
    while (left >= sizeof(signature_hash)) {
1366
0
      memcpy(&signature_hash, buf, sizeof(signature_hash));
1367
0
      signature_hash = betoh16(signature_hash);
1368
0
      log_debug("%s: signature hash %s (%x)", __func__,
1369
0
          print_map(signature_hash, ikev2_sighash_map),
1370
0
          signature_hash);
1371
0
      left -= sizeof(signature_hash);
1372
0
      buf += sizeof(signature_hash);
1373
0
      if (signature_hash == IKEV2_SIGHASH_SHA2_256)
1374
0
        msg->msg_parent->msg_flags
1375
0
            |= IKED_MSG_FLAGS_SIGSHA2;
1376
0
    }
1377
0
    break;
1378
27.0k
  }
1379
1380
26.0k
  return (0);
1381
27.0k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
7.11k
{
1387
7.11k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
7.11k
  if (left < sizeof(*del)) {
1390
1.39k
    log_debug("%s: malformed payload: too short for header "
1391
1.39k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.39k
    return (-1);
1393
1.39k
  }
1394
5.72k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.72k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.63k
  return (0);
1402
5.72k
}
1403
1404
int
1405
ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
1406
    struct iked_message *msg, size_t offset, size_t left)
1407
7.11k
{
1408
7.11k
  struct ikev2_delete  del;
1409
7.11k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
7.11k
  size_t       cnt, sz, len;
1411
1412
7.11k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.47k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.63k
  if (ikev2_msg_frompeer(msg) &&
1417
5.63k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.63k
  cnt = betoh16(del.del_nspi);
1421
5.63k
  sz = del.del_spisize;
1422
1423
5.63k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.63k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.63k
      sz, cnt);
1426
1427
5.63k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.32k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.32k
    return (0);
1430
5.32k
  }
1431
1432
315
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
315
  msg->msg_parent->msg_del_cnt = cnt;
1434
315
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
315
  buf = msgbuf + offset + sizeof(del);
1437
315
  len = left - sizeof(del);
1438
315
  if (len == 0 || sz == 0 || cnt == 0)
1439
292
    return (0);
1440
1441
23
  if ((len / sz) != cnt) {
1442
21
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
21
        __func__, len, sz, cnt);
1444
21
    return (-1);
1445
21
  }
1446
1447
2
  print_hex(buf, 0, len);
1448
1449
2
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
2
  return (0);
1452
23
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
18.0k
{
1458
18.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
18.0k
  if (left < sizeof(*tsp)) {
1461
2.39k
    log_debug("%s: malformed payload: too short for header "
1462
2.39k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.39k
    return (-1);
1464
2.39k
  }
1465
15.6k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
15.6k
  return (0);
1468
18.0k
}
1469
1470
int
1471
ikev2_pld_tss(struct iked *env, struct ikev2_payload *pld,
1472
    struct iked_message *msg, size_t offset, size_t left)
1473
18.0k
{
1474
18.0k
  struct ikev2_tsp     tsp;
1475
18.0k
  struct ikev2_ts      ts;
1476
18.0k
  size_t         ts_len, i;
1477
1478
18.0k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.39k
    return (-1);
1480
1481
15.6k
  offset += sizeof(tsp);
1482
15.6k
  left -= sizeof(tsp);
1483
1484
15.6k
  log_debug("%s: count %d length %zu", __func__,
1485
15.6k
      tsp.tsp_count, left);
1486
1487
30.8k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
29.2k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
12.3k
      return (-1);
1490
1491
16.8k
    log_debug("%s: type %s protoid %u length %d "
1492
16.8k
        "startport %u endport %u", __func__,
1493
16.8k
        print_map(ts.ts_type, ikev2_ts_map),
1494
16.8k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
16.8k
        betoh16(ts.ts_startport),
1496
16.8k
        betoh16(ts.ts_endport));
1497
1498
16.8k
    offset += sizeof(ts);
1499
16.8k
    left -= sizeof(ts);
1500
1501
16.8k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
16.8k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.68k
      return (-1);
1504
1505
15.1k
    offset += ts_len;
1506
15.1k
    left -= ts_len;
1507
15.1k
  }
1508
1509
1.59k
  return (0);
1510
15.6k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
29.2k
{
1516
29.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
29.2k
  size_t     ts_length;
1518
1519
29.2k
  if (left < sizeof(*ts)) {
1520
11.2k
    log_debug("%s: malformed payload: too short for header "
1521
11.2k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
11.2k
    return (-1);
1523
11.2k
  }
1524
18.0k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
18.0k
  ts_length = betoh16(ts->ts_length);
1527
18.0k
  if (ts_length < sizeof(*ts)) {
1528
312
    log_debug("%s: malformed payload: shorter than minimum header "
1529
312
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
312
    return (-1);
1531
312
  }
1532
17.7k
  if (left < ts_length) {
1533
864
    log_debug("%s: malformed payload: too long for payload size "
1534
864
        "(%zu < %zu)", __func__, left, ts_length);
1535
864
    return (-1);
1536
864
  }
1537
1538
16.8k
  return (0);
1539
17.7k
}
1540
1541
int
1542
ikev2_pld_ts(struct iked *env, struct ikev2_payload *pld,
1543
    struct iked_message *msg, size_t offset, size_t left, unsigned int type)
1544
16.8k
{
1545
16.8k
  struct sockaddr_in     start4, end4;
1546
16.8k
  struct sockaddr_in6    start6, end6;
1547
16.8k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
16.8k
  uint8_t       *ptr;
1549
1550
16.8k
  ptr = msgbuf + offset;
1551
1552
16.8k
  switch (type) {
1553
6.12k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
6.12k
    if (left < 2 * 4) {
1555
323
      log_debug("%s: malformed payload: too short "
1556
323
          "for ipv4 addr range (%zu < %u)",
1557
323
          __func__, left, 2 * 4);
1558
323
      return (-1);
1559
323
    }
1560
1561
5.80k
    bzero(&start4, sizeof(start4));
1562
5.80k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
5.80k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
5.80k
    ptr += 4;
1568
5.80k
    left -= 4;
1569
1570
5.80k
    bzero(&end4, sizeof(end4));
1571
5.80k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
5.80k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
5.80k
    left -= 4;
1577
1578
5.80k
    log_debug("%s: start %s end %s", __func__,
1579
5.80k
        print_addr(&start4), print_addr(&end4));
1580
5.80k
    break;
1581
1.35k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.35k
    if (left < 2 * 16) {
1583
252
      log_debug("%s: malformed payload: too short "
1584
252
          "for ipv6 addr range (%zu < %u)",
1585
252
          __func__, left, 2 * 16);
1586
252
      return (-1);
1587
252
    }
1588
1.09k
    bzero(&start6, sizeof(start6));
1589
1.09k
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
1.09k
    memcpy(&start6.sin6_addr, ptr, 16);
1594
1.09k
    ptr += 16;
1595
1.09k
    left -= 16;
1596
1597
1.09k
    bzero(&end6, sizeof(end6));
1598
1.09k
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
1.09k
    memcpy(&end6.sin6_addr, ptr, 16);
1603
1.09k
    left -= 16;
1604
1605
1.09k
    log_debug("%s: start %s end %s", __func__,
1606
1.09k
        print_addr(&start6), print_addr(&end6));
1607
1.09k
    break;
1608
9.40k
  default:
1609
9.40k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
9.40k
    return (0);
1611
16.8k
  }
1612
1613
6.90k
  if (left > 0) {
1614
1.10k
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
1.10k
        __func__, left);
1616
1.10k
    return (-1);
1617
1.10k
  }
1618
1619
5.79k
  return (0);
1620
6.90k
}
1621
1622
int
1623
ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
1624
    struct iked_message *msg, size_t offset, size_t left)
1625
0
{
1626
0
  struct iked_sa      *sa = msg->msg_sa;
1627
0
  struct iked_frag    *sa_frag = &sa->sa_fragments;
1628
0
  struct iked_frag_entry    *el;
1629
0
  struct ikev2_frag_payload  frag;
1630
0
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1631
0
  uint8_t       *buf;
1632
0
  struct ibuf     *e = NULL;
1633
0
  size_t         frag_num, frag_total;
1634
0
  size_t         len;
1635
0
  int        ret = -1;
1636
0
  int        processed = 0;
1637
0
  ssize_t        elen;
1638
1639
0
  buf = msgbuf + offset;
1640
0
  memcpy(&frag, buf, sizeof(frag));
1641
0
  frag_num = betoh16(frag.frag_num);
1642
0
  frag_total = betoh16(frag.frag_total);
1643
1644
0
  offset += sizeof(frag);
1645
0
  buf = msgbuf + offset;
1646
0
  len = left - sizeof(frag);
1647
1648
0
  ikestat_inc(env, ikes_frag_rcvd);
1649
1650
  /* Limit number of total fragments to avoid DOS */
1651
0
  if (frag_total > IKED_FRAG_TOTAL_MAX ) {
1652
0
    log_debug("%s: Total Fragments too big  %zu",
1653
0
        __func__, frag_total);
1654
0
    goto dropall;
1655
0
  }
1656
1657
  /* Check sanity of fragment header */
1658
0
  if (frag_num == 0 || frag_total == 0) {
1659
0
    log_debug("%s: Malformed fragment received: %zu of %zu",
1660
0
        __func__, frag_num, frag_total);
1661
0
    goto done;
1662
0
  }
1663
0
  log_debug("%s: Received fragment: %zu of %zu",
1664
0
      __func__, frag_num, frag_total);
1665
1666
  /* Drop fragment if frag_num and frag_total don't match */
1667
0
  if (frag_num > frag_total)
1668
0
    goto done;
1669
1670
  /* Decrypt fragment */
1671
0
  if ((e = ibuf_new(buf, len)) == NULL)
1672
0
    goto done;
1673
1674
0
  if ((e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e))
1675
0
      == NULL ) {
1676
0
    log_debug("%s: Failed to decrypt fragment: %zu of %zu",
1677
0
        __func__, frag_num, frag_total);
1678
0
    goto done;
1679
0
  }
1680
0
  elen = ibuf_size(e);
1681
1682
  /* Check new fragmented message */
1683
0
  if (sa_frag->frag_arr == NULL) {
1684
0
    sa_frag->frag_arr = recallocarray(NULL, 0, frag_total,
1685
0
        sizeof(struct iked_frag_entry*));
1686
0
    if (sa_frag->frag_arr == NULL) {
1687
0
      log_info("%s: recallocarray sa_frag->frag_arr.", __func__);
1688
0
      goto done;
1689
0
    }
1690
0
    sa_frag->frag_total = frag_total;
1691
0
  } else {
1692
    /* Drop all fragments if frag_total doesn't match previous */
1693
0
    if (frag_total != sa_frag->frag_total)
1694
0
      goto dropall;
1695
1696
    /* Silent drop if fragment already stored */
1697
0
    if (sa_frag->frag_arr[frag_num-1] != NULL)
1698
0
      goto done;
1699
0
  }
1700
1701
  /* The first fragments IKE header determines pld_nextpayload */
1702
0
  if (frag_num == 1)
1703
0
    sa_frag->frag_nextpayload = pld->pld_nextpayload;
1704
1705
  /* Insert new list element */
1706
0
  el = calloc(1, sizeof(struct iked_frag_entry));
1707
0
  if (el == NULL) {
1708
0
    log_info("%s: Failed allocating new fragment: %zu of %zu",
1709
0
        __func__, frag_num, frag_total);
1710
0
    goto done;
1711
0
  }
1712
1713
0
  sa_frag->frag_arr[frag_num-1] = el;
1714
0
  el->frag_size = elen;
1715
0
  el->frag_data = calloc(1, elen);
1716
0
  if (el->frag_data == NULL) {
1717
0
    log_debug("%s: Failed allocating new fragment data: %zu of %zu",
1718
0
        __func__, frag_num, frag_total);
1719
0
    goto done;
1720
0
  }
1721
1722
  /* Copy plaintext to fragment */
1723
0
  memcpy(el->frag_data, ibuf_seek(e, 0, 0), elen);
1724
0
  sa_frag->frag_total_size += elen;
1725
0
  sa_frag->frag_count++;
1726
1727
  /* If all frags are received start reassembly */
1728
0
  if (sa_frag->frag_count == sa_frag->frag_total) {
1729
0
    log_debug("%s: All fragments received: %zu of %zu",
1730
0
        __func__, frag_num, frag_total);
1731
0
    ret = ikev2_frags_reassemble(env, pld, msg);
1732
0
  } else {
1733
0
    ret = 0;
1734
0
  }
1735
0
  processed = 1;
1736
1737
0
done:
1738
0
  if (!processed)
1739
0
    ikestat_inc(env, ikes_frag_rcvd_drop);
1740
0
  ibuf_free(e);
1741
0
  return (ret);
1742
0
dropall:
1743
0
  ikestat_add(env, ikes_frag_rcvd_drop, sa_frag->frag_count + 1);
1744
0
  config_free_fragments(sa_frag);
1745
0
  ibuf_free(e);
1746
0
  return -1;
1747
0
}
1748
1749
int
1750
ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
1751
    struct iked_message *msg)
1752
0
{
1753
0
  struct iked_frag    *sa_frag = &msg->msg_sa->sa_fragments;
1754
0
  struct ibuf     *e = NULL;
1755
0
  struct iked_frag_entry    *el;
1756
0
  uint8_t       *ptr;
1757
0
  size_t         offset;
1758
0
  size_t         i;
1759
0
  struct iked_message    emsg;
1760
0
  int        ret = -1;
1761
0
  int        processed = 0;
1762
1763
  /* Reassemble fragments to single buffer */
1764
0
  if ((e = ibuf_new(NULL, sa_frag->frag_total_size)) == NULL) {
1765
0
    log_debug("%s: Failed allocating SK buffer.", __func__);
1766
0
    goto done;
1767
0
  }
1768
1769
  /* Empty queue to new buffer */
1770
0
  offset = 0;
1771
0
  for (i = 0; i < sa_frag->frag_total; i++) {
1772
0
    if ((el = sa_frag->frag_arr[i]) == NULL)
1773
0
      fatalx("Tried to reassemble shallow frag_arr");
1774
0
    ptr = ibuf_seek(e, offset, el->frag_size);
1775
0
    if (ptr == NULL) {
1776
0
      log_info("%s: failed to reassemble fragments", __func__);
1777
0
      goto done;
1778
0
    }
1779
0
    memcpy(ptr, el->frag_data, el->frag_size);
1780
0
    offset += el->frag_size;
1781
0
  }
1782
1783
0
  log_debug("%s: Defragmented length %zd", __func__,
1784
0
      sa_frag->frag_total_size);
1785
0
  print_hex(ibuf_data(e), 0,  sa_frag->frag_total_size);
1786
1787
  /* Drop the original request's packets from the retransmit queue */
1788
0
  if (msg->msg_response)
1789
0
    ikev2_msg_dispose(env, &msg->msg_sa->sa_requests,
1790
0
        ikev2_msg_lookup(env, &msg->msg_sa->sa_requests, msg,
1791
0
        msg->msg_exchange));
1792
1793
  /*
1794
   * Parse decrypted payload
1795
   */
1796
0
  bzero(&emsg, sizeof(emsg));
1797
0
  memcpy(&emsg, msg, sizeof(*msg));
1798
0
  emsg.msg_data = e;
1799
0
  emsg.msg_e = 1;
1800
0
  emsg.msg_parent = msg;
1801
0
  TAILQ_INIT(&emsg.msg_proposals);
1802
1803
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1804
0
      sa_frag->frag_nextpayload);
1805
0
  processed = 1;
1806
0
done:
1807
0
  if (processed)
1808
0
    ikestat_add(env, ikes_frag_reass_ok, sa_frag->frag_total);
1809
0
  else
1810
0
    ikestat_add(env, ikes_frag_reass_drop, sa_frag->frag_total);
1811
0
  config_free_fragments(sa_frag);
1812
0
  ibuf_free(e);
1813
1814
0
  return (ret);
1815
0
}
1816
1817
int
1818
ikev2_pld_e(struct iked *env, struct ikev2_payload *pld,
1819
    struct iked_message *msg, size_t offset, size_t left)
1820
0
{
1821
0
  struct iked_sa    *sa = msg->msg_sa;
1822
0
  struct ibuf   *e = NULL;
1823
0
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1824
0
  struct iked_message  emsg;
1825
0
  uint8_t     *buf;
1826
0
  size_t       len;
1827
0
  int      ret = -1;
1828
1829
0
  if (sa->sa_fragments.frag_arr != NULL) {
1830
0
    log_warn("%s: Received SK payload when SKFs are in queue.",
1831
0
        __func__);
1832
0
    config_free_fragments(&sa->sa_fragments);
1833
0
    return (ret);
1834
0
  }
1835
1836
0
  buf = msgbuf + offset;
1837
0
  len = left;
1838
1839
0
  if ((e = ibuf_new(buf, len)) == NULL)
1840
0
    goto done;
1841
1842
0
  if (ikev2_msg_frompeer(msg)) {
1843
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1844
0
  } else {
1845
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1846
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1847
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1848
0
  }
1849
1850
0
  if (e == NULL)
1851
0
    goto done;
1852
1853
  /*
1854
   * Parse decrypted payload
1855
   */
1856
0
  bzero(&emsg, sizeof(emsg));
1857
0
  memcpy(&emsg, msg, sizeof(*msg));
1858
0
  emsg.msg_data = e;
1859
0
  emsg.msg_e = 1;
1860
0
  emsg.msg_parent = msg;
1861
0
  TAILQ_INIT(&emsg.msg_proposals);
1862
1863
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1864
0
      pld->pld_nextpayload);
1865
1866
0
 done:
1867
0
  ibuf_free(e);
1868
1869
0
  return (ret);
1870
0
}
1871
1872
int
1873
ikev2_validate_cp(struct iked_message *msg, size_t offset, size_t left,
1874
    struct ikev2_cp *cp)
1875
9.77k
{
1876
9.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
9.77k
  if (left < sizeof(*cp)) {
1879
3.14k
    log_debug("%s: malformed payload: too short for header "
1880
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
3.14k
    return (-1);
1882
3.14k
  }
1883
6.63k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
6.63k
  return (0);
1886
9.77k
}
1887
1888
int
1889
ikev2_pld_cp(struct iked *env, struct ikev2_payload *pld,
1890
    struct iked_message *msg, size_t offset, size_t left)
1891
9.77k
{
1892
9.77k
  struct ikev2_cp    cp;
1893
9.77k
  struct ikev2_cfg  *cfg;
1894
9.77k
  struct iked_addr  *addr;
1895
9.77k
  struct sockaddr_in  *in4;
1896
9.77k
  struct sockaddr_in6 *in6;
1897
9.77k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
9.77k
  uint8_t     *ptr;
1899
9.77k
  size_t       len;
1900
9.77k
  int      cfg_type;
1901
1902
9.77k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
3.14k
    return (-1);
1904
1905
6.63k
  ptr = msgbuf + offset + sizeof(cp);
1906
6.63k
  len = left - sizeof(cp);
1907
1908
6.63k
  log_debug("%s: type %s length %zu",
1909
6.63k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
6.63k
  print_hex(ptr, 0, len);
1911
1912
14.4k
  while (len > 0) {
1913
9.33k
    if (len < sizeof(*cfg)) {
1914
352
      log_debug("%s: malformed payload: too short for cfg "
1915
352
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
352
      return (-1);
1917
352
    }
1918
8.98k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.98k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.98k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.98k
        betoh16(cfg->cfg_type),
1923
8.98k
        betoh16(cfg->cfg_length));
1924
1925
8.98k
    ptr += sizeof(*cfg);
1926
8.98k
    len -= sizeof(*cfg);
1927
1928
8.98k
    if (len < betoh16(cfg->cfg_length)) {
1929
1.12k
      log_debug("%s: malformed payload: too short for "
1930
1.12k
          "cfg_length (%zu < %u)", __func__, len,
1931
1.12k
          betoh16(cfg->cfg_length));
1932
1.12k
      return (-1);
1933
1.12k
    }
1934
1935
7.85k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.85k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.85k
    switch (cfg_type) {
1939
844
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.50k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.50k
      if (!ikev2_msg_frompeer(msg))
1942
735
        break;
1943
769
      if (betoh16(cfg->cfg_length) == 0)
1944
309
        break;
1945
      /* XXX multiple-valued */
1946
460
      if (betoh16(cfg->cfg_length) < 4) {
1947
6
        log_debug("%s: malformed payload: too short "
1948
6
            "for ipv4 addr (%u < %u)",
1949
6
            __func__, betoh16(cfg->cfg_length), 4);
1950
6
        return (-1);
1951
6
      }
1952
454
      switch(cfg_type) {
1953
355
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
355
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
238
          log_debug("%s: address already set", __func__);
1956
238
          goto skip;
1957
238
        }
1958
117
        break;
1959
117
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
99
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
51
          log_debug("%s: dns already set", __func__);
1962
51
          goto skip;
1963
51
        }
1964
48
        break;
1965
48
      default:
1966
0
        break;
1967
454
      }
1968
165
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
165
      addr->addr_af = AF_INET;
1973
165
      in4 = (struct sockaddr_in *)&addr->addr;
1974
165
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
165
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
165
      switch(cfg_type) {
1980
117
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
117
        msg->msg_parent->msg_cp_addr = addr;
1982
117
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
117
            print_addr(&addr->addr));
1984
117
        break;
1985
48
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
48
        msg->msg_parent->msg_cp_dns = addr;
1987
48
        log_debug("%s: IP4_DNS %s", __func__,
1988
48
            print_addr(&addr->addr));
1989
48
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
165
      }
1995
165
      break;
1996
2.25k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
3.05k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
3.05k
      if (!ikev2_msg_frompeer(msg))
1999
2.86k
        break;
2000
198
      if (betoh16(cfg->cfg_length) == 0)
2001
67
        break;
2002
      /* XXX multiple-valued */
2003
131
      if (betoh16(cfg->cfg_length) < 16) {
2004
4
        log_debug("%s: malformed payload: too short "
2005
4
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
4
            __func__, betoh16(cfg->cfg_length), 16);
2007
4
        return (-1);
2008
4
      }
2009
127
      switch(cfg_type) {
2010
87
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
87
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
40
        break;
2016
40
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
40
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
36
          log_debug("%s: dns already set", __func__);
2019
36
          goto skip;
2020
36
        }
2021
4
        break;
2022
127
      }
2023
44
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
44
      addr->addr_af = AF_INET6;
2028
44
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
44
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
44
      memcpy(&in6->sin6_addr, ptr, 16);
2034
44
      switch(cfg_type) {
2035
40
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
40
        msg->msg_parent->msg_cp_addr6 = addr;
2037
40
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
40
            print_addr(&addr->addr));
2039
40
        break;
2040
4
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
4
        msg->msg_parent->msg_cp_dns = addr;
2042
4
        log_debug("%s: IP6_DNS %s", __func__,
2043
4
            print_addr(&addr->addr));
2044
4
        break;
2045
0
      default:
2046
0
        log_debug("%s: cfg %s/%d", __func__,
2047
0
            print_addr(&addr->addr), ptr[16]);
2048
0
        break;
2049
44
      }
2050
44
      break;
2051
7.85k
    }
2052
2053
7.84k
 skip:
2054
7.84k
    ptr += betoh16(cfg->cfg_length);
2055
7.84k
    len -= betoh16(cfg->cfg_length);
2056
7.84k
  }
2057
2058
5.15k
  if (!ikev2_msg_frompeer(msg))
2059
4.95k
    return (0);
2060
2061
192
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
192
  return (0);
2064
5.15k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
17.0k
{
2070
17.0k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
17.0k
  if (left < sizeof(*hdr)) {
2073
7.15k
    log_debug("%s: malformed payload: too short for header "
2074
7.15k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
7.15k
    return (-1);
2076
7.15k
  }
2077
9.94k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.94k
  return (0);
2080
17.0k
}
2081
2082
int
2083
ikev2_pld_eap(struct iked *env, struct ikev2_payload *pld,
2084
    struct iked_message *msg, size_t offset, size_t left)
2085
17.0k
{
2086
17.0k
  struct eap_header    hdr;
2087
17.0k
  struct eap_message    *eap = NULL;
2088
17.0k
  const struct iked_sa    *sa = msg->msg_sa;
2089
17.0k
  size_t         len;
2090
2091
17.0k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
7.15k
    return (-1);
2093
9.94k
  len = betoh16(hdr.eap_length);
2094
2095
9.94k
  if (len < sizeof(*eap)) {
2096
3.45k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.45k
        print_map(hdr.eap_code, eap_code_map),
2098
3.45k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
6.48k
  } else {
2100
    /* Now try to get the indicated length */
2101
6.48k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
3.28k
      log_debug("%s: invalid EAP length", __func__);
2103
3.28k
      return (-1);
2104
3.28k
    }
2105
2106
3.20k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.20k
        print_map(eap->eap_code, eap_code_map),
2108
3.20k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.20k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.20k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.20k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.20k
  }
2115
2116
6.65k
  return (0);
2117
9.94k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/ikev2_pld.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: ikev2_pld.c,v 1.133 2023/09/02 18:36:30 tobhe Exp $ */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 * Copyright (c) 2014 Hans-Joerg Hoexer
7
 *
8
 * Permission to use, copy, modify, and distribute this software for any
9
 * purpose with or without fee is hereby granted, provided that the above
10
 * copyright notice and this permission notice appear in all copies.
11
 *
12
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
 */
20
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <arpa/inet.h>
27
28
#include <stdlib.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <string.h>
32
#include <signal.h>
33
#include <endian.h>
34
#include <errno.h>
35
#include <err.h>
36
#include <event.h>
37
38
#include <openssl/sha.h>
39
#include <openssl/evp.h>
40
41
#include "iked.h"
42
#include "ikev2.h"
43
#include "eap.h"
44
#include "dh.h"
45
46
int  ikev2_validate_pld(struct iked_message *, size_t, size_t,
47
      struct ikev2_payload *);
48
int  ikev2_pld_payloads(struct iked *, struct iked_message *,
49
      size_t, size_t, unsigned int);
50
int  ikev2_validate_sa(struct iked_message *, size_t, size_t,
51
      struct ikev2_sa_proposal *);
52
int  ikev2_pld_sa(struct iked *, struct ikev2_payload *,
53
      struct iked_message *, size_t, size_t);
54
int  ikev2_validate_xform(struct iked_message *, size_t, size_t,
55
      struct ikev2_transform *);
56
int  ikev2_pld_xform(struct iked *, struct iked_message *,
57
      size_t, size_t);
58
int  ikev2_validate_attr(struct iked_message *, size_t, size_t,
59
      struct ikev2_attribute *);
60
int  ikev2_pld_attr(struct iked *, struct ikev2_transform *,
61
      struct iked_message *, size_t, size_t);
62
int  ikev2_validate_ke(struct iked_message *, size_t, size_t,
63
      struct ikev2_keyexchange *);
64
int  ikev2_pld_ke(struct iked *, struct ikev2_payload *,
65
      struct iked_message *, size_t, size_t);
66
int  ikev2_validate_id(struct iked_message *, size_t, size_t,
67
      struct ikev2_id *);
68
int  ikev2_pld_id(struct iked *, struct ikev2_payload *,
69
      struct iked_message *, size_t, size_t, unsigned int);
70
int  ikev2_validate_cert(struct iked_message *, size_t, size_t,
71
      struct ikev2_cert *);
72
int  ikev2_pld_cert(struct iked *, struct ikev2_payload *,
73
      struct iked_message *, size_t, size_t);
74
int  ikev2_validate_certreq(struct iked_message *, size_t, size_t,
75
      struct ikev2_cert *);
76
int  ikev2_pld_certreq(struct iked *, struct ikev2_payload *,
77
      struct iked_message *, size_t, size_t);
78
int  ikev2_pld_nonce(struct iked *, struct ikev2_payload *,
79
      struct iked_message *, size_t, size_t);
80
int  ikev2_validate_notify(struct iked_message *, size_t, size_t,
81
      struct ikev2_notify *);
82
int  ikev2_pld_notify(struct iked *, struct ikev2_payload *,
83
      struct iked_message *, size_t, size_t);
84
int  ikev2_validate_delete(struct iked_message *, size_t, size_t,
85
      struct ikev2_delete *);
86
int  ikev2_pld_delete(struct iked *, struct ikev2_payload *,
87
      struct iked_message *, size_t, size_t);
88
int  ikev2_validate_tss(struct iked_message *, size_t, size_t,
89
      struct ikev2_tsp *);
90
int  ikev2_pld_tss(struct iked *, struct ikev2_payload *,
91
      struct iked_message *, size_t, size_t);
92
int  ikev2_validate_ts(struct iked_message *, size_t, size_t,
93
      struct ikev2_ts *);
94
int  ikev2_pld_ts(struct iked *, struct ikev2_payload *,
95
      struct iked_message *, size_t, size_t, unsigned int);
96
int  ikev2_validate_auth(struct iked_message *, size_t, size_t,
97
      struct ikev2_auth *);
98
int  ikev2_pld_auth(struct iked *, struct ikev2_payload *,
99
      struct iked_message *, size_t, size_t);
100
int  ikev2_pld_e(struct iked *, struct ikev2_payload *,
101
      struct iked_message *, size_t, size_t);
102
int  ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
103
      struct iked_message *msg, size_t offset, size_t left);
104
int  ikev2_frags_reassemble(struct iked *env,
105
      struct ikev2_payload *pld, struct iked_message *msg);
106
int  ikev2_validate_cp(struct iked_message *, size_t, size_t,
107
      struct ikev2_cp *);
108
int  ikev2_pld_cp(struct iked *, struct ikev2_payload *,
109
      struct iked_message *, size_t, size_t);
110
int  ikev2_validate_eap(struct iked_message *, size_t, size_t,
111
      struct eap_header *);
112
int  ikev2_pld_eap(struct iked *, struct ikev2_payload *,
113
      struct iked_message *, size_t, size_t);
114
115
int
116
ikev2_pld_parse(struct iked *env, struct ike_header *hdr,
117
    struct iked_message *msg, size_t offset)
118
13.1k
{
119
13.1k
  log_debug("%s: header ispi %s rspi %s"
120
13.1k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
13.1k
      " msgid %d length %u response %d", __func__,
122
13.1k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
13.1k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
13.1k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
13.1k
      hdr->ike_version,
126
13.1k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
13.1k
      hdr->ike_flags,
128
13.1k
      betoh32(hdr->ike_msgid),
129
13.1k
      betoh32(hdr->ike_length),
130
13.1k
      msg->msg_response);
131
132
13.1k
  if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) {
133
4
    log_debug("%s: short message", __func__);
134
4
    return (-1);
135
4
  }
136
137
13.1k
  offset += sizeof(*hdr);
138
139
13.1k
  return (ikev2_pld_payloads(env, msg, offset,
140
13.1k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
13.1k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
235k
{
147
235k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
235k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
235k
  if (left < sizeof(*pld)) {
152
1.73k
    log_debug("%s: malformed payload: too short for generic "
153
1.73k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.73k
    return (-1);
155
1.73k
  }
156
233k
  memcpy(pld, msgbuf + offset, sizeof(*pld));
157
158
  /*
159
   * We need at least the specified number of bytes.
160
   * pld_length is the full size of the payload including
161
   * the generic payload header.
162
   */
163
233k
  pld_length = betoh16(pld->pld_length);
164
233k
  if (left < pld_length) {
165
5.87k
    log_debug("%s: malformed payload: shorter than specified "
166
5.87k
        "(%zu < %zu)", __func__, left, pld_length);
167
5.87k
    return (-1);
168
5.87k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
228k
  if (pld_length < sizeof(*pld)) {
174
2.36k
    log_debug("%s: malformed payload: shorter than minimum "
175
2.36k
        "header size (%zu < %zu)", __func__, pld_length,
176
2.36k
        sizeof(*pld));
177
2.36k
    return (-1);
178
2.36k
  }
179
180
225k
  return (0);
181
228k
}
182
183
int
184
ikev2_pld_payloads(struct iked *env, struct iked_message *msg,
185
    size_t offset, size_t length, unsigned int payload)
186
13.1k
{
187
13.1k
  struct ikev2_payload   pld;
188
13.1k
  unsigned int     e;
189
13.1k
  int      ret;
190
13.1k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
13.1k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
13.1k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
13.1k
  total = length - offset;
198
199
238k
  while (payload != 0 && offset < length) {
200
235k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
9.97k
      return (-1);
202
203
225k
    log_debug("%s: %spayload %s"
204
225k
        " nextpayload %s critical 0x%02x length %d",
205
225k
        __func__, e ? "decrypted " : "",
206
225k
        print_map(payload, ikev2_payload_map),
207
225k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
225k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
225k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
225k
    offset += sizeof(pld);
213
225k
    total -= sizeof(pld);
214
225k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
225k
    ret = 0;
216
217
225k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
28.2k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
28.2k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
28.2k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
8.28k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
8.28k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
8.28k
      break;
226
12.9k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
19.4k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
19.4k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
19.4k
          payload);
230
19.4k
      break;
231
5.80k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.80k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.80k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
12.1k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
12.1k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
12.1k
      break;
238
8.17k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
8.17k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
8.17k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
242
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
242
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
242
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
32.4k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
32.4k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
32.4k
      break;
249
7.11k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
7.11k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
7.11k
      break;
252
4.65k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
18.1k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
18.1k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
18.1k
      break;
256
0
    case IKEV2_PAYLOAD_SK:
257
0
      ret = ikev2_pld_e(env, &pld, msg, offset, left);
258
0
      break;
259
0
    case IKEV2_PAYLOAD_SKF:
260
0
      ret = ikev2_pld_ef(env, &pld, msg, offset, left);
261
0
      break;
262
9.77k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
9.77k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
9.77k
      break;
265
17.1k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
17.1k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
17.1k
      break;
268
58.8k
    default:
269
58.8k
      print_hex(msgbuf, offset,
270
58.8k
          betoh16(pld.pld_length) - sizeof(pld));
271
58.8k
      break;
272
225k
    }
273
274
225k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
723
      (void)ikev2_send_informational(env, msg);
276
723
      return (-1);
277
723
    }
278
279
    /* Encrypted payloads must appear last */
280
224k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
224k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
224k
    payload = pld.pld_nextpayload;
285
224k
    offset += left;
286
224k
    total -= left;
287
224k
  }
288
289
2.47k
  return (0);
290
13.1k
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
32.6k
{
296
32.6k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
32.6k
  size_t     sap_length;
298
299
32.6k
  if (left < sizeof(*sap)) {
300
13.9k
    log_debug("%s: malformed payload: too short for header "
301
13.9k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.9k
    return (-1);
303
13.9k
  }
304
18.7k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.7k
  sap_length = betoh16(sap->sap_length);
307
18.7k
  if (sap_length < sizeof(*sap)) {
308
5.01k
    log_debug("%s: malformed payload: shorter than minimum header "
309
5.01k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
5.01k
    return (-1);
311
5.01k
  }
312
13.6k
  if (left < sap_length) {
313
2.30k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.30k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.30k
    return (-1);
316
2.30k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
11.3k
  if (!sap->sap_more && left != sap_length) {
322
30
    log_debug("%s: malformed payload: SA payload length mismatches "
323
30
        "single proposal substructure length (%zu != %zu)",
324
30
        __func__, left, sap_length);
325
30
    return (-1);
326
30
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
11.3k
  if (sap->sap_more && left <= sap_length) {
332
839
    log_debug("%s: malformed payload: SA payload too small for "
333
839
        "further proposals (%zu <= %zu)", __func__,
334
839
        left, sap_length);
335
839
    return (-1);
336
839
  }
337
10.5k
  return (0);
338
11.3k
}
339
340
int
341
ikev2_pld_sa(struct iked *env, struct ikev2_payload *pld,
342
    struct iked_message *msg, size_t offset, size_t left)
343
28.2k
{
344
28.2k
  struct ikev2_sa_proposal   sap;
345
28.2k
  struct iked_proposal    *prop = NULL;
346
28.2k
  uint32_t       spi32;
347
28.2k
  uint64_t       spi = 0, spi64;
348
28.2k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
28.2k
  int        r;
350
28.2k
  struct iked_proposals   *props;
351
28.2k
  size_t         total;
352
353
32.6k
  do {
354
32.6k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
22.0k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.5k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.5k
    props = &msg->msg_parent->msg_proposals;
361
362
10.5k
    offset += sizeof(sap);
363
10.5k
    left -= sizeof(sap);
364
365
10.5k
    if (sap.sap_spisize) {
366
1.40k
      if (left < sap.sap_spisize) {
367
646
        log_debug("%s: malformed payload: SPI larger than "
368
646
            "actual payload (%zu < %d)", __func__, left,
369
646
            sap.sap_spisize);
370
646
        return (-1);
371
646
      }
372
755
      if (total < sap.sap_spisize) {
373
135
        log_debug("%s: malformed payload: SPI larger than "
374
135
            "proposal (%zu < %d)", __func__, total,
375
135
            sap.sap_spisize);
376
135
        return (-1);
377
135
      }
378
620
      switch (sap.sap_spisize) {
379
290
      case 4:
380
290
        memcpy(&spi32, msgbuf + offset, 4);
381
290
        spi = betoh32(spi32);
382
290
        break;
383
200
      case 8:
384
200
        memcpy(&spi64, msgbuf + offset, 8);
385
200
        spi = betoh64(spi64);
386
200
        break;
387
130
      default:
388
130
        log_debug("%s: unsupported SPI size %d",
389
130
            __func__, sap.sap_spisize);
390
130
        return (-1);
391
620
      }
392
393
490
      offset += sap.sap_spisize;
394
490
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
490
      total -= sap.sap_spisize;
398
490
    }
399
400
    /*
401
     * As we verified sanity of packet headers, this check will
402
     * be always false, but just to be sure we keep it.
403
     */
404
9.60k
    if (left < total) {
405
0
      log_debug("%s: malformed payload: too long for payload "
406
0
          "(%zu < %zu)", __func__, left, total);
407
0
      return (-1);
408
0
    }
409
410
9.60k
    log_debug("%s: more %d reserved %d length %d"
411
9.60k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.60k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.60k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.60k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.60k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.60k
    if (ikev2_msg_frompeer(msg)) {
418
69
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
69
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
69
        log_debug("%s: invalid proposal", __func__);
421
69
        return (-1);
422
69
      }
423
0
      prop = msg->msg_parent->msg_prop;
424
0
      prop->prop_peerspi.spi = spi;
425
0
      prop->prop_peerspi.spi_protoid = sap.sap_protoid;
426
0
      prop->prop_peerspi.spi_size = sap.sap_spisize;
427
428
0
      prop->prop_localspi.spi_protoid = sap.sap_protoid;
429
0
      prop->prop_localspi.spi_size = sap.sap_spisize;
430
0
    }
431
432
    /*
433
     * Parse the attached transforms
434
     */
435
9.53k
    if (sap.sap_transforms) {
436
5.45k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.45k
      if ((r == -2) && ikev2_msg_frompeer(msg)) {
438
0
        log_debug("%s: invalid proposal transform",
439
0
            __func__);
440
441
        /* cleanup and ignore proposal */
442
0
        config_free_proposal(props, prop);
443
0
        prop = msg->msg_parent->msg_prop = NULL;
444
5.45k
      } else if (r != 0) {
445
4.37k
        log_debug("%s: invalid proposal transforms",
446
4.37k
            __func__);
447
4.37k
        return (-1);
448
4.37k
      }
449
5.45k
    }
450
451
5.16k
    offset += total;
452
5.16k
    left -= total;
453
5.16k
  } while (sap.sap_more);
454
455
750
  return (0);
456
28.2k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
7.30k
{
462
7.30k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
7.30k
  size_t     xfrm_length;
464
465
7.30k
  if (total < sizeof(*xfrm)) {
466
625
    log_debug("%s: malformed payload: too short for header "
467
625
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
625
    return (-1);
469
625
  }
470
6.67k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.67k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.67k
  if (xfrm_length < sizeof(*xfrm)) {
474
1.12k
    log_debug("%s: malformed payload: shorter than minimum header "
475
1.12k
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
1.12k
    return (-1);
477
1.12k
  }
478
5.54k
  if (total < xfrm_length) {
479
644
    log_debug("%s: malformed payload: too long for payload size "
480
644
        "(%zu < %zu)", __func__, total, xfrm_length);
481
644
    return (-1);
482
644
  }
483
484
4.90k
  return (0);
485
5.54k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
7.30k
{
491
7.30k
  struct ikev2_transform     xfrm;
492
7.30k
  char         id[BUFSIZ];
493
7.30k
  int        ret = 0;
494
7.30k
  int        r;
495
7.30k
  size_t         xfrm_length;
496
497
7.30k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.39k
    return (-1);
499
500
4.90k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.90k
  switch (xfrm.xfrm_type) {
503
1.07k
  case IKEV2_XFORMTYPE_ENCR:
504
1.07k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.07k
        ikev2_xformencr_map), sizeof(id));
506
1.07k
    break;
507
777
  case IKEV2_XFORMTYPE_PRF:
508
777
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
777
        ikev2_xformprf_map), sizeof(id));
510
777
    break;
511
154
  case IKEV2_XFORMTYPE_INTEGR:
512
154
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
154
        ikev2_xformauth_map), sizeof(id));
514
154
    break;
515
567
  case IKEV2_XFORMTYPE_DH:
516
567
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
567
        ikev2_xformdh_map), sizeof(id));
518
567
    break;
519
1.00k
  case IKEV2_XFORMTYPE_ESN:
520
1.00k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
1.00k
        ikev2_xformesn_map), sizeof(id));
522
1.00k
    break;
523
1.32k
  default:
524
1.32k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.32k
    break;
526
4.90k
  }
527
528
4.90k
  log_debug("%s: more %d reserved %d length %zu"
529
4.90k
      " type %s id %s",
530
4.90k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.90k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.90k
  msg->msg_attrlength = 0;
537
4.90k
  if (xfrm_length > sizeof(xfrm)) {
538
2.34k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.34k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.80k
      return (-1);
541
1.80k
    }
542
2.34k
  }
543
544
3.10k
  if (ikev2_msg_frompeer(msg)) {
545
0
    r = config_add_transform(msg->msg_parent->msg_prop,
546
0
        xfrm.xfrm_type, betoh16(xfrm.xfrm_id),
547
0
        msg->msg_attrlength, msg->msg_attrlength);
548
0
    if (r == -1) {
549
0
      log_debug("%s: failed to add transform: alloc error",
550
0
          __func__);
551
0
      return (r);
552
0
    } else if (r == -2) {
553
0
      log_debug("%s: failed to add transform: unknown type",
554
0
          __func__);
555
0
      return (r);
556
0
    }
557
0
  }
558
559
  /* Next transform */
560
3.10k
  offset += xfrm_length;
561
3.10k
  total -= xfrm_length;
562
3.10k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.85k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.25k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
177
    log_debug("%s: less data than specified, %zu bytes left",
567
177
        __func__, total);
568
177
    ret = -1;
569
177
  }
570
571
3.10k
  return (ret);
572
3.10k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
29.4k
{
578
29.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
29.4k
  if (total < sizeof(*attr)) {
581
817
    log_debug("%s: malformed payload: too short for header "
582
817
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
817
    return (-1);
584
817
  }
585
28.6k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.6k
  return (0);
588
29.4k
}
589
590
int
591
ikev2_pld_attr(struct iked *env, struct ikev2_transform *xfrm,
592
    struct iked_message *msg, size_t offset, size_t total)
593
29.4k
{
594
29.4k
  struct ikev2_attribute     attr;
595
29.4k
  unsigned int       type;
596
29.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
29.4k
  int        ret = 0;
598
29.4k
  size_t         attr_length;
599
600
29.4k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
817
    return (-1);
602
603
28.6k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.6k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.6k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.6k
      betoh16(attr.attr_length), total);
608
609
28.6k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
22.1k
    offset += sizeof(attr);
612
22.1k
    total -= sizeof(attr);
613
614
22.1k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
47
      msg->msg_attrlength = betoh16(attr.attr_length);
616
22.1k
  } else {
617
    /* Type-Length-Value attribute */
618
6.49k
    attr_length = betoh16(attr.attr_length);
619
6.49k
    if (attr_length < sizeof(attr)) {
620
543
      log_debug("%s: malformed payload: shorter than "
621
543
          "minimum header size (%zu < %zu)", __func__,
622
543
          attr_length, sizeof(attr));
623
543
      return (-1);
624
543
    }
625
5.94k
    if (total < attr_length) {
626
443
      log_debug("%s: malformed payload: attribute larger "
627
443
          "than actual payload (%zu < %zu)", __func__,
628
443
          total, attr_length);
629
443
      return (-1);
630
443
    }
631
5.50k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.50k
        attr_length - sizeof(attr));
633
5.50k
    offset += attr_length;
634
5.50k
    total -= attr_length;
635
5.50k
  }
636
637
27.6k
  if (total > 0) {
638
    /* Next attribute */
639
27.0k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
27.0k
  }
641
642
27.6k
  return (ret);
643
28.6k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
8.28k
{
649
8.28k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
8.28k
  if (left < sizeof(*kex)) {
652
5.12k
    log_debug("%s: malformed payload: too short for header "
653
5.12k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
5.12k
    return (-1);
655
5.12k
  }
656
3.16k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
3.16k
  return (0);
659
8.28k
}
660
661
int
662
ikev2_pld_ke(struct iked *env, struct ikev2_payload *pld,
663
    struct iked_message *msg, size_t offset, size_t left)
664
8.28k
{
665
8.28k
  struct ikev2_keyexchange   kex;
666
8.28k
  uint8_t       *buf;
667
8.28k
  size_t         len;
668
8.28k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
8.28k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
5.12k
    return (-1);
672
673
3.16k
  log_debug("%s: dh group %s reserved %d", __func__,
674
3.16k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
3.16k
      betoh16(kex.kex_reserved));
676
677
3.16k
  buf = msgbuf + offset + sizeof(kex);
678
3.16k
  len = left - sizeof(kex);
679
680
3.16k
  if (len == 0) {
681
1.41k
    log_debug("%s: malformed payload: no KE data given", __func__);
682
1.41k
    return (-1);
683
1.41k
  }
684
685
1.75k
  print_hex(buf, 0, len);
686
687
1.75k
  if (ikev2_msg_frompeer(msg)) {
688
27
    if (msg->msg_parent->msg_ke != NULL) {
689
4
      log_info("%s: duplicate KE payload", __func__);
690
4
      return (-1);
691
4
    }
692
23
    if ((msg->msg_parent->msg_ke = ibuf_new(buf, len)) == NULL) {
693
0
      log_debug("%s: failed to get exchange", __func__);
694
0
      return (-1);
695
0
    }
696
23
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
23
  }
698
699
1.74k
  return (0);
700
1.75k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
19.4k
{
706
19.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
19.4k
  if (left < sizeof(*id)) {
709
7.63k
    log_debug("%s: malformed payload: too short for header "
710
7.63k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.63k
    return (-1);
712
7.63k
  }
713
11.8k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.8k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.46k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.46k
        __func__);
718
6.46k
    return (-1);
719
6.46k
  }
720
721
5.38k
  return (0);
722
11.8k
}
723
724
int
725
ikev2_pld_id(struct iked *env, struct ikev2_payload *pld,
726
    struct iked_message *msg, size_t offset, size_t left, unsigned int payload)
727
19.4k
{
728
19.4k
  uint8_t       *ptr;
729
19.4k
  struct ikev2_id      id;
730
19.4k
  size_t         len;
731
19.4k
  struct iked_id      *idp, idb;
732
19.4k
  const struct iked_sa    *sa = msg->msg_sa;
733
19.4k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
19.4k
  char         idstr[IKED_ID_SIZE];
735
736
19.4k
  if (ikev2_validate_id(msg, offset, left, &id))
737
14.0k
    return (-1);
738
739
5.38k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
5.38k
  ptr = msgbuf + offset;
743
5.38k
  len = left;
744
745
5.38k
  idb.id_type = id.id_type;
746
5.38k
  idb.id_offset = sizeof(id);
747
5.38k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
5.38k
  if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) {
751
0
    ibuf_free(idb.id_buf);
752
0
    log_debug("%s: malformed id", __func__);
753
0
    return (-1);
754
0
  }
755
756
5.38k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
5.38k
  if (!ikev2_msg_frompeer(msg)) {
759
5.28k
    ibuf_free(idb.id_buf);
760
5.28k
    return (0);
761
5.28k
  }
762
763
101
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
101
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
59
    idp = &msg->msg_parent->msg_peerid;
766
42
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
42
    idp = &msg->msg_parent->msg_localid;
768
0
  else {
769
0
    ibuf_free(idb.id_buf);
770
0
    log_debug("%s: unexpected id payload", __func__);
771
0
    return (0);
772
0
  }
773
774
101
  if (idp->id_type) {
775
16
    ibuf_free(idb.id_buf);
776
16
    log_debug("%s: duplicate id payload", __func__);
777
16
    return (-1);
778
16
  }
779
780
85
  idp->id_buf = idb.id_buf;
781
85
  idp->id_offset = idb.id_offset;
782
85
  idp->id_type = idb.id_type;
783
784
85
  return (0);
785
101
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
5.80k
{
791
5.80k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.80k
  if (left < sizeof(*cert)) {
794
1.46k
    log_debug("%s: malformed payload: too short for header "
795
1.46k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.46k
    return (-1);
797
1.46k
  }
798
4.34k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.34k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
982
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
982
    return (-1);
802
982
  }
803
804
3.36k
  return (0);
805
4.34k
}
806
807
int
808
ikev2_pld_cert(struct iked *env, struct ikev2_payload *pld,
809
    struct iked_message *msg, size_t offset, size_t left)
810
5.80k
{
811
5.80k
  struct ikev2_cert    cert;
812
5.80k
  uint8_t       *buf;
813
5.80k
  size_t         len;
814
5.80k
  struct iked_id      *certid;
815
5.80k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.80k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.80k
  int        i;
818
819
5.80k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.44k
    return (-1);
821
3.36k
  offset += sizeof(cert);
822
823
3.36k
  buf = msgbuf + offset;
824
3.36k
  len = left - sizeof(cert);
825
826
3.36k
  log_debug("%s: type %s length %zu",
827
3.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.36k
  print_hex(buf, 0, len);
830
831
3.36k
  if (!ikev2_msg_frompeer(msg))
832
1.41k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.94k
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
290
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
290
       SPI_SA(sa, __func__));
838
290
    return (0);
839
290
  }
840
841
1.65k
  certid = &msg->msg_parent->msg_cert;
842
1.65k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
4.10k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
3.35k
      certid = &msg->msg_parent->msg_scert[i];
846
3.35k
      if (!certid->id_type)
847
605
        break;
848
3.35k
    }
849
1.35k
    if (certid->id_type) {
850
748
      log_debug("%s: too many cert payloads, ignoring",
851
748
         SPI_SA(sa, __func__));
852
748
      return (0);
853
748
    }
854
1.35k
  }
855
856
911
  if ((certid->id_buf = ibuf_new(buf, len)) == NULL) {
857
0
    log_debug("%s: failed to save cert", __func__);
858
0
    return (-1);
859
0
  }
860
911
  certid->id_type = cert.cert_type;
861
911
  certid->id_offset = 0;
862
863
911
  return (0);
864
911
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
12.1k
{
870
12.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
12.1k
  if (left < sizeof(*cert)) {
873
2.65k
    log_debug("%s: malformed payload: too short for header "
874
2.65k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.65k
    return (-1);
876
2.65k
  }
877
9.48k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
9.48k
  return (0);
880
12.1k
}
881
882
int
883
ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
884
    struct iked_message *msg, size_t offset, size_t left)
885
12.1k
{
886
12.1k
  struct ikev2_cert    cert;
887
12.1k
  struct iked_certreq   *cr;
888
12.1k
  uint8_t       *buf;
889
12.1k
  ssize_t        len;
890
12.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
12.1k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.65k
    return (-1);
894
9.48k
  offset += sizeof(cert);
895
896
9.48k
  buf = msgbuf + offset;
897
9.48k
  len = left - sizeof(cert);
898
899
9.48k
  log_debug("%s: type %s length %zd",
900
9.48k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
9.48k
  print_hex(buf, 0, len);
903
904
9.48k
  if (!ikev2_msg_frompeer(msg))
905
8.30k
    return (0);
906
907
1.18k
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
321
    if (len == 0) {
909
279
      log_info("%s: invalid length 0", __func__);
910
279
      return (0);
911
279
    }
912
42
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
9
      log_info("%s: invalid certificate request",
914
9
          __func__);
915
9
      return (-1);
916
9
    }
917
42
  }
918
919
897
  if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) {
920
0
    log_info("%s: failed to allocate certreq.", __func__);
921
0
    return (-1);
922
0
  }
923
897
  if ((cr->cr_data = ibuf_new(buf, len)) == NULL) {
924
0
    log_info("%s: failed to allocate buffer.", __func__);
925
0
    free(cr);
926
0
    return (-1);
927
0
  }
928
897
  cr->cr_type = cert.cert_type;
929
897
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
897
  return (0);
932
897
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
8.17k
{
938
8.17k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
8.17k
  if (left < sizeof(*auth)) {
941
1.85k
    log_debug("%s: malformed payload: too short for header "
942
1.85k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.85k
    return (-1);
944
1.85k
  }
945
6.31k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.31k
  if (auth->auth_method == 0) {
948
3.36k
    log_info("%s: malformed payload: invalid auth method",
949
3.36k
        __func__);
950
3.36k
    return (-1);
951
3.36k
  }
952
953
2.95k
  return (0);
954
6.31k
}
955
956
int
957
ikev2_pld_auth(struct iked *env, struct ikev2_payload *pld,
958
    struct iked_message *msg, size_t offset, size_t left)
959
8.17k
{
960
8.17k
  struct ikev2_auth    auth;
961
8.17k
  struct iked_id      *idp;
962
8.17k
  uint8_t       *buf;
963
8.17k
  size_t         len;
964
8.17k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
8.17k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.21k
    return (-1);
968
2.95k
  offset += sizeof(auth);
969
970
2.95k
  buf = msgbuf + offset;
971
2.95k
  len = left - sizeof(auth);
972
973
2.95k
  log_debug("%s: method %s length %zu",
974
2.95k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.95k
  print_hex(buf, 0, len);
977
978
2.95k
  if (!ikev2_msg_frompeer(msg))
979
2.91k
    return (0);
980
981
42
  idp = &msg->msg_parent->msg_auth;
982
42
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
41
  ibuf_free(idp->id_buf);
988
41
  idp->id_type = auth.auth_method;
989
41
  idp->id_offset = 0;
990
41
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
41
  return (0);
994
41
}
995
996
int
997
ikev2_pld_nonce(struct iked *env, struct ikev2_payload *pld,
998
    struct iked_message *msg, size_t offset, size_t left)
999
242
{
1000
242
  size_t     len;
1001
242
  uint8_t   *buf;
1002
242
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
242
  buf = msgbuf + offset;
1005
242
  len = left;
1006
1007
242
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
160
  print_hex(buf, 0, len);
1013
1014
160
  if (ikev2_msg_frompeer(msg)) {
1015
61
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
42
    if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) {
1020
0
      log_debug("%s: failed to get peer nonce", __func__);
1021
0
      return (-1);
1022
0
    }
1023
42
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
42
  }
1025
1026
141
  return (0);
1027
160
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
32.4k
{
1033
32.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
32.4k
  if (left < sizeof(*n)) {
1036
3.51k
    log_debug("%s: malformed payload: too short for header "
1037
3.51k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.51k
    return (-1);
1039
3.51k
  }
1040
28.8k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
28.8k
  return (0);
1043
32.4k
}
1044
1045
int
1046
ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
1047
    struct iked_message *msg, size_t offset, size_t left)
1048
32.4k
{
1049
32.4k
  struct ikev2_notify  n;
1050
32.4k
  const struct iked_sa  *sa = msg->msg_sa;
1051
32.4k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
32.4k
  uint32_t     spi32;
1053
32.4k
  uint64_t     spi64;
1054
32.4k
  struct iked_spi   *rekey;
1055
32.4k
  uint16_t     type;
1056
32.4k
  uint16_t     signature_hash;
1057
1058
32.4k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.51k
    return (-1);
1060
28.8k
  type = betoh16(n.n_type);
1061
1062
28.8k
  log_debug("%s: protoid %s spisize %d type %s",
1063
28.8k
      __func__,
1064
28.8k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
28.8k
      print_map(type, ikev2_n_map));
1066
1067
28.8k
  left -= sizeof(n);
1068
28.8k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
28.8k
  print_hex(buf, 0, left);
1072
1073
28.8k
  if (!ikev2_msg_frompeer(msg))
1074
1.44k
    return (0);
1075
1076
27.4k
  switch (type) {
1077
3.05k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
23.0k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
23.0k
    if (left != sizeof(md)) {
1080
16
      log_debug("%s: malformed payload: hash size mismatch"
1081
16
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
16
      return (-1);
1083
16
    }
1084
22.9k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
22.9k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
22.9k
    if (memcmp(buf, md, left) != 0) {
1088
22.9k
      log_debug("%s: %s detected NAT", __func__,
1089
22.9k
          print_map(type, ikev2_n_map));
1090
22.9k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
3.05k
        msg->msg_parent->msg_nat_detected
1092
3.05k
            |= IKED_MSG_NAT_SRC_IP;
1093
19.9k
      else
1094
19.9k
        msg->msg_parent->msg_nat_detected
1095
19.9k
            |= IKED_MSG_NAT_DST_IP;
1096
22.9k
    }
1097
22.9k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
22.9k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
22.9k
    break;
1101
6
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
6
    if (!msg->msg_e) {
1103
0
      log_debug("%s: AUTHENTICATION_FAILED not encrypted",
1104
0
          __func__);
1105
0
      return (-1);
1106
0
    }
1107
    /*
1108
     * If we are the responder, then we only accept
1109
     * AUTHENTICATION_FAILED from authenticated peers.
1110
     * If we are the initiator, the peer cannot be authenticated.
1111
     */
1112
6
    if (!sa->sa_hdr.sh_initiator) {
1113
6
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
6
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
6
            " from unauthenticated initiator",
1116
6
            __func__);
1117
6
        return (-1);
1118
6
      }
1119
6
    } else {
1120
0
      if (sa_stateok(sa, IKEV2_STATE_VALID)) {
1121
0
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1122
0
            " from authenticated responder",
1123
0
            __func__);
1124
0
        return (-1);
1125
0
      }
1126
0
    }
1127
0
    msg->msg_parent->msg_flags
1128
0
        |= IKED_MSG_FLAGS_AUTHENTICATION_FAILED;
1129
0
    break;
1130
135
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
135
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
135
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
135
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
4
      log_debug("%s: malformed payload: group size mismatch"
1139
4
          " (%zu != %zu)", __func__, left,
1140
4
          sizeof(msg->msg_parent->msg_group));
1141
4
      return (-1);
1142
4
    }
1143
131
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
131
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
131
    break;
1146
241
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
241
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
241
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
241
    break;
1154
75
  case IKEV2_N_REKEY_SA:
1155
75
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
75
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
70
    rekey = &msg->msg_parent->msg_rekey;
1164
70
    if (rekey->spi != 0) {
1165
5
      log_debug("%s: rekeying of multiple SAs not supported",
1166
5
          __func__);
1167
5
      return (-1);
1168
5
    }
1169
65
    switch (n.n_spisize) {
1170
59
    case 4:
1171
59
      memcpy(&spi32, buf, left);
1172
59
      rekey->spi = betoh32(spi32);
1173
59
      break;
1174
3
    case 8:
1175
3
      memcpy(&spi64, buf, left);
1176
3
      rekey->spi = betoh64(spi64);
1177
3
      break;
1178
3
    default:
1179
3
      log_debug("%s: invalid spi size %d", __func__,
1180
3
          n.n_spisize);
1181
3
      return (-1);
1182
65
    }
1183
62
    rekey->spi_size = n.n_spisize;
1184
62
    rekey->spi_protoid = n.n_protoid;
1185
1186
62
    log_debug("%s: rekey %s spi %s", __func__,
1187
62
        print_map(n.n_protoid, ikev2_saproto_map),
1188
62
        print_spi(rekey->spi, n.n_spisize));
1189
62
    break;
1190
348
  case IKEV2_N_TEMPORARY_FAILURE:
1191
348
    if (!msg->msg_e) {
1192
0
      log_debug("%s: IKEV2_N_TEMPORARY_FAILURE not encrypted",
1193
0
          __func__);
1194
0
      return (-1);
1195
0
    }
1196
348
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
348
    break;
1198
255
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
255
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
255
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
255
        sizeof(msg->msg_parent->msg_transform)) {
1206
127
      log_debug("%s: ignoring malformed ipcomp notification",
1207
127
          __func__);
1208
127
      return (0);
1209
127
    }
1210
128
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
128
        sizeof(msg->msg_parent->msg_cpi));
1212
128
    memcpy(&msg->msg_parent->msg_transform,
1213
128
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
128
        sizeof(msg->msg_parent->msg_transform));
1215
1216
128
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
128
        msg->msg_parent->msg_response ? "res" : "req",
1218
128
        betoh16(msg->msg_parent->msg_cpi),
1219
128
        print_map(msg->msg_parent->msg_transform,
1220
128
        ikev2_ipcomp_map), left);
1221
1222
128
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
128
    break;
1224
73
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
73
    if (!msg->msg_e) {
1226
0
      log_debug("%s: N_CHILD_SA_NOT_FOUND not encrypted",
1227
0
          __func__);
1228
0
      return (-1);
1229
0
    }
1230
73
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
73
    break;
1232
36
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
36
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
36
    break;
1235
267
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
267
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
267
    if (left != 0) {
1242
131
      log_debug("%s: ignoring malformed mobike"
1243
131
          " notification: %zu", __func__, left);
1244
131
      return (0);
1245
131
    }
1246
136
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
136
    break;
1248
316
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
316
    if (!msg->msg_e) {
1250
0
      log_debug("%s: N_USE_TRANSPORT_MODE not encrypted",
1251
0
          __func__);
1252
0
      return (-1);
1253
0
    }
1254
316
    if (left != 0) {
1255
77
      log_debug("%s: ignoring malformed transport mode"
1256
77
          " notification: %zu", __func__, left);
1257
77
      return (0);
1258
77
    }
1259
239
    if (msg->msg_parent->msg_response) {
1260
0
      if (!(msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT)) {
1261
0
        log_debug("%s: ignoring transport mode"
1262
0
            " notification (policy)", __func__);
1263
0
        return (0);
1264
0
      }
1265
0
    }
1266
239
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
239
    break;
1268
388
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
388
    if (!msg->msg_e) {
1270
0
      log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted",
1271
0
          __func__);
1272
0
      return (-1);
1273
0
    }
1274
388
    if (!sa->sa_mobike) {
1275
388
      log_debug("%s: ignoring update sa addresses"
1276
388
          " notification w/o mobike: %zu", __func__, left);
1277
388
      return (0);
1278
388
    }
1279
0
    if (left != 0) {
1280
0
      log_debug("%s: ignoring malformed update sa addresses"
1281
0
          " notification: %zu", __func__, left);
1282
0
      return (0);
1283
0
    }
1284
0
    msg->msg_parent->msg_update_sa_addresses = 1;
1285
0
    break;
1286
202
  case IKEV2_N_COOKIE2:
1287
202
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
202
    if (!sa->sa_mobike) {
1293
202
      log_debug("%s: ignoring cookie2 notification"
1294
202
          " w/o mobike: %zu", __func__, left);
1295
202
      return (0);
1296
202
    }
1297
0
    if (left < IKED_COOKIE2_MIN || left > IKED_COOKIE2_MAX) {
1298
0
      log_debug("%s: ignoring malformed cookie2"
1299
0
          " notification: %zu", __func__, left);
1300
0
      return (0);
1301
0
    }
1302
0
    ibuf_free(msg->msg_cookie2);  /* should not happen */
1303
0
    if ((msg->msg_cookie2 = ibuf_new(buf, left)) == NULL) {
1304
0
      log_debug("%s: failed to get peer cookie2", __func__);
1305
0
      return (-1);
1306
0
    }
1307
0
    msg->msg_parent->msg_cookie2 = msg->msg_cookie2;
1308
0
    break;
1309
2
  case IKEV2_N_COOKIE:
1310
2
    if (msg->msg_e) {
1311
2
      log_debug("%s: N_COOKIE encrypted",
1312
2
          __func__);
1313
2
      return (-1);
1314
2
    }
1315
0
    if (left < IKED_COOKIE_MIN || left > IKED_COOKIE_MAX) {
1316
0
      log_debug("%s: ignoring malformed cookie"
1317
0
          " notification: %zu", __func__, left);
1318
0
      return (0);
1319
0
    }
1320
0
    log_debug("%s: received cookie, len %zu", __func__, left);
1321
0
    print_hex(buf, 0, left);
1322
1323
0
    ibuf_free(msg->msg_cookie);
1324
0
    if ((msg->msg_cookie = ibuf_new(buf, left)) == NULL) {
1325
0
      log_debug("%s: failed to get peer cookie", __func__);
1326
0
      return (-1);
1327
0
    }
1328
0
    msg->msg_parent->msg_cookie = msg->msg_cookie;
1329
0
    break;
1330
14
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
14
    if (msg->msg_e) {
1332
14
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
14
          __func__);
1334
14
      return (-1);
1335
14
    }
1336
0
    if (left != 0) {
1337
0
      log_debug("%s: ignoring malformed fragmentation"
1338
0
          " notification: %zu", __func__, left);
1339
0
      return (0);
1340
0
    }
1341
0
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_FRAGMENTATION;
1342
0
    break;
1343
7
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
7
    if (msg->msg_e) {
1345
7
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
7
          __func__);
1347
7
      return (-1);
1348
7
    }
1349
0
    if (sa == NULL) {
1350
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: no SA",
1351
0
          __func__);
1352
0
      return (-1);
1353
0
    }
1354
0
    if (sa->sa_sigsha2) {
1355
0
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: "
1356
0
          "duplicate notify", __func__);
1357
0
      return (0);
1358
0
    }
1359
0
    if (left < sizeof(signature_hash) ||
1360
0
        left % sizeof(signature_hash)) {
1361
0
      log_debug("%s: malformed signature hash notification"
1362
0
          "(%zu bytes)", __func__, left);
1363
0
      return (0);
1364
0
    }
1365
0
    while (left >= sizeof(signature_hash)) {
1366
0
      memcpy(&signature_hash, buf, sizeof(signature_hash));
1367
0
      signature_hash = betoh16(signature_hash);
1368
0
      log_debug("%s: signature hash %s (%x)", __func__,
1369
0
          print_map(signature_hash, ikev2_sighash_map),
1370
0
          signature_hash);
1371
0
      left -= sizeof(signature_hash);
1372
0
      buf += sizeof(signature_hash);
1373
0
      if (signature_hash == IKEV2_SIGHASH_SHA2_256)
1374
0
        msg->msg_parent->msg_flags
1375
0
            |= IKED_MSG_FLAGS_SIGSHA2;
1376
0
    }
1377
0
    break;
1378
27.4k
  }
1379
1380
26.4k
  return (0);
1381
27.4k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
7.11k
{
1387
7.11k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
7.11k
  if (left < sizeof(*del)) {
1390
1.39k
    log_debug("%s: malformed payload: too short for header "
1391
1.39k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.39k
    return (-1);
1393
1.39k
  }
1394
5.72k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.72k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.64k
  return (0);
1402
5.72k
}
1403
1404
int
1405
ikev2_pld_delete(struct iked *env, struct ikev2_payload *pld,
1406
    struct iked_message *msg, size_t offset, size_t left)
1407
7.11k
{
1408
7.11k
  struct ikev2_delete  del;
1409
7.11k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
7.11k
  size_t       cnt, sz, len;
1411
1412
7.11k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.47k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.64k
  if (ikev2_msg_frompeer(msg) &&
1417
5.64k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.64k
  cnt = betoh16(del.del_nspi);
1421
5.64k
  sz = del.del_spisize;
1422
1423
5.64k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.64k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.64k
      sz, cnt);
1426
1427
5.64k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.32k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.32k
    return (0);
1430
5.32k
  }
1431
1432
316
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
316
  msg->msg_parent->msg_del_cnt = cnt;
1434
316
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
316
  buf = msgbuf + offset + sizeof(del);
1437
316
  len = left - sizeof(del);
1438
316
  if (len == 0 || sz == 0 || cnt == 0)
1439
293
    return (0);
1440
1441
23
  if ((len / sz) != cnt) {
1442
21
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
21
        __func__, len, sz, cnt);
1444
21
    return (-1);
1445
21
  }
1446
1447
2
  print_hex(buf, 0, len);
1448
1449
2
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
2
  return (0);
1452
23
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
18.1k
{
1458
18.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
18.1k
  if (left < sizeof(*tsp)) {
1461
2.39k
    log_debug("%s: malformed payload: too short for header "
1462
2.39k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.39k
    return (-1);
1464
2.39k
  }
1465
15.7k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
15.7k
  return (0);
1468
18.1k
}
1469
1470
int
1471
ikev2_pld_tss(struct iked *env, struct ikev2_payload *pld,
1472
    struct iked_message *msg, size_t offset, size_t left)
1473
18.1k
{
1474
18.1k
  struct ikev2_tsp     tsp;
1475
18.1k
  struct ikev2_ts      ts;
1476
18.1k
  size_t         ts_len, i;
1477
1478
18.1k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.39k
    return (-1);
1480
1481
15.7k
  offset += sizeof(tsp);
1482
15.7k
  left -= sizeof(tsp);
1483
1484
15.7k
  log_debug("%s: count %d length %zu", __func__,
1485
15.7k
      tsp.tsp_count, left);
1486
1487
31.1k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
29.5k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
12.4k
      return (-1);
1490
1491
17.1k
    log_debug("%s: type %s protoid %u length %d "
1492
17.1k
        "startport %u endport %u", __func__,
1493
17.1k
        print_map(ts.ts_type, ikev2_ts_map),
1494
17.1k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
17.1k
        betoh16(ts.ts_startport),
1496
17.1k
        betoh16(ts.ts_endport));
1497
1498
17.1k
    offset += sizeof(ts);
1499
17.1k
    left -= sizeof(ts);
1500
1501
17.1k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
17.1k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.69k
      return (-1);
1504
1505
15.4k
    offset += ts_len;
1506
15.4k
    left -= ts_len;
1507
15.4k
  }
1508
1509
1.59k
  return (0);
1510
15.7k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
29.5k
{
1516
29.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
29.5k
  size_t     ts_length;
1518
1519
29.5k
  if (left < sizeof(*ts)) {
1520
11.2k
    log_debug("%s: malformed payload: too short for header "
1521
11.2k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
11.2k
    return (-1);
1523
11.2k
  }
1524
18.3k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
18.3k
  ts_length = betoh16(ts->ts_length);
1527
18.3k
  if (ts_length < sizeof(*ts)) {
1528
315
    log_debug("%s: malformed payload: shorter than minimum header "
1529
315
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
315
    return (-1);
1531
315
  }
1532
18.0k
  if (left < ts_length) {
1533
873
    log_debug("%s: malformed payload: too long for payload size "
1534
873
        "(%zu < %zu)", __func__, left, ts_length);
1535
873
    return (-1);
1536
873
  }
1537
1538
17.1k
  return (0);
1539
18.0k
}
1540
1541
int
1542
ikev2_pld_ts(struct iked *env, struct ikev2_payload *pld,
1543
    struct iked_message *msg, size_t offset, size_t left, unsigned int type)
1544
17.1k
{
1545
17.1k
  struct sockaddr_in     start4, end4;
1546
17.1k
  struct sockaddr_in6    start6, end6;
1547
17.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
17.1k
  uint8_t       *ptr;
1549
1550
17.1k
  ptr = msgbuf + offset;
1551
1552
17.1k
  switch (type) {
1553
6.22k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
6.22k
    if (left < 2 * 4) {
1555
323
      log_debug("%s: malformed payload: too short "
1556
323
          "for ipv4 addr range (%zu < %u)",
1557
323
          __func__, left, 2 * 4);
1558
323
      return (-1);
1559
323
    }
1560
1561
5.90k
    bzero(&start4, sizeof(start4));
1562
5.90k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
5.90k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
5.90k
    ptr += 4;
1568
5.90k
    left -= 4;
1569
1570
5.90k
    bzero(&end4, sizeof(end4));
1571
5.90k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
5.90k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
5.90k
    left -= 4;
1577
1578
5.90k
    log_debug("%s: start %s end %s", __func__,
1579
5.90k
        print_addr(&start4), print_addr(&end4));
1580
5.90k
    break;
1581
1.36k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.36k
    if (left < 2 * 16) {
1583
252
      log_debug("%s: malformed payload: too short "
1584
252
          "for ipv6 addr range (%zu < %u)",
1585
252
          __func__, left, 2 * 16);
1586
252
      return (-1);
1587
252
    }
1588
1.11k
    bzero(&start6, sizeof(start6));
1589
1.11k
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
1.11k
    memcpy(&start6.sin6_addr, ptr, 16);
1594
1.11k
    ptr += 16;
1595
1.11k
    left -= 16;
1596
1597
1.11k
    bzero(&end6, sizeof(end6));
1598
1.11k
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
1.11k
    memcpy(&end6.sin6_addr, ptr, 16);
1603
1.11k
    left -= 16;
1604
1605
1.11k
    log_debug("%s: start %s end %s", __func__,
1606
1.11k
        print_addr(&start6), print_addr(&end6));
1607
1.11k
    break;
1608
9.54k
  default:
1609
9.54k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
9.54k
    return (0);
1611
17.1k
  }
1612
1613
7.01k
  if (left > 0) {
1614
1.12k
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
1.12k
        __func__, left);
1616
1.12k
    return (-1);
1617
1.12k
  }
1618
1619
5.89k
  return (0);
1620
7.01k
}
1621
1622
int
1623
ikev2_pld_ef(struct iked *env, struct ikev2_payload *pld,
1624
    struct iked_message *msg, size_t offset, size_t left)
1625
0
{
1626
0
  struct iked_sa      *sa = msg->msg_sa;
1627
0
  struct iked_frag    *sa_frag = &sa->sa_fragments;
1628
0
  struct iked_frag_entry    *el;
1629
0
  struct ikev2_frag_payload  frag;
1630
0
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1631
0
  uint8_t       *buf;
1632
0
  struct ibuf     *e = NULL;
1633
0
  size_t         frag_num, frag_total;
1634
0
  size_t         len;
1635
0
  int        ret = -1;
1636
0
  int        processed = 0;
1637
0
  ssize_t        elen;
1638
1639
0
  buf = msgbuf + offset;
1640
0
  memcpy(&frag, buf, sizeof(frag));
1641
0
  frag_num = betoh16(frag.frag_num);
1642
0
  frag_total = betoh16(frag.frag_total);
1643
1644
0
  offset += sizeof(frag);
1645
0
  buf = msgbuf + offset;
1646
0
  len = left - sizeof(frag);
1647
1648
0
  ikestat_inc(env, ikes_frag_rcvd);
1649
1650
  /* Limit number of total fragments to avoid DOS */
1651
0
  if (frag_total > IKED_FRAG_TOTAL_MAX ) {
1652
0
    log_debug("%s: Total Fragments too big  %zu",
1653
0
        __func__, frag_total);
1654
0
    goto dropall;
1655
0
  }
1656
1657
  /* Check sanity of fragment header */
1658
0
  if (frag_num == 0 || frag_total == 0) {
1659
0
    log_debug("%s: Malformed fragment received: %zu of %zu",
1660
0
        __func__, frag_num, frag_total);
1661
0
    goto done;
1662
0
  }
1663
0
  log_debug("%s: Received fragment: %zu of %zu",
1664
0
      __func__, frag_num, frag_total);
1665
1666
  /* Drop fragment if frag_num and frag_total don't match */
1667
0
  if (frag_num > frag_total)
1668
0
    goto done;
1669
1670
  /* Decrypt fragment */
1671
0
  if ((e = ibuf_new(buf, len)) == NULL)
1672
0
    goto done;
1673
1674
0
  if ((e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e))
1675
0
      == NULL ) {
1676
0
    log_debug("%s: Failed to decrypt fragment: %zu of %zu",
1677
0
        __func__, frag_num, frag_total);
1678
0
    goto done;
1679
0
  }
1680
0
  elen = ibuf_size(e);
1681
1682
  /* Check new fragmented message */
1683
0
  if (sa_frag->frag_arr == NULL) {
1684
0
    sa_frag->frag_arr = recallocarray(NULL, 0, frag_total,
1685
0
        sizeof(struct iked_frag_entry*));
1686
0
    if (sa_frag->frag_arr == NULL) {
1687
0
      log_info("%s: recallocarray sa_frag->frag_arr.", __func__);
1688
0
      goto done;
1689
0
    }
1690
0
    sa_frag->frag_total = frag_total;
1691
0
  } else {
1692
    /* Drop all fragments if frag_total doesn't match previous */
1693
0
    if (frag_total != sa_frag->frag_total)
1694
0
      goto dropall;
1695
1696
    /* Silent drop if fragment already stored */
1697
0
    if (sa_frag->frag_arr[frag_num-1] != NULL)
1698
0
      goto done;
1699
0
  }
1700
1701
  /* The first fragments IKE header determines pld_nextpayload */
1702
0
  if (frag_num == 1)
1703
0
    sa_frag->frag_nextpayload = pld->pld_nextpayload;
1704
1705
  /* Insert new list element */
1706
0
  el = calloc(1, sizeof(struct iked_frag_entry));
1707
0
  if (el == NULL) {
1708
0
    log_info("%s: Failed allocating new fragment: %zu of %zu",
1709
0
        __func__, frag_num, frag_total);
1710
0
    goto done;
1711
0
  }
1712
1713
0
  sa_frag->frag_arr[frag_num-1] = el;
1714
0
  el->frag_size = elen;
1715
0
  el->frag_data = calloc(1, elen);
1716
0
  if (el->frag_data == NULL) {
1717
0
    log_debug("%s: Failed allocating new fragment data: %zu of %zu",
1718
0
        __func__, frag_num, frag_total);
1719
0
    goto done;
1720
0
  }
1721
1722
  /* Copy plaintext to fragment */
1723
0
  memcpy(el->frag_data, ibuf_seek(e, 0, 0), elen);
1724
0
  sa_frag->frag_total_size += elen;
1725
0
  sa_frag->frag_count++;
1726
1727
  /* If all frags are received start reassembly */
1728
0
  if (sa_frag->frag_count == sa_frag->frag_total) {
1729
0
    log_debug("%s: All fragments received: %zu of %zu",
1730
0
        __func__, frag_num, frag_total);
1731
0
    ret = ikev2_frags_reassemble(env, pld, msg);
1732
0
  } else {
1733
0
    ret = 0;
1734
0
  }
1735
0
  processed = 1;
1736
1737
0
done:
1738
0
  if (!processed)
1739
0
    ikestat_inc(env, ikes_frag_rcvd_drop);
1740
0
  ibuf_free(e);
1741
0
  return (ret);
1742
0
dropall:
1743
0
  ikestat_add(env, ikes_frag_rcvd_drop, sa_frag->frag_count + 1);
1744
0
  config_free_fragments(sa_frag);
1745
0
  ibuf_free(e);
1746
0
  return -1;
1747
0
}
1748
1749
int
1750
ikev2_frags_reassemble(struct iked *env, struct ikev2_payload *pld,
1751
    struct iked_message *msg)
1752
0
{
1753
0
  struct iked_frag    *sa_frag = &msg->msg_sa->sa_fragments;
1754
0
  struct ibuf     *e = NULL;
1755
0
  struct iked_frag_entry    *el;
1756
0
  uint8_t       *ptr;
1757
0
  size_t         offset;
1758
0
  size_t         i;
1759
0
  struct iked_message    emsg;
1760
0
  int        ret = -1;
1761
0
  int        processed = 0;
1762
1763
  /* Reassemble fragments to single buffer */
1764
0
  if ((e = ibuf_new(NULL, sa_frag->frag_total_size)) == NULL) {
1765
0
    log_debug("%s: Failed allocating SK buffer.", __func__);
1766
0
    goto done;
1767
0
  }
1768
1769
  /* Empty queue to new buffer */
1770
0
  offset = 0;
1771
0
  for (i = 0; i < sa_frag->frag_total; i++) {
1772
0
    if ((el = sa_frag->frag_arr[i]) == NULL)
1773
0
      fatalx("Tried to reassemble shallow frag_arr");
1774
0
    ptr = ibuf_seek(e, offset, el->frag_size);
1775
0
    if (ptr == NULL) {
1776
0
      log_info("%s: failed to reassemble fragments", __func__);
1777
0
      goto done;
1778
0
    }
1779
0
    memcpy(ptr, el->frag_data, el->frag_size);
1780
0
    offset += el->frag_size;
1781
0
  }
1782
1783
0
  log_debug("%s: Defragmented length %zd", __func__,
1784
0
      sa_frag->frag_total_size);
1785
0
  print_hex(ibuf_data(e), 0,  sa_frag->frag_total_size);
1786
1787
  /* Drop the original request's packets from the retransmit queue */
1788
0
  if (msg->msg_response)
1789
0
    ikev2_msg_dispose(env, &msg->msg_sa->sa_requests,
1790
0
        ikev2_msg_lookup(env, &msg->msg_sa->sa_requests, msg,
1791
0
        msg->msg_exchange));
1792
1793
  /*
1794
   * Parse decrypted payload
1795
   */
1796
0
  bzero(&emsg, sizeof(emsg));
1797
0
  memcpy(&emsg, msg, sizeof(*msg));
1798
0
  emsg.msg_data = e;
1799
0
  emsg.msg_e = 1;
1800
0
  emsg.msg_parent = msg;
1801
0
  TAILQ_INIT(&emsg.msg_proposals);
1802
1803
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1804
0
      sa_frag->frag_nextpayload);
1805
0
  processed = 1;
1806
0
done:
1807
0
  if (processed)
1808
0
    ikestat_add(env, ikes_frag_reass_ok, sa_frag->frag_total);
1809
0
  else
1810
0
    ikestat_add(env, ikes_frag_reass_drop, sa_frag->frag_total);
1811
0
  config_free_fragments(sa_frag);
1812
0
  ibuf_free(e);
1813
1814
0
  return (ret);
1815
0
}
1816
1817
int
1818
ikev2_pld_e(struct iked *env, struct ikev2_payload *pld,
1819
    struct iked_message *msg, size_t offset, size_t left)
1820
0
{
1821
0
  struct iked_sa    *sa = msg->msg_sa;
1822
0
  struct ibuf   *e = NULL;
1823
0
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1824
0
  struct iked_message  emsg;
1825
0
  uint8_t     *buf;
1826
0
  size_t       len;
1827
0
  int      ret = -1;
1828
1829
0
  if (sa->sa_fragments.frag_arr != NULL) {
1830
0
    log_warn("%s: Received SK payload when SKFs are in queue.",
1831
0
        __func__);
1832
0
    config_free_fragments(&sa->sa_fragments);
1833
0
    return (ret);
1834
0
  }
1835
1836
0
  buf = msgbuf + offset;
1837
0
  len = left;
1838
1839
0
  if ((e = ibuf_new(buf, len)) == NULL)
1840
0
    goto done;
1841
1842
0
  if (ikev2_msg_frompeer(msg)) {
1843
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1844
0
  } else {
1845
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1846
0
    e = ikev2_msg_decrypt(env, msg->msg_sa, msg->msg_data, e);
1847
0
    sa->sa_hdr.sh_initiator = sa->sa_hdr.sh_initiator ? 0 : 1;
1848
0
  }
1849
1850
0
  if (e == NULL)
1851
0
    goto done;
1852
1853
  /*
1854
   * Parse decrypted payload
1855
   */
1856
0
  bzero(&emsg, sizeof(emsg));
1857
0
  memcpy(&emsg, msg, sizeof(*msg));
1858
0
  emsg.msg_data = e;
1859
0
  emsg.msg_e = 1;
1860
0
  emsg.msg_parent = msg;
1861
0
  TAILQ_INIT(&emsg.msg_proposals);
1862
1863
0
  ret = ikev2_pld_payloads(env, &emsg, 0, ibuf_size(e),
1864
0
      pld->pld_nextpayload);
1865
1866
0
 done:
1867
0
  ibuf_free(e);
1868
1869
0
  return (ret);
1870
0
}
1871
1872
int
1873
ikev2_validate_cp(struct iked_message *msg, size_t offset, size_t left,
1874
    struct ikev2_cp *cp)
1875
9.77k
{
1876
9.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
9.77k
  if (left < sizeof(*cp)) {
1879
3.14k
    log_debug("%s: malformed payload: too short for header "
1880
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
3.14k
    return (-1);
1882
3.14k
  }
1883
6.63k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
6.63k
  return (0);
1886
9.77k
}
1887
1888
int
1889
ikev2_pld_cp(struct iked *env, struct ikev2_payload *pld,
1890
    struct iked_message *msg, size_t offset, size_t left)
1891
9.77k
{
1892
9.77k
  struct ikev2_cp    cp;
1893
9.77k
  struct ikev2_cfg  *cfg;
1894
9.77k
  struct iked_addr  *addr;
1895
9.77k
  struct sockaddr_in  *in4;
1896
9.77k
  struct sockaddr_in6 *in6;
1897
9.77k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
9.77k
  uint8_t     *ptr;
1899
9.77k
  size_t       len;
1900
9.77k
  int      cfg_type;
1901
1902
9.77k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
3.14k
    return (-1);
1904
1905
6.63k
  ptr = msgbuf + offset + sizeof(cp);
1906
6.63k
  len = left - sizeof(cp);
1907
1908
6.63k
  log_debug("%s: type %s length %zu",
1909
6.63k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
6.63k
  print_hex(ptr, 0, len);
1911
1912
14.4k
  while (len > 0) {
1913
9.33k
    if (len < sizeof(*cfg)) {
1914
352
      log_debug("%s: malformed payload: too short for cfg "
1915
352
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
352
      return (-1);
1917
352
    }
1918
8.98k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.98k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.98k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.98k
        betoh16(cfg->cfg_type),
1923
8.98k
        betoh16(cfg->cfg_length));
1924
1925
8.98k
    ptr += sizeof(*cfg);
1926
8.98k
    len -= sizeof(*cfg);
1927
1928
8.98k
    if (len < betoh16(cfg->cfg_length)) {
1929
1.12k
      log_debug("%s: malformed payload: too short for "
1930
1.12k
          "cfg_length (%zu < %u)", __func__, len,
1931
1.12k
          betoh16(cfg->cfg_length));
1932
1.12k
      return (-1);
1933
1.12k
    }
1934
1935
7.86k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.86k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.86k
    switch (cfg_type) {
1939
844
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.50k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.50k
      if (!ikev2_msg_frompeer(msg))
1942
735
        break;
1943
769
      if (betoh16(cfg->cfg_length) == 0)
1944
309
        break;
1945
      /* XXX multiple-valued */
1946
460
      if (betoh16(cfg->cfg_length) < 4) {
1947
6
        log_debug("%s: malformed payload: too short "
1948
6
            "for ipv4 addr (%u < %u)",
1949
6
            __func__, betoh16(cfg->cfg_length), 4);
1950
6
        return (-1);
1951
6
      }
1952
454
      switch(cfg_type) {
1953
355
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
355
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
238
          log_debug("%s: address already set", __func__);
1956
238
          goto skip;
1957
238
        }
1958
117
        break;
1959
117
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
99
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
51
          log_debug("%s: dns already set", __func__);
1962
51
          goto skip;
1963
51
        }
1964
48
        break;
1965
48
      default:
1966
0
        break;
1967
454
      }
1968
165
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
165
      addr->addr_af = AF_INET;
1973
165
      in4 = (struct sockaddr_in *)&addr->addr;
1974
165
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
165
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
165
      switch(cfg_type) {
1980
117
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
117
        msg->msg_parent->msg_cp_addr = addr;
1982
117
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
117
            print_addr(&addr->addr));
1984
117
        break;
1985
48
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
48
        msg->msg_parent->msg_cp_dns = addr;
1987
48
        log_debug("%s: IP4_DNS %s", __func__,
1988
48
            print_addr(&addr->addr));
1989
48
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
165
      }
1995
165
      break;
1996
2.25k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
3.06k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
3.06k
      if (!ikev2_msg_frompeer(msg))
1999
2.86k
        break;
2000
199
      if (betoh16(cfg->cfg_length) == 0)
2001
67
        break;
2002
      /* XXX multiple-valued */
2003
132
      if (betoh16(cfg->cfg_length) < 16) {
2004
5
        log_debug("%s: malformed payload: too short "
2005
5
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
5
            __func__, betoh16(cfg->cfg_length), 16);
2007
5
        return (-1);
2008
5
      }
2009
127
      switch(cfg_type) {
2010
87
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
87
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
40
        break;
2016
40
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
40
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
36
          log_debug("%s: dns already set", __func__);
2019
36
          goto skip;
2020
36
        }
2021
4
        break;
2022
127
      }
2023
44
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
44
      addr->addr_af = AF_INET6;
2028
44
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
44
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
44
      memcpy(&in6->sin6_addr, ptr, 16);
2034
44
      switch(cfg_type) {
2035
40
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
40
        msg->msg_parent->msg_cp_addr6 = addr;
2037
40
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
40
            print_addr(&addr->addr));
2039
40
        break;
2040
4
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
4
        msg->msg_parent->msg_cp_dns = addr;
2042
4
        log_debug("%s: IP6_DNS %s", __func__,
2043
4
            print_addr(&addr->addr));
2044
4
        break;
2045
0
      default:
2046
0
        log_debug("%s: cfg %s/%d", __func__,
2047
0
            print_addr(&addr->addr), ptr[16]);
2048
0
        break;
2049
44
      }
2050
44
      break;
2051
7.86k
    }
2052
2053
7.84k
 skip:
2054
7.84k
    ptr += betoh16(cfg->cfg_length);
2055
7.84k
    len -= betoh16(cfg->cfg_length);
2056
7.84k
  }
2057
2058
5.15k
  if (!ikev2_msg_frompeer(msg))
2059
4.95k
    return (0);
2060
2061
192
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
192
  return (0);
2064
5.15k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
17.1k
{
2070
17.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
17.1k
  if (left < sizeof(*hdr)) {
2073
7.15k
    log_debug("%s: malformed payload: too short for header "
2074
7.15k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
7.15k
    return (-1);
2076
7.15k
  }
2077
9.94k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.94k
  return (0);
2080
17.1k
}
2081
2082
int
2083
ikev2_pld_eap(struct iked *env, struct ikev2_payload *pld,
2084
    struct iked_message *msg, size_t offset, size_t left)
2085
17.1k
{
2086
17.1k
  struct eap_header    hdr;
2087
17.1k
  struct eap_message    *eap = NULL;
2088
17.1k
  const struct iked_sa    *sa = msg->msg_sa;
2089
17.1k
  size_t         len;
2090
2091
17.1k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
7.15k
    return (-1);
2093
9.94k
  len = betoh16(hdr.eap_length);
2094
2095
9.94k
  if (len < sizeof(*eap)) {
2096
3.45k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.45k
        print_map(hdr.eap_code, eap_code_map),
2098
3.45k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
6.48k
  } else {
2100
    /* Now try to get the indicated length */
2101
6.48k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
3.28k
      log_debug("%s: invalid EAP length", __func__);
2103
3.28k
      return (-1);
2104
3.28k
    }
2105
2106
3.20k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.20k
        print_map(eap->eap_code, eap_code_map),
2108
3.20k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.20k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.20k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.20k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.20k
  }
2115
2116
6.66k
  return (0);
2117
9.94k
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/imsg_util.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/imsg_util.c.html index a6da5db72..bf125d947 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/imsg_util.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/imsg_util.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/imsg_util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg_util.c,v 1.21 2023/07/18 15:07:41 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <netdb.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <fcntl.h>
30
#include <ctype.h>
31
#include <event.h>
32
33
#include "iked.h"
34
35
/*
36
 * Extending the imsg buffer API for internal use
37
 */
38
39
struct ibuf *
40
ibuf_new(const void *data, size_t len)
41
20.3k
{
42
20.3k
  struct ibuf *buf;
43
44
20.3k
  if ((buf = ibuf_dynamic(len,
45
20.3k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
20.3k
  if (len == 0)
49
1.41k
    return (buf);
50
51
18.9k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
18.9k
  } else {
57
18.9k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
18.9k
  }
62
63
18.9k
  return (buf);
64
18.9k
}
65
66
struct ibuf *
67
ibuf_static(void)
68
0
{
69
0
  return ibuf_open(IKED_MSGBUF_MAX);
70
0
}
71
72
size_t
73
ibuf_length(struct ibuf *buf)
74
0
{
75
0
  if (buf == NULL)
76
0
    return (0);
77
0
  return (ibuf_size(buf));
78
0
}
79
80
struct ibuf *
81
ibuf_getdata(struct ibuf *buf, size_t len)
82
0
{
83
0
  void  *data;
84
85
0
  if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
86
0
    return (NULL);
87
0
  buf->rpos += len;
88
89
0
  return (ibuf_new(data, len));
90
0
}
91
92
struct ibuf *
93
ibuf_dup(struct ibuf *buf)
94
0
{
95
0
  if (buf == NULL)
96
0
    return (NULL);
97
0
  return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
98
0
}
99
100
struct ibuf *
101
ibuf_random(size_t len)
102
0
{
103
0
  struct ibuf *buf;
104
0
  void    *ptr;
105
106
0
  if ((buf = ibuf_open(len)) == NULL)
107
0
    return (NULL);
108
0
  if ((ptr = ibuf_reserve(buf, len)) == NULL) {
109
0
    ibuf_free(buf);
110
0
    return (NULL);
111
0
  }
112
0
  arc4random_buf(ptr, len);
113
0
  return (buf);
114
0
}
115
116
int
117
ibuf_setsize(struct ibuf *buf, size_t len)
118
0
{
119
0
  if (len > buf->size)
120
0
    return (-1);
121
0
  buf->wpos = len;
122
0
  return (0);
123
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/imsg_util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: imsg_util.c,v 1.21 2023/07/18 15:07:41 claudio Exp $  */
2
3
/*
4
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/queue.h>
20
#include <sys/socket.h>
21
#include <sys/uio.h>
22
23
#include <netdb.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <string.h>
28
#include <errno.h>
29
#include <fcntl.h>
30
#include <ctype.h>
31
#include <event.h>
32
33
#include "iked.h"
34
35
/*
36
 * Extending the imsg buffer API for internal use
37
 */
38
39
struct ibuf *
40
ibuf_new(const void *data, size_t len)
41
20.4k
{
42
20.4k
  struct ibuf *buf;
43
44
20.4k
  if ((buf = ibuf_dynamic(len,
45
20.4k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
20.4k
  if (len == 0)
49
1.41k
    return (buf);
50
51
19.0k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
19.0k
  } else {
57
19.0k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
19.0k
  }
62
63
19.0k
  return (buf);
64
19.0k
}
65
66
struct ibuf *
67
ibuf_static(void)
68
0
{
69
0
  return ibuf_open(IKED_MSGBUF_MAX);
70
0
}
71
72
size_t
73
ibuf_length(struct ibuf *buf)
74
0
{
75
0
  if (buf == NULL)
76
0
    return (0);
77
0
  return (ibuf_size(buf));
78
0
}
79
80
struct ibuf *
81
ibuf_getdata(struct ibuf *buf, size_t len)
82
0
{
83
0
  void  *data;
84
85
0
  if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL)
86
0
    return (NULL);
87
0
  buf->rpos += len;
88
89
0
  return (ibuf_new(data, len));
90
0
}
91
92
struct ibuf *
93
ibuf_dup(struct ibuf *buf)
94
0
{
95
0
  if (buf == NULL)
96
0
    return (NULL);
97
0
  return (ibuf_new(ibuf_data(buf), ibuf_size(buf)));
98
0
}
99
100
struct ibuf *
101
ibuf_random(size_t len)
102
0
{
103
0
  struct ibuf *buf;
104
0
  void    *ptr;
105
106
0
  if ((buf = ibuf_open(len)) == NULL)
107
0
    return (NULL);
108
0
  if ((ptr = ibuf_reserve(buf, len)) == NULL) {
109
0
    ibuf_free(buf);
110
0
    return (NULL);
111
0
  }
112
0
  arc4random_buf(ptr, len);
113
0
  return (buf);
114
0
}
115
116
int
117
ibuf_setsize(struct ibuf *buf, size_t len)
118
0
{
119
0
  if (len > buf->size)
120
0
    return (-1);
121
0
  buf->wpos = len;
122
0
  return (0);
123
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/log.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/log.c.html index aa7c47bf4..8ef8b23a0 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/log.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/log.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/log.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: log.c,v 1.12 2017/03/21 12:06:55 bluhm Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <stdarg.h>
22
#include <string.h>
23
#include <syslog.h>
24
#include <errno.h>
25
#include <time.h>
26
27
static int   debug;
28
static int   verbose;
29
const char  *log_procname;
30
31
void  log_init(int, int);
32
void  log_procinit(const char *);
33
void  log_setverbose(int);
34
int log_getverbose(void);
35
void  log_warn(const char *, ...)
36
      __attribute__((__format__ (printf, 1, 2)));
37
void  log_warnx(const char *, ...)
38
      __attribute__((__format__ (printf, 1, 2)));
39
void  log_info(const char *, ...)
40
      __attribute__((__format__ (printf, 1, 2)));
41
void  log_debug(const char *, ...)
42
      __attribute__((__format__ (printf, 1, 2)));
43
void  logit(int, const char *, ...)
44
      __attribute__((__format__ (printf, 2, 3)));
45
void  vlog(int, const char *, va_list)
46
      __attribute__((__format__ (printf, 2, 0)));
47
__dead void fatal(const char *, ...)
48
      __attribute__((__format__ (printf, 1, 2)));
49
__dead void fatalx(const char *, ...)
50
      __attribute__((__format__ (printf, 1, 2)));
51
52
void
53
log_init(int n_debug, int facility)
54
0
{
55
0
  extern char *__progname;
56
57
0
  debug = n_debug;
58
0
  verbose = n_debug;
59
0
  log_procinit(__progname);
60
61
0
  if (!debug)
62
0
    openlog(__progname, LOG_PID | LOG_NDELAY, facility);
63
64
0
  tzset();
65
0
}
66
67
void
68
log_procinit(const char *procname)
69
0
{
70
0
  if (procname != NULL)
71
0
    log_procname = procname;
72
0
}
73
74
void
75
log_setverbose(int v)
76
0
{
77
0
  verbose = v;
78
0
}
79
80
int
81
log_getverbose(void)
82
147k
{
83
147k
  return (verbose);
84
147k
}
85
86
void
87
logit(int pri, const char *fmt, ...)
88
0
{
89
0
  va_list ap;
90
91
0
  va_start(ap, fmt);
92
0
  vlog(pri, fmt, ap);
93
0
  va_end(ap);
94
0
}
95
96
void
97
vlog(int pri, const char *fmt, va_list ap)
98
10.4k
{
99
10.4k
  char  *nfmt;
100
10.4k
  int  saved_errno = errno;
101
102
10.4k
  if (debug) {
103
    /* best effort in out of mem situations */
104
0
    if (asprintf(&nfmt, "%s\n", fmt) == -1) {
105
0
      vfprintf(stderr, fmt, ap);
106
0
      fprintf(stderr, "\n");
107
0
    } else {
108
0
      vfprintf(stderr, nfmt, ap);
109
0
      free(nfmt);
110
0
    }
111
0
    fflush(stderr);
112
0
  } else
113
10.4k
    vsyslog(pri, fmt, ap);
114
115
10.4k
  errno = saved_errno;
116
10.4k
}
117
118
void
119
log_warn(const char *emsg, ...)
120
0
{
121
0
  char    *nfmt;
122
0
  va_list    ap;
123
0
  int    saved_errno = errno;
124
125
  /* best effort to even work in out of memory situations */
126
0
  if (emsg == NULL)
127
0
    logit(LOG_ERR, "%s", strerror(saved_errno));
128
0
  else {
129
0
    va_start(ap, emsg);
130
131
0
    if (asprintf(&nfmt, "%s: %s", emsg,
132
0
        strerror(saved_errno)) == -1) {
133
      /* we tried it... */
134
0
      vlog(LOG_ERR, emsg, ap);
135
0
      logit(LOG_ERR, "%s", strerror(saved_errno));
136
0
    } else {
137
0
      vlog(LOG_ERR, nfmt, ap);
138
0
      free(nfmt);
139
0
    }
140
0
    va_end(ap);
141
0
  }
142
143
0
  errno = saved_errno;
144
0
}
145
146
void
147
log_warnx(const char *emsg, ...)
148
0
{
149
0
  va_list  ap;
150
151
0
  va_start(ap, emsg);
152
0
  vlog(LOG_ERR, emsg, ap);
153
0
  va_end(ap);
154
0
}
155
156
void
157
log_info(const char *emsg, ...)
158
10.4k
{
159
10.4k
  va_list  ap;
160
161
10.4k
  va_start(ap, emsg);
162
10.4k
  vlog(LOG_INFO, emsg, ap);
163
10.4k
  va_end(ap);
164
10.4k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
540k
{
169
540k
  va_list  ap;
170
171
540k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
540k
}
177
178
static void
179
vfatalc(int code, const char *emsg, va_list ap)
180
0
{
181
0
  static char s[BUFSIZ];
182
0
  const char  *sep;
183
184
0
  if (emsg != NULL) {
185
0
    (void)vsnprintf(s, sizeof(s), emsg, ap);
186
0
    sep = ": ";
187
0
  } else {
188
0
    s[0] = '\0';
189
0
    sep = "";
190
0
  }
191
0
  if (code)
192
0
    logit(LOG_CRIT, "%s: %s%s%s",
193
0
        log_procname, s, sep, strerror(code));
194
0
  else
195
0
    logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196
0
}
197
198
void
199
fatal(const char *emsg, ...)
200
0
{
201
0
  va_list ap;
202
203
0
  va_start(ap, emsg);
204
0
  vfatalc(errno, emsg, ap);
205
0
  va_end(ap);
206
0
  exit(1);
207
0
}
208
209
void
210
fatalx(const char *emsg, ...)
211
0
{
212
0
  va_list ap;
213
214
0
  va_start(ap, emsg);
215
0
  vfatalc(0, emsg, ap);
216
0
  va_end(ap);
217
0
  exit(1);
218
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/log.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: log.c,v 1.12 2017/03/21 12:06:55 bluhm Exp $  */
2
3
/*
4
 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <stdio.h>
20
#include <stdlib.h>
21
#include <stdarg.h>
22
#include <string.h>
23
#include <syslog.h>
24
#include <errno.h>
25
#include <time.h>
26
27
static int   debug;
28
static int   verbose;
29
const char  *log_procname;
30
31
void  log_init(int, int);
32
void  log_procinit(const char *);
33
void  log_setverbose(int);
34
int log_getverbose(void);
35
void  log_warn(const char *, ...)
36
      __attribute__((__format__ (printf, 1, 2)));
37
void  log_warnx(const char *, ...)
38
      __attribute__((__format__ (printf, 1, 2)));
39
void  log_info(const char *, ...)
40
      __attribute__((__format__ (printf, 1, 2)));
41
void  log_debug(const char *, ...)
42
      __attribute__((__format__ (printf, 1, 2)));
43
void  logit(int, const char *, ...)
44
      __attribute__((__format__ (printf, 2, 3)));
45
void  vlog(int, const char *, va_list)
46
      __attribute__((__format__ (printf, 2, 0)));
47
__dead void fatal(const char *, ...)
48
      __attribute__((__format__ (printf, 1, 2)));
49
__dead void fatalx(const char *, ...)
50
      __attribute__((__format__ (printf, 1, 2)));
51
52
void
53
log_init(int n_debug, int facility)
54
0
{
55
0
  extern char *__progname;
56
57
0
  debug = n_debug;
58
0
  verbose = n_debug;
59
0
  log_procinit(__progname);
60
61
0
  if (!debug)
62
0
    openlog(__progname, LOG_PID | LOG_NDELAY, facility);
63
64
0
  tzset();
65
0
}
66
67
void
68
log_procinit(const char *procname)
69
0
{
70
0
  if (procname != NULL)
71
0
    log_procname = procname;
72
0
}
73
74
void
75
log_setverbose(int v)
76
0
{
77
0
  verbose = v;
78
0
}
79
80
int
81
log_getverbose(void)
82
148k
{
83
148k
  return (verbose);
84
148k
}
85
86
void
87
logit(int pri, const char *fmt, ...)
88
0
{
89
0
  va_list ap;
90
91
0
  va_start(ap, fmt);
92
0
  vlog(pri, fmt, ap);
93
0
  va_end(ap);
94
0
}
95
96
void
97
vlog(int pri, const char *fmt, va_list ap)
98
10.4k
{
99
10.4k
  char  *nfmt;
100
10.4k
  int  saved_errno = errno;
101
102
10.4k
  if (debug) {
103
    /* best effort in out of mem situations */
104
0
    if (asprintf(&nfmt, "%s\n", fmt) == -1) {
105
0
      vfprintf(stderr, fmt, ap);
106
0
      fprintf(stderr, "\n");
107
0
    } else {
108
0
      vfprintf(stderr, nfmt, ap);
109
0
      free(nfmt);
110
0
    }
111
0
    fflush(stderr);
112
0
  } else
113
10.4k
    vsyslog(pri, fmt, ap);
114
115
10.4k
  errno = saved_errno;
116
10.4k
}
117
118
void
119
log_warn(const char *emsg, ...)
120
0
{
121
0
  char    *nfmt;
122
0
  va_list    ap;
123
0
  int    saved_errno = errno;
124
125
  /* best effort to even work in out of memory situations */
126
0
  if (emsg == NULL)
127
0
    logit(LOG_ERR, "%s", strerror(saved_errno));
128
0
  else {
129
0
    va_start(ap, emsg);
130
131
0
    if (asprintf(&nfmt, "%s: %s", emsg,
132
0
        strerror(saved_errno)) == -1) {
133
      /* we tried it... */
134
0
      vlog(LOG_ERR, emsg, ap);
135
0
      logit(LOG_ERR, "%s", strerror(saved_errno));
136
0
    } else {
137
0
      vlog(LOG_ERR, nfmt, ap);
138
0
      free(nfmt);
139
0
    }
140
0
    va_end(ap);
141
0
  }
142
143
0
  errno = saved_errno;
144
0
}
145
146
void
147
log_warnx(const char *emsg, ...)
148
0
{
149
0
  va_list  ap;
150
151
0
  va_start(ap, emsg);
152
0
  vlog(LOG_ERR, emsg, ap);
153
0
  va_end(ap);
154
0
}
155
156
void
157
log_info(const char *emsg, ...)
158
10.4k
{
159
10.4k
  va_list  ap;
160
161
10.4k
  va_start(ap, emsg);
162
10.4k
  vlog(LOG_INFO, emsg, ap);
163
10.4k
  va_end(ap);
164
10.4k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
543k
{
169
543k
  va_list  ap;
170
171
543k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
543k
}
177
178
static void
179
vfatalc(int code, const char *emsg, va_list ap)
180
0
{
181
0
  static char s[BUFSIZ];
182
0
  const char  *sep;
183
184
0
  if (emsg != NULL) {
185
0
    (void)vsnprintf(s, sizeof(s), emsg, ap);
186
0
    sep = ": ";
187
0
  } else {
188
0
    s[0] = '\0';
189
0
    sep = "";
190
0
  }
191
0
  if (code)
192
0
    logit(LOG_CRIT, "%s: %s%s%s",
193
0
        log_procname, s, sep, strerror(code));
194
0
  else
195
0
    logit(LOG_CRIT, "%s%s%s", log_procname, sep, s);
196
0
}
197
198
void
199
fatal(const char *emsg, ...)
200
0
{
201
0
  va_list ap;
202
203
0
  va_start(ap, emsg);
204
0
  vfatalc(errno, emsg, ap);
205
0
  va_end(ap);
206
0
  exit(1);
207
0
}
208
209
void
210
fatalx(const char *emsg, ...)
211
0
{
212
0
  va_list ap;
213
214
0
  va_start(ap, emsg);
215
0
  vfatalc(0, emsg, ap);
216
0
  va_end(ap);
217
0
  exit(1);
218
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/types.h.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/types.h.html index 0ec7812fb..989374846 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/types.h.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/types.h.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/types.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: types.h,v 1.52 2023/03/04 22:22:51 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_TYPES_H
21
#define IKED_TYPES_H
22
23
#ifndef IKED_USER
24
#define IKED_USER   "_iked"
25
#endif
26
27
#ifndef IKED_CONFIG
28
#define IKED_CONFIG   "/etc/iked.conf"
29
#endif
30
31
#define IKED_SOCKET   "/var/run/iked.sock"
32
33
#ifndef IKED_CA
34
#define IKED_CA     "/etc/iked/"
35
#endif
36
37
#define IKED_CA_DIR   "ca/"
38
#define IKED_CRL_DIR    "crls/"
39
#define IKED_CERT_DIR   "certs/"
40
#define IKED_PUBKEY_DIR   "pubkeys/"
41
#define IKED_PRIVKEY    IKED_CA "private/local.key"
42
#define IKED_PUBKEY   "local.pub"
43
44
#define IKED_VENDOR_ID    "OpenIKED-"
45
46
#define IKED_OCSP_RESPCERT  "ocsp/responder.crt"
47
48
#define IKED_OPT_VERBOSE  0x00000001
49
#define IKED_OPT_NOACTION 0x00000002
50
#define IKED_OPT_PASSIVE  0x00000004
51
52
#define IKED_IKE_PORT   500
53
#define IKED_NATT_PORT    4500
54
55
#define IKED_NONCE_MIN    16  /* XXX 128 bits */
56
#define IKED_NONCE_SIZE   32  /* XXX 256 bits */
57
58
0
#define IKED_COOKIE_MIN   1  /* min 1 bytes */
59
0
#define IKED_COOKIE_MAX   64  /* max 64 bytes */
60
61
0
#define IKED_COOKIE2_MIN  8  /* min 8 bytes */
62
0
#define IKED_COOKIE2_MAX  64  /* max 64 bytes */
63
64
#define IKED_ID_SIZE    1024  /* XXX should be dynamic */
65
#define IKED_PSK_SIZE   1024  /* XXX should be dynamic */
66
20.3k
#define IKED_MSGBUF_MAX   8192
67
#define IKED_CFG_MAX    16  /* maximum CP attributes */
68
#define IKED_IPPROTO_MAX  16
69
#define IKED_TAG_SIZE   64
70
718k
#define IKED_CYCLE_BUFFERS  8  /* # of static buffers for mapping */
71
#define IKED_PASSWORD_SIZE  256 /* limited by most EAP types */
72
73
#define IKED_LIFETIME_BYTES 4294967296ULL /* 4 GB */
74
#define IKED_LIFETIME_SECONDS 10800     /* 3 hours */
75
76
196k
#define IKED_E      0x1000  /* Decrypted flag */
77
78
struct iked_constmap {
79
  unsigned int   cm_type;
80
  const char  *cm_name;
81
  const char  *cm_descr;
82
};
83
84
struct iked_transform {
85
  uint8_t        xform_type;
86
  uint16_t       xform_id;
87
  uint16_t       xform_length;
88
  uint16_t       xform_keylength;
89
  unsigned int       xform_score;
90
  struct iked_constmap    *xform_map;
91
};
92
93
enum imsg_type {
94
  IMSG_NONE,
95
  IMSG_CTL_OK,
96
  IMSG_CTL_FAIL,
97
  IMSG_CTL_VERBOSE,
98
  IMSG_CTL_NOTIFY,
99
  IMSG_CTL_RELOAD,
100
  IMSG_CTL_RESET,
101
  IMSG_CTL_COUPLE,
102
  IMSG_CTL_DECOUPLE,
103
  IMSG_CTL_ACTIVE,
104
  IMSG_CTL_PASSIVE,
105
  IMSG_CTL_RESET_ID,
106
  IMSG_CTL_SHOW_SA,
107
  IMSG_CTL_STATIC,
108
  IMSG_COMPILE,
109
  IMSG_UDP_SOCKET,
110
  IMSG_PFKEY_SOCKET,
111
  IMSG_IKE_MESSAGE,
112
  IMSG_CFG_POLICY,
113
  IMSG_CFG_FLOW,
114
  IMSG_CFG_USER,
115
  IMSG_CERTREQ,
116
  IMSG_CERT,
117
  IMSG_CERTVALID,
118
  IMSG_CERTINVALID,
119
  IMSG_CERT_PARTIAL_CHAIN,
120
  IMSG_SCERT,
121
  IMSG_IF_ADDADDR,
122
  IMSG_IF_DELADDR,
123
  IMSG_VROUTE_ADD,
124
  IMSG_VROUTE_DEL,
125
  IMSG_VROUTE_CLONE,
126
  IMSG_VDNS_ADD,
127
  IMSG_VDNS_DEL,
128
  IMSG_OCSP_FD,
129
  IMSG_OCSP_CFG,
130
  IMSG_AUTH,
131
  IMSG_PRIVKEY,
132
  IMSG_PUBKEY,
133
  IMSG_CTL_SHOW_CERTSTORE,
134
  IMSG_CTL_SHOW_STATS,
135
  IMSG_CTL_PROCFD,
136
};
137
138
enum privsep_procid {
139
  PROC_PARENT = 0,
140
  PROC_CONTROL,
141
  PROC_CERT,
142
  PROC_IKEV2,
143
  PROC_MAX
144
};
145
146
enum flushmode {
147
  RESET_RELOAD  = 0,
148
  RESET_ALL,
149
  RESET_CA,
150
  RESET_POLICY,
151
  RESET_SA,
152
  RESET_USER,
153
};
154
155
#ifndef nitems
156
#define nitems(_a)   (sizeof((_a)) / sizeof((_a)[0]))
157
#endif
158
159
#endif /* IKED_TYPES_H */
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/types.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: types.h,v 1.52 2023/03/04 22:22:51 tobhe Exp $  */
2
3
/*
4
 * Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#ifndef IKED_TYPES_H
21
#define IKED_TYPES_H
22
23
#ifndef IKED_USER
24
#define IKED_USER   "_iked"
25
#endif
26
27
#ifndef IKED_CONFIG
28
#define IKED_CONFIG   "/etc/iked.conf"
29
#endif
30
31
#define IKED_SOCKET   "/var/run/iked.sock"
32
33
#ifndef IKED_CA
34
#define IKED_CA     "/etc/iked/"
35
#endif
36
37
#define IKED_CA_DIR   "ca/"
38
#define IKED_CRL_DIR    "crls/"
39
#define IKED_CERT_DIR   "certs/"
40
#define IKED_PUBKEY_DIR   "pubkeys/"
41
#define IKED_PRIVKEY    IKED_CA "private/local.key"
42
#define IKED_PUBKEY   "local.pub"
43
44
#define IKED_VENDOR_ID    "OpenIKED-"
45
46
#define IKED_OCSP_RESPCERT  "ocsp/responder.crt"
47
48
#define IKED_OPT_VERBOSE  0x00000001
49
#define IKED_OPT_NOACTION 0x00000002
50
#define IKED_OPT_PASSIVE  0x00000004
51
52
#define IKED_IKE_PORT   500
53
#define IKED_NATT_PORT    4500
54
55
#define IKED_NONCE_MIN    16  /* XXX 128 bits */
56
#define IKED_NONCE_SIZE   32  /* XXX 256 bits */
57
58
0
#define IKED_COOKIE_MIN   1  /* min 1 bytes */
59
0
#define IKED_COOKIE_MAX   64  /* max 64 bytes */
60
61
0
#define IKED_COOKIE2_MIN  8  /* min 8 bytes */
62
0
#define IKED_COOKIE2_MAX  64  /* max 64 bytes */
63
64
#define IKED_ID_SIZE    1024  /* XXX should be dynamic */
65
#define IKED_PSK_SIZE   1024  /* XXX should be dynamic */
66
20.4k
#define IKED_MSGBUF_MAX   8192
67
#define IKED_CFG_MAX    16  /* maximum CP attributes */
68
#define IKED_IPPROTO_MAX  16
69
#define IKED_TAG_SIZE   64
70
722k
#define IKED_CYCLE_BUFFERS  8  /* # of static buffers for mapping */
71
#define IKED_PASSWORD_SIZE  256 /* limited by most EAP types */
72
73
#define IKED_LIFETIME_BYTES 4294967296ULL /* 4 GB */
74
#define IKED_LIFETIME_SECONDS 10800     /* 3 hours */
75
76
197k
#define IKED_E      0x1000  /* Decrypted flag */
77
78
struct iked_constmap {
79
  unsigned int   cm_type;
80
  const char  *cm_name;
81
  const char  *cm_descr;
82
};
83
84
struct iked_transform {
85
  uint8_t        xform_type;
86
  uint16_t       xform_id;
87
  uint16_t       xform_length;
88
  uint16_t       xform_keylength;
89
  unsigned int       xform_score;
90
  struct iked_constmap    *xform_map;
91
};
92
93
enum imsg_type {
94
  IMSG_NONE,
95
  IMSG_CTL_OK,
96
  IMSG_CTL_FAIL,
97
  IMSG_CTL_VERBOSE,
98
  IMSG_CTL_NOTIFY,
99
  IMSG_CTL_RELOAD,
100
  IMSG_CTL_RESET,
101
  IMSG_CTL_COUPLE,
102
  IMSG_CTL_DECOUPLE,
103
  IMSG_CTL_ACTIVE,
104
  IMSG_CTL_PASSIVE,
105
  IMSG_CTL_RESET_ID,
106
  IMSG_CTL_SHOW_SA,
107
  IMSG_CTL_STATIC,
108
  IMSG_COMPILE,
109
  IMSG_UDP_SOCKET,
110
  IMSG_PFKEY_SOCKET,
111
  IMSG_IKE_MESSAGE,
112
  IMSG_CFG_POLICY,
113
  IMSG_CFG_FLOW,
114
  IMSG_CFG_USER,
115
  IMSG_CERTREQ,
116
  IMSG_CERT,
117
  IMSG_CERTVALID,
118
  IMSG_CERTINVALID,
119
  IMSG_CERT_PARTIAL_CHAIN,
120
  IMSG_SCERT,
121
  IMSG_IF_ADDADDR,
122
  IMSG_IF_DELADDR,
123
  IMSG_VROUTE_ADD,
124
  IMSG_VROUTE_DEL,
125
  IMSG_VROUTE_CLONE,
126
  IMSG_VDNS_ADD,
127
  IMSG_VDNS_DEL,
128
  IMSG_OCSP_FD,
129
  IMSG_OCSP_CFG,
130
  IMSG_AUTH,
131
  IMSG_PRIVKEY,
132
  IMSG_PUBKEY,
133
  IMSG_CTL_SHOW_CERTSTORE,
134
  IMSG_CTL_SHOW_STATS,
135
  IMSG_CTL_PROCFD,
136
};
137
138
enum privsep_procid {
139
  PROC_PARENT = 0,
140
  PROC_CONTROL,
141
  PROC_CERT,
142
  PROC_IKEV2,
143
  PROC_MAX
144
};
145
146
enum flushmode {
147
  RESET_RELOAD  = 0,
148
  RESET_ALL,
149
  RESET_CA,
150
  RESET_POLICY,
151
  RESET_SA,
152
  RESET_USER,
153
};
154
155
#ifndef nitems
156
#define nitems(_a)   (sizeof((_a)) / sizeof((_a)[0]))
157
#endif
158
159
#endif /* IKED_TYPES_H */
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/util.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/util.c.html index c58d14a0a..999f87e04 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/util.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/iked/util.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/iked/util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: util.c,v 1.43 2023/07/28 11:23:03 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <netinet/ip_ipsp.h>
27
28
#include <netdb.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <unistd.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <limits.h>
35
#include <fcntl.h>
36
#include <ctype.h>
37
#include <event.h>
38
39
#include "iked.h"
40
#include "ikev2.h"
41
42
int
43
socket_af(struct sockaddr *sa, in_port_t port)
44
0
{
45
0
  errno = 0;
46
0
  switch (sa->sa_family) {
47
0
  case AF_INET:
48
0
    ((struct sockaddr_in *)sa)->sin_port = port;
49
#ifdef HAVE_SOCKADDR_SA_LEN
50
    ((struct sockaddr_in *)sa)->sin_len =
51
        sizeof(struct sockaddr_in);
52
#endif
53
0
    break;
54
0
  case AF_INET6:
55
0
    ((struct sockaddr_in6 *)sa)->sin6_port = port;
56
#ifdef HAVE_SOCKADDR_SA_LEN
57
    ((struct sockaddr_in6 *)sa)->sin6_len =
58
        sizeof(struct sockaddr_in6);
59
#endif
60
0
    break;
61
0
  default:
62
0
    errno = EPFNOSUPPORT;
63
0
    return (-1);
64
0
  }
65
66
0
  return (0);
67
0
}
68
69
in_port_t
70
socket_getport(struct sockaddr *sa)
71
14.0k
{
72
14.0k
  switch (sa->sa_family) {
73
11.7k
  case AF_INET:
74
11.7k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
2.24k
  case AF_INET6:
76
2.24k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
14.0k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
14.0k
}
84
85
int
86
socket_setport(struct sockaddr *sa, in_port_t port)
87
0
{
88
0
  switch (sa->sa_family) {
89
0
  case AF_INET:
90
0
    ((struct sockaddr_in *)sa)->sin_port = htons(port);
91
0
    break;
92
0
  case AF_INET6:
93
0
    ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
94
0
    break;
95
0
  default:
96
0
    return (-1);
97
0
  }
98
0
  return (0);
99
0
}
100
101
int
102
socket_getaddr(int s, struct sockaddr_storage *ss)
103
0
{
104
0
  socklen_t sslen = sizeof(*ss);
105
106
0
  return (getsockname(s, (struct sockaddr *)ss, &sslen));
107
0
}
108
109
int
110
socket_bypass(int s, struct sockaddr *sa)
111
0
{
112
#if defined(__OpenBSD__)
113
  int  v, *a;
114
  int  a4[] = {
115
        IPPROTO_IP,
116
        IP_AUTH_LEVEL,
117
        IP_ESP_TRANS_LEVEL,
118
        IP_ESP_NETWORK_LEVEL,
119
#ifdef IPV6_IPCOMP_LEVEL
120
        IP_IPCOMP_LEVEL
121
#endif
122
  };
123
  int  a6[] = {
124
        IPPROTO_IPV6,
125
        IPV6_AUTH_LEVEL,
126
        IPV6_ESP_TRANS_LEVEL,
127
        IPV6_ESP_NETWORK_LEVEL,
128
#ifdef IPV6_IPCOMP_LEVEL
129
        IPV6_IPCOMP_LEVEL
130
#endif
131
  };
132
133
  switch (sa->sa_family) {
134
  case AF_INET:
135
    a = a4;
136
    break;
137
  case AF_INET6:
138
    a = a6;
139
    break;
140
  default:
141
    log_warn("%s: invalid address family", __func__);
142
    return (-1);
143
  }
144
145
  v = IPSEC_LEVEL_BYPASS;
146
  if (setsockopt(s, a[0], a[1], &v, sizeof(v)) == -1) {
147
    log_warn("%s: AUTH_LEVEL", __func__);
148
    return (-1);
149
  }
150
  if (setsockopt(s, a[0], a[2], &v, sizeof(v)) == -1) {
151
    log_warn("%s: ESP_TRANS_LEVEL", __func__);
152
    return (-1);
153
  }
154
  if (setsockopt(s, a[0], a[3], &v, sizeof(v)) == -1) {
155
    log_warn("%s: ESP_NETWORK_LEVEL", __func__);
156
    return (-1);
157
  }
158
#ifdef IP_IPCOMP_LEVEL
159
  if (setsockopt(s, a[0], a[4], &v, sizeof(v)) == -1) {
160
    log_warn("%s: IPCOMP_LEVEL", __func__);
161
    return (-1);
162
  }
163
#endif
164
#else /* __OpenBSD__ */
165
0
  int *a;
166
0
  int  a4[] = {
167
0
        IPPROTO_IP,
168
0
        IP_IPSEC_POLICY
169
0
  };
170
0
  int  a6[] = {
171
0
        IPPROTO_IPV6,
172
0
        IPV6_IPSEC_POLICY,
173
0
  };
174
0
  struct sadb_x_policy pol = {
175
0
        SADB_UPDATE,
176
0
        SADB_EXT_SENSITIVITY,
177
0
        IPSEC_POLICY_BYPASS,
178
0
        0, 0, 0, 0
179
0
  };
180
181
0
  switch (sa->sa_family) {
182
0
  case AF_INET:
183
0
    a = a4;
184
0
    break;
185
0
  case AF_INET6:
186
0
    a = a6;
187
0
    break;
188
0
  default:
189
0
    log_warn("%s: invalid address family", __func__);
190
0
    return (-1);
191
0
  }
192
193
0
  pol.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
194
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
195
0
    log_warn("%s: IPSEC_DIR_INBOUND", __func__);
196
0
    return (-1);
197
0
  }
198
0
  pol.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
199
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
200
0
    log_warn("%s: IPSEC_DIR_OUTBOUND", __func__);
201
0
    return (-1);
202
0
  }
203
0
#endif /* !__OpenBSD__ */
204
205
0
  return (0);
206
0
}
207
208
int
209
udp_bind(struct sockaddr *sa, in_port_t port)
210
0
{
211
0
  int  s, val;
212
213
0
  if (socket_af(sa, port) == -1) {
214
0
    log_warn("%s: failed to set UDP port", __func__);
215
0
    return (-1);
216
0
  }
217
218
0
  if ((s = socket(sa->sa_family,
219
0
      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1) {
220
0
    log_warn("%s: failed to get UDP socket", __func__);
221
0
    return (-1);
222
0
  }
223
224
  /* Skip IPsec processing (don't encrypt) for IKE messages */
225
0
  if (socket_bypass(s, sa) == -1) {
226
0
    log_warn("%s: failed to bypass IPsec on IKE socket",
227
0
        __func__);
228
0
    goto bad;
229
0
  }
230
231
0
  val = 1;
232
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) {
233
0
    log_warn("%s: failed to set reuseport", __func__);
234
0
    goto bad;
235
0
  }
236
0
  val = 1;
237
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) {
238
0
    log_warn("%s: failed to set reuseaddr", __func__);
239
0
    goto bad;
240
0
  }
241
242
0
  if (sa->sa_family == AF_INET) {
243
0
#if defined(IP_RECVORIGDSTADDR)
244
0
    val = 1;
245
0
    if (setsockopt(s, IPPROTO_IP, IP_RECVORIGDSTADDR,
246
0
        &val, sizeof(int)) == -1) {
247
0
      log_warn("%s: failed to set IPv4 packet info",
248
0
          __func__);
249
0
      goto bad;
250
0
    }
251
#elif defined(IP_RECVDSTADDR)
252
    val = 1;
253
    if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
254
        &val, sizeof(int)) == -1) {
255
      log_warn("%s: failed to set IPv4 packet info",
256
          __func__);
257
      goto bad;
258
    }
259
#endif
260
0
  } else {
261
0
#ifdef IPV6_RECVPKTINFO
262
0
    val = 1;
263
0
    if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO,
264
0
        &val, sizeof(int)) == -1) {
265
0
      log_warn("%s: failed to set IPv6 packet info",
266
0
          __func__);
267
0
      goto bad;
268
0
    }
269
0
#endif
270
0
  }
271
272
0
  if (bind(s, sa, SA_LEN(sa)) == -1) {
273
0
    log_warn("%s: failed to bind UDP socket", __func__);
274
0
    goto bad;
275
0
  }
276
277
0
  return (s);
278
0
 bad:
279
0
  close(s);
280
0
  return (-1);
281
0
}
282
283
int
284
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
285
0
{
286
0
  struct sockaddr_in  *a4, *b4;
287
0
  struct sockaddr_in6 *a6, *b6;
288
0
  uint32_t     av[4], bv[4], mv[4];
289
290
0
  if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
291
0
    return (0);
292
0
  else if (a->sa_family > b->sa_family)
293
0
    return (1);
294
0
  else if (a->sa_family < b->sa_family)
295
0
    return (-1);
296
297
0
  if (prefixlen == -1)
298
0
    memset(&mv, 0xff, sizeof(mv));
299
300
0
  switch (a->sa_family) {
301
0
  case AF_INET:
302
0
    a4 = (struct sockaddr_in *)a;
303
0
    b4 = (struct sockaddr_in *)b;
304
305
0
    av[0] = a4->sin_addr.s_addr;
306
0
    bv[0] = b4->sin_addr.s_addr;
307
0
    if (prefixlen != -1)
308
0
      mv[0] = prefixlen2mask(prefixlen);
309
310
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
311
0
      return (1);
312
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
313
0
      return (-1);
314
0
    break;
315
0
  case AF_INET6:
316
0
    a6 = (struct sockaddr_in6 *)a;
317
0
    b6 = (struct sockaddr_in6 *)b;
318
319
0
    memcpy(&av, &a6->sin6_addr.s6_addr, 16);
320
0
    memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
321
0
    if (prefixlen != -1)
322
0
      prefixlen2mask6(prefixlen, mv);
323
324
0
    if ((av[3] & mv[3]) > (bv[3] & mv[3]))
325
0
      return (1);
326
0
    if ((av[3] & mv[3]) < (bv[3] & mv[3]))
327
0
      return (-1);
328
0
    if ((av[2] & mv[2]) > (bv[2] & mv[2]))
329
0
      return (1);
330
0
    if ((av[2] & mv[2]) < (bv[2] & mv[2]))
331
0
      return (-1);
332
0
    if ((av[1] & mv[1]) > (bv[1] & mv[1]))
333
0
      return (1);
334
0
    if ((av[1] & mv[1]) < (bv[1] & mv[1]))
335
0
      return (-1);
336
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
337
0
      return (1);
338
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
339
0
      return (-1);
340
0
    break;
341
0
  }
342
343
0
  return (0);
344
0
}
345
346
ssize_t
347
sendtofrom(int s, void *buf, size_t len, int flags, struct sockaddr *to,
348
    socklen_t tolen, struct sockaddr *from, socklen_t fromlen)
349
0
{
350
0
  struct iovec     iov;
351
0
  struct msghdr    msg;
352
0
  struct cmsghdr    *cmsg;
353
#ifdef IP_SENDSRCADDR
354
  struct sockaddr_in  *in;
355
#endif
356
0
#ifdef IPV6_PKTINFO
357
0
  struct in6_pktinfo  *pkt6;
358
0
  struct sockaddr_in6 *in6;
359
0
#endif
360
0
  union {
361
0
    struct cmsghdr  hdr;
362
0
    char    inbuf[CMSG_SPACE(sizeof(struct in_addr))];
363
0
    char    in6buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
364
0
  } cmsgbuf;
365
366
0
  bzero(&msg, sizeof(msg));
367
0
  bzero(&cmsgbuf, sizeof(cmsgbuf));
368
369
0
  iov.iov_base = buf;
370
0
  iov.iov_len = len;
371
0
  msg.msg_iov = &iov;
372
0
  msg.msg_iovlen = 1;
373
0
  msg.msg_name = to;
374
0
  msg.msg_namelen = tolen;
375
0
  msg.msg_controllen = 0;
376
377
0
  switch (to->sa_family) {
378
0
  case AF_INET:
379
#ifdef IP_SENDSRCADDR
380
    in = (struct sockaddr_in *)from;
381
    if (in->sin_addr.s_addr == INADDR_ANY)
382
      break;
383
    msg.msg_control = &cmsgbuf;
384
    msg.msg_controllen += sizeof(cmsgbuf.inbuf);
385
    cmsg = CMSG_FIRSTHDR(&msg);
386
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
387
    cmsg->cmsg_level = IPPROTO_IP;
388
    cmsg->cmsg_type = IP_SENDSRCADDR;
389
    memcpy(CMSG_DATA(cmsg), &in->sin_addr, sizeof(struct in_addr));
390
#endif
391
0
    break;
392
0
  case AF_INET6:
393
0
#ifdef IPV6_PKTINFO
394
0
    msg.msg_control = &cmsgbuf;
395
0
    msg.msg_controllen += sizeof(cmsgbuf.in6buf);
396
0
    cmsg = CMSG_FIRSTHDR(&msg);
397
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
398
0
    cmsg->cmsg_level = IPPROTO_IPV6;
399
0
    cmsg->cmsg_type = IPV6_PKTINFO;
400
0
    in6 = (struct sockaddr_in6 *)from;
401
0
    pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
402
0
    pkt6->ipi6_addr = in6->sin6_addr;
403
0
#endif
404
0
    break;
405
0
  }
406
407
0
  return sendmsg(s, &msg, flags);
408
0
}
409
410
ssize_t
411
recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
412
    socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen)
413
0
{
414
0
  struct iovec     iov;
415
0
  struct msghdr    msg;
416
0
  struct cmsghdr    *cmsg;
417
#if !defined(IP_RECVORIGDSTADDR) && defined(IP_RECVDSTADDR)
418
  struct sockaddr_in  *in;
419
#endif
420
0
#ifdef IPV6_PKTINFO
421
0
  struct in6_pktinfo  *pkt6;
422
0
  struct sockaddr_in6 *in6;
423
0
#endif
424
0
  ssize_t      ret;
425
0
  union {
426
0
    struct cmsghdr hdr;
427
0
    char  buf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
428
0
  } cmsgbuf;
429
430
0
  bzero(&msg, sizeof(msg));
431
0
  bzero(&cmsgbuf.buf, sizeof(cmsgbuf.buf));
432
433
0
  iov.iov_base = buf;
434
0
  iov.iov_len = len;
435
0
  msg.msg_iov = &iov;
436
0
  msg.msg_iovlen = 1;
437
0
  msg.msg_name = from;
438
0
  msg.msg_namelen = *fromlen;
439
0
  msg.msg_control = &cmsgbuf.buf;
440
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
441
442
0
  if ((ret = recvmsg(s, &msg, flags)) == -1)
443
0
    return (-1);
444
445
0
  *fromlen = SA_LEN(from);
446
447
0
  if (getsockname(s, to, tolen) != 0)
448
0
    *tolen = 0;
449
450
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
451
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
452
0
    switch (from->sa_family) {
453
0
    case AF_INET:
454
0
#if defined(IP_RECVORIGDSTADDR)
455
0
      if (cmsg->cmsg_level == IPPROTO_IP &&
456
0
          cmsg->cmsg_type == IP_RECVORIGDSTADDR) {
457
0
        memcpy(to, CMSG_DATA(cmsg),
458
0
            sizeof(struct sockaddr_in));
459
0
      }
460
#elif defined(IP_RECVDSTADDR)
461
      if (cmsg->cmsg_level == IPPROTO_IP &&
462
          cmsg->cmsg_type == IP_RECVDSTADDR) {
463
        in = (struct sockaddr_in *)to;
464
        in->sin_family = AF_INET;
465
#ifdef HAVE_SOCKADDR_SA_LEN
466
        in->sin_len = *tolen = sizeof(*in);
467
#endif
468
        memcpy(&in->sin_addr, CMSG_DATA(cmsg),
469
            sizeof(struct in_addr));
470
      }
471
#endif /* defined(IP_RECVDSTADDR) */
472
0
      break;
473
0
    case AF_INET6:
474
0
#ifdef IPV6_PKTINFO
475
0
      if (cmsg->cmsg_level == IPPROTO_IPV6 &&
476
0
          cmsg->cmsg_type == IPV6_PKTINFO) {
477
0
        in6 = (struct sockaddr_in6 *)to;
478
0
        in6->sin6_family = AF_INET6;
479
#ifdef HAVE_SOCKADDR_SA_LEN
480
        in6->sin6_len = *tolen = sizeof(*in6);
481
#endif
482
0
        pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
483
0
        memcpy(&in6->sin6_addr, &pkt6->ipi6_addr,
484
0
            sizeof(struct in6_addr));
485
0
        if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
486
0
          in6->sin6_scope_id =
487
0
              pkt6->ipi6_ifindex;
488
0
      }
489
0
#endif
490
0
      break;
491
0
    }
492
0
  }
493
494
0
  return (ret);
495
0
}
496
497
const char *
498
print_spi(uint64_t spi, int size)
499
35.7k
{
500
35.7k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
35.7k
  static int     i = 0;
502
35.7k
  char      *ptr;
503
504
35.7k
  ptr = buf[i];
505
506
35.7k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
349
  case 4:
511
349
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
349
    break;
513
26.2k
  case 8:
514
26.2k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
26.2k
    break;
516
9.10k
  default:
517
9.10k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
9.10k
    break;
519
35.7k
  }
520
521
35.7k
  if (++i >= IKED_CYCLE_BUFFERS)
522
4.46k
    i = 0;
523
524
35.7k
  return (ptr);
525
35.7k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
669k
{
530
669k
  unsigned int     i;
531
669k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
669k
  static int     idx = 0;
533
669k
  const char    *name = NULL;
534
535
669k
  if (idx >= IKED_CYCLE_BUFFERS)
536
83.6k
    idx = 0;
537
669k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
14.1M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
13.4M
    if (map[i].cm_type == type)
541
465k
      name = map[i].cm_name;
542
13.4M
  }
543
544
669k
  if (name == NULL)
545
203k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
465k
  else
547
465k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
669k
  return (buf[idx++]);
550
669k
}
551
552
void
553
lc_idtype(char *str)
554
0
{
555
0
  for (; *str != '\0' && *str != '/'; str++)
556
0
    *str = tolower((unsigned char)*str);
557
0
}
558
559
void
560
print_hex(const uint8_t *buf, off_t offset, size_t length)
561
147k
{
562
147k
  unsigned int   i;
563
564
147k
  if (log_getverbose() < 3 || !length)
565
147k
    return;
566
567
0
  for (i = 0; i < length; i++) {
568
0
    if (i && (i % 4) == 0) {
569
0
      if ((i % 32) == 0)
570
0
        print_debug("\n");
571
0
      else
572
0
        print_debug(" ");
573
0
    }
574
0
    print_debug("%02x", buf[offset + i]);
575
0
  }
576
0
  print_debug("\n");
577
0
}
578
579
void
580
print_hexval(const uint8_t *buf, off_t offset, size_t length)
581
0
{
582
0
  unsigned int   i;
583
584
0
  if (log_getverbose() < 2 || !length)
585
0
    return;
586
587
0
  print_debug("0x");
588
0
  for (i = 0; i < length; i++)
589
0
    print_debug("%02x", buf[offset + i]);
590
0
  print_debug("\n");
591
0
}
592
593
void
594
print_hexbuf(struct ibuf *ibuf)
595
0
{
596
0
  print_hex(ibuf_data(ibuf), 0, ibuf_size(ibuf));
597
0
}
598
599
const char *
600
print_bits(unsigned short v, unsigned char *bits)
601
0
{
602
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
603
0
  static int   idx = 0;
604
0
  unsigned int   i, any = 0, j = 0;
605
0
  unsigned char  c;
606
607
0
  if (!bits)
608
0
    return ("");
609
610
0
  if (++idx >= IKED_CYCLE_BUFFERS)
611
0
    idx = 0;
612
613
0
  bzero(buf[idx], sizeof(buf[idx]));
614
615
0
  bits++;
616
0
  while ((i = *bits++)) {
617
0
    if (v & (1 << (i-1))) {
618
0
      if (any) {
619
0
        buf[idx][j++] = ',';
620
0
        if (j >= sizeof(buf[idx]))
621
0
          return (buf[idx]);
622
0
      }
623
0
      any = 1;
624
0
      for (; (c = *bits) > 32; bits++) {
625
0
        buf[idx][j++] = tolower((unsigned char)c);
626
0
        if (j >= sizeof(buf[idx]))
627
0
          return (buf[idx]);
628
0
      }
629
0
    } else
630
0
      for (; *bits > 32; bits++)
631
0
        ;
632
0
  }
633
634
0
  return (buf[idx]);
635
0
}
636
637
uint8_t
638
mask2prefixlen(struct sockaddr *sa)
639
0
{
640
0
  struct sockaddr_in  *sa_in = (struct sockaddr_in *)sa;
641
0
  in_addr_t    ina = sa_in->sin_addr.s_addr;
642
643
0
  if (ina == 0)
644
0
    return (0);
645
0
  else
646
0
    return (33 - ffs(ntohl(ina)));
647
0
}
648
649
uint8_t
650
mask2prefixlen6(struct sockaddr *sa)
651
0
{
652
0
  struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
653
0
  uint8_t     *ap, *ep;
654
0
  unsigned int     l = 0;
655
656
  /*
657
   * sin6_len is the size of the sockaddr so substract the offset of
658
   * the possibly truncated sin6_addr struct.
659
   */
660
0
  ap = (uint8_t *)&sa_in6->sin6_addr;
661
0
  ep = (uint8_t *)sa_in6 + SA_LEN(sa);
662
0
  for (; ap < ep; ap++) {
663
    /* this "beauty" is adopted from sbin/route/show.c ... */
664
0
    switch (*ap) {
665
0
    case 0xff:
666
0
      l += 8;
667
0
      break;
668
0
    case 0xfe:
669
0
      l += 7;
670
0
      goto done;
671
0
    case 0xfc:
672
0
      l += 6;
673
0
      goto done;
674
0
    case 0xf8:
675
0
      l += 5;
676
0
      goto done;
677
0
    case 0xf0:
678
0
      l += 4;
679
0
      goto done;
680
0
    case 0xe0:
681
0
      l += 3;
682
0
      goto done;
683
0
    case 0xc0:
684
0
      l += 2;
685
0
      goto done;
686
0
    case 0x80:
687
0
      l += 1;
688
0
      goto done;
689
0
    case 0x00:
690
0
      goto done;
691
0
    default:
692
0
      fatalx("non contiguous inet6 netmask");
693
0
    }
694
0
  }
695
696
0
done:
697
0
  if (l > sizeof(struct in6_addr) * 8)
698
0
    fatalx("%s: prefixlen %d out of bound", __func__, l);
699
0
  return (l);
700
0
}
701
702
uint32_t
703
prefixlen2mask(uint8_t prefixlen)
704
0
{
705
0
  if (prefixlen == 0)
706
0
    return (0);
707
708
0
  if (prefixlen > 32)
709
0
    prefixlen = 32;
710
711
0
  return (htonl(0xffffffff << (32 - prefixlen)));
712
0
}
713
714
struct in6_addr *
715
prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
716
0
{
717
0
  static struct in6_addr  s6;
718
0
  int     i;
719
720
0
  if (prefixlen > 128)
721
0
    prefixlen = 128;
722
723
0
  bzero(&s6, sizeof(s6));
724
0
  for (i = 0; i < prefixlen / 8; i++)
725
0
    s6.s6_addr[i] = 0xff;
726
0
  i = prefixlen % 8;
727
0
  if (i)
728
0
    s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
729
730
0
  memcpy(mask, &s6, sizeof(s6));
731
732
0
  return (&s6);
733
0
}
734
735
const char *
736
print_addr(void *addr)
737
14.0k
{
738
14.0k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
14.0k
  static int   idx;
740
14.0k
  struct sockaddr *sa = addr;
741
14.0k
  char    *buf;
742
14.0k
  size_t     len;
743
14.0k
  char     pbuf[7];
744
14.0k
  in_port_t  port;
745
746
14.0k
  buf = sbuf[idx];
747
14.0k
  len = sizeof(sbuf[idx]);
748
14.0k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.75k
    idx = 0;
750
751
14.0k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
14.0k
  if (getnameinfo(sa, SA_LEN(sa),
757
14.0k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
14.0k
  if ((port = socket_getport(sa)) != 0) {
763
0
    snprintf(pbuf, sizeof(pbuf), ":%d", port);
764
0
    (void)strlcat(buf, pbuf, len);
765
0
  }
766
767
14.0k
  return (buf);
768
14.0k
}
769
770
char *
771
get_string(uint8_t *ptr, size_t len)
772
0
{
773
0
  size_t   i;
774
775
0
  for (i = 0; i < len; i++)
776
0
    if (!isprint(ptr[i]))
777
0
      break;
778
779
0
  return strndup(ptr, i);
780
0
}
781
782
const char *
783
print_proto(uint8_t proto)
784
0
{
785
0
  struct protoent *p;
786
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
787
0
  static int   idx = 0;
788
789
0
  if (idx >= IKED_CYCLE_BUFFERS)
790
0
    idx = 0;
791
792
0
  if ((p = getprotobynumber(proto)) != NULL)
793
0
    strlcpy(buf[idx], p->p_name, sizeof(buf[idx]));
794
0
  else
795
0
    snprintf(buf[idx], sizeof(buf), "%u", proto);
796
797
798
0
  return (buf[idx++]);
799
0
}
800
801
int
802
expand_string(char *label, size_t len, const char *srch, const char *repl)
803
0
{
804
0
  char *tmp;
805
0
  char *p, *q;
806
807
0
  if ((tmp = calloc(1, len)) == NULL) {
808
0
    log_debug("%s: calloc", __func__);
809
0
    return (-1);
810
0
  }
811
0
  p = label;
812
0
  while ((q = strstr(p, srch)) != NULL) {
813
0
    *q = '\0';
814
0
    if ((strlcat(tmp, p, len) >= len) ||
815
0
        (strlcat(tmp, repl, len) >= len)) {
816
0
      log_debug("%s: string too long", __func__);
817
0
      free(tmp);
818
0
      return (-1);
819
0
    }
820
0
    q += strlen(srch);
821
0
    p = q;
822
0
  }
823
0
  if (strlcat(tmp, p, len) >= len) {
824
0
    log_debug("%s: string too long", __func__);
825
0
    free(tmp);
826
0
    return (-1);
827
0
  }
828
0
  strlcpy(label, tmp, len); /* always fits */
829
0
  free(tmp);
830
831
0
  return (0);
832
0
}
833
834
uint8_t *
835
string2unicode(const char *ascii, size_t *outlen)
836
0
{
837
0
  uint8_t   *uc = NULL;
838
0
  size_t     i, len = strlen(ascii);
839
840
0
  if ((uc = calloc(1, (len * 2) + 2)) == NULL)
841
0
    return (NULL);
842
843
0
  for (i = 0; i < len; i++) {
844
    /* XXX what about the byte order? */
845
0
    uc[i * 2] = ascii[i];
846
0
  }
847
0
  *outlen = len * 2;
848
849
0
  return (uc);
850
0
}
851
852
void
853
print_debug(const char *emsg, ...)
854
0
{
855
0
  va_list  ap;
856
857
0
  if (log_getverbose() > 2) {
858
0
    va_start(ap, emsg);
859
0
    vfprintf(stderr, emsg, ap);
860
0
    va_end(ap);
861
0
  }
862
0
}
863
864
void
865
print_verbose(const char *emsg, ...)
866
0
{
867
0
  va_list  ap;
868
869
0
  if (log_getverbose()) {
870
0
    va_start(ap, emsg);
871
0
    vfprintf(stderr, emsg, ap);
872
0
    va_end(ap);
873
0
  }
874
0
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/iked/util.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: util.c,v 1.43 2023/07/28 11:23:03 claudio Exp $ */
2
3
/*
4
 * Copyright (c) 2021 Tobias Heider <tobhe@openbsd.org>
5
 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
#include <sys/uio.h>
24
25
#include <netinet/in.h>
26
#include <netinet/ip_ipsp.h>
27
28
#include <netdb.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <unistd.h>
32
#include <string.h>
33
#include <errno.h>
34
#include <limits.h>
35
#include <fcntl.h>
36
#include <ctype.h>
37
#include <event.h>
38
39
#include "iked.h"
40
#include "ikev2.h"
41
42
int
43
socket_af(struct sockaddr *sa, in_port_t port)
44
0
{
45
0
  errno = 0;
46
0
  switch (sa->sa_family) {
47
0
  case AF_INET:
48
0
    ((struct sockaddr_in *)sa)->sin_port = port;
49
#ifdef HAVE_SOCKADDR_SA_LEN
50
    ((struct sockaddr_in *)sa)->sin_len =
51
        sizeof(struct sockaddr_in);
52
#endif
53
0
    break;
54
0
  case AF_INET6:
55
0
    ((struct sockaddr_in6 *)sa)->sin6_port = port;
56
#ifdef HAVE_SOCKADDR_SA_LEN
57
    ((struct sockaddr_in6 *)sa)->sin6_len =
58
        sizeof(struct sockaddr_in6);
59
#endif
60
0
    break;
61
0
  default:
62
0
    errno = EPFNOSUPPORT;
63
0
    return (-1);
64
0
  }
65
66
0
  return (0);
67
0
}
68
69
in_port_t
70
socket_getport(struct sockaddr *sa)
71
14.2k
{
72
14.2k
  switch (sa->sa_family) {
73
11.9k
  case AF_INET:
74
11.9k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
2.27k
  case AF_INET6:
76
2.27k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
14.2k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
14.2k
}
84
85
int
86
socket_setport(struct sockaddr *sa, in_port_t port)
87
0
{
88
0
  switch (sa->sa_family) {
89
0
  case AF_INET:
90
0
    ((struct sockaddr_in *)sa)->sin_port = htons(port);
91
0
    break;
92
0
  case AF_INET6:
93
0
    ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
94
0
    break;
95
0
  default:
96
0
    return (-1);
97
0
  }
98
0
  return (0);
99
0
}
100
101
int
102
socket_getaddr(int s, struct sockaddr_storage *ss)
103
0
{
104
0
  socklen_t sslen = sizeof(*ss);
105
106
0
  return (getsockname(s, (struct sockaddr *)ss, &sslen));
107
0
}
108
109
int
110
socket_bypass(int s, struct sockaddr *sa)
111
0
{
112
#if defined(__OpenBSD__)
113
  int  v, *a;
114
  int  a4[] = {
115
        IPPROTO_IP,
116
        IP_AUTH_LEVEL,
117
        IP_ESP_TRANS_LEVEL,
118
        IP_ESP_NETWORK_LEVEL,
119
#ifdef IPV6_IPCOMP_LEVEL
120
        IP_IPCOMP_LEVEL
121
#endif
122
  };
123
  int  a6[] = {
124
        IPPROTO_IPV6,
125
        IPV6_AUTH_LEVEL,
126
        IPV6_ESP_TRANS_LEVEL,
127
        IPV6_ESP_NETWORK_LEVEL,
128
#ifdef IPV6_IPCOMP_LEVEL
129
        IPV6_IPCOMP_LEVEL
130
#endif
131
  };
132
133
  switch (sa->sa_family) {
134
  case AF_INET:
135
    a = a4;
136
    break;
137
  case AF_INET6:
138
    a = a6;
139
    break;
140
  default:
141
    log_warn("%s: invalid address family", __func__);
142
    return (-1);
143
  }
144
145
  v = IPSEC_LEVEL_BYPASS;
146
  if (setsockopt(s, a[0], a[1], &v, sizeof(v)) == -1) {
147
    log_warn("%s: AUTH_LEVEL", __func__);
148
    return (-1);
149
  }
150
  if (setsockopt(s, a[0], a[2], &v, sizeof(v)) == -1) {
151
    log_warn("%s: ESP_TRANS_LEVEL", __func__);
152
    return (-1);
153
  }
154
  if (setsockopt(s, a[0], a[3], &v, sizeof(v)) == -1) {
155
    log_warn("%s: ESP_NETWORK_LEVEL", __func__);
156
    return (-1);
157
  }
158
#ifdef IP_IPCOMP_LEVEL
159
  if (setsockopt(s, a[0], a[4], &v, sizeof(v)) == -1) {
160
    log_warn("%s: IPCOMP_LEVEL", __func__);
161
    return (-1);
162
  }
163
#endif
164
#else /* __OpenBSD__ */
165
0
  int *a;
166
0
  int  a4[] = {
167
0
        IPPROTO_IP,
168
0
        IP_IPSEC_POLICY
169
0
  };
170
0
  int  a6[] = {
171
0
        IPPROTO_IPV6,
172
0
        IPV6_IPSEC_POLICY,
173
0
  };
174
0
  struct sadb_x_policy pol = {
175
0
        SADB_UPDATE,
176
0
        SADB_EXT_SENSITIVITY,
177
0
        IPSEC_POLICY_BYPASS,
178
0
        0, 0, 0, 0
179
0
  };
180
181
0
  switch (sa->sa_family) {
182
0
  case AF_INET:
183
0
    a = a4;
184
0
    break;
185
0
  case AF_INET6:
186
0
    a = a6;
187
0
    break;
188
0
  default:
189
0
    log_warn("%s: invalid address family", __func__);
190
0
    return (-1);
191
0
  }
192
193
0
  pol.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
194
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
195
0
    log_warn("%s: IPSEC_DIR_INBOUND", __func__);
196
0
    return (-1);
197
0
  }
198
0
  pol.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
199
0
  if (setsockopt(s, a[0], a[1], &pol, sizeof(pol)) == -1) {
200
0
    log_warn("%s: IPSEC_DIR_OUTBOUND", __func__);
201
0
    return (-1);
202
0
  }
203
0
#endif /* !__OpenBSD__ */
204
205
0
  return (0);
206
0
}
207
208
int
209
udp_bind(struct sockaddr *sa, in_port_t port)
210
0
{
211
0
  int  s, val;
212
213
0
  if (socket_af(sa, port) == -1) {
214
0
    log_warn("%s: failed to set UDP port", __func__);
215
0
    return (-1);
216
0
  }
217
218
0
  if ((s = socket(sa->sa_family,
219
0
      SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP)) == -1) {
220
0
    log_warn("%s: failed to get UDP socket", __func__);
221
0
    return (-1);
222
0
  }
223
224
  /* Skip IPsec processing (don't encrypt) for IKE messages */
225
0
  if (socket_bypass(s, sa) == -1) {
226
0
    log_warn("%s: failed to bypass IPsec on IKE socket",
227
0
        __func__);
228
0
    goto bad;
229
0
  }
230
231
0
  val = 1;
232
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(int)) == -1) {
233
0
    log_warn("%s: failed to set reuseport", __func__);
234
0
    goto bad;
235
0
  }
236
0
  val = 1;
237
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)) == -1) {
238
0
    log_warn("%s: failed to set reuseaddr", __func__);
239
0
    goto bad;
240
0
  }
241
242
0
  if (sa->sa_family == AF_INET) {
243
0
#if defined(IP_RECVORIGDSTADDR)
244
0
    val = 1;
245
0
    if (setsockopt(s, IPPROTO_IP, IP_RECVORIGDSTADDR,
246
0
        &val, sizeof(int)) == -1) {
247
0
      log_warn("%s: failed to set IPv4 packet info",
248
0
          __func__);
249
0
      goto bad;
250
0
    }
251
#elif defined(IP_RECVDSTADDR)
252
    val = 1;
253
    if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
254
        &val, sizeof(int)) == -1) {
255
      log_warn("%s: failed to set IPv4 packet info",
256
          __func__);
257
      goto bad;
258
    }
259
#endif
260
0
  } else {
261
0
#ifdef IPV6_RECVPKTINFO
262
0
    val = 1;
263
0
    if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO,
264
0
        &val, sizeof(int)) == -1) {
265
0
      log_warn("%s: failed to set IPv6 packet info",
266
0
          __func__);
267
0
      goto bad;
268
0
    }
269
0
#endif
270
0
  }
271
272
0
  if (bind(s, sa, SA_LEN(sa)) == -1) {
273
0
    log_warn("%s: failed to bind UDP socket", __func__);
274
0
    goto bad;
275
0
  }
276
277
0
  return (s);
278
0
 bad:
279
0
  close(s);
280
0
  return (-1);
281
0
}
282
283
int
284
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen)
285
0
{
286
0
  struct sockaddr_in  *a4, *b4;
287
0
  struct sockaddr_in6 *a6, *b6;
288
0
  uint32_t     av[4], bv[4], mv[4];
289
290
0
  if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC)
291
0
    return (0);
292
0
  else if (a->sa_family > b->sa_family)
293
0
    return (1);
294
0
  else if (a->sa_family < b->sa_family)
295
0
    return (-1);
296
297
0
  if (prefixlen == -1)
298
0
    memset(&mv, 0xff, sizeof(mv));
299
300
0
  switch (a->sa_family) {
301
0
  case AF_INET:
302
0
    a4 = (struct sockaddr_in *)a;
303
0
    b4 = (struct sockaddr_in *)b;
304
305
0
    av[0] = a4->sin_addr.s_addr;
306
0
    bv[0] = b4->sin_addr.s_addr;
307
0
    if (prefixlen != -1)
308
0
      mv[0] = prefixlen2mask(prefixlen);
309
310
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
311
0
      return (1);
312
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
313
0
      return (-1);
314
0
    break;
315
0
  case AF_INET6:
316
0
    a6 = (struct sockaddr_in6 *)a;
317
0
    b6 = (struct sockaddr_in6 *)b;
318
319
0
    memcpy(&av, &a6->sin6_addr.s6_addr, 16);
320
0
    memcpy(&bv, &b6->sin6_addr.s6_addr, 16);
321
0
    if (prefixlen != -1)
322
0
      prefixlen2mask6(prefixlen, mv);
323
324
0
    if ((av[3] & mv[3]) > (bv[3] & mv[3]))
325
0
      return (1);
326
0
    if ((av[3] & mv[3]) < (bv[3] & mv[3]))
327
0
      return (-1);
328
0
    if ((av[2] & mv[2]) > (bv[2] & mv[2]))
329
0
      return (1);
330
0
    if ((av[2] & mv[2]) < (bv[2] & mv[2]))
331
0
      return (-1);
332
0
    if ((av[1] & mv[1]) > (bv[1] & mv[1]))
333
0
      return (1);
334
0
    if ((av[1] & mv[1]) < (bv[1] & mv[1]))
335
0
      return (-1);
336
0
    if ((av[0] & mv[0]) > (bv[0] & mv[0]))
337
0
      return (1);
338
0
    if ((av[0] & mv[0]) < (bv[0] & mv[0]))
339
0
      return (-1);
340
0
    break;
341
0
  }
342
343
0
  return (0);
344
0
}
345
346
ssize_t
347
sendtofrom(int s, void *buf, size_t len, int flags, struct sockaddr *to,
348
    socklen_t tolen, struct sockaddr *from, socklen_t fromlen)
349
0
{
350
0
  struct iovec     iov;
351
0
  struct msghdr    msg;
352
0
  struct cmsghdr    *cmsg;
353
#ifdef IP_SENDSRCADDR
354
  struct sockaddr_in  *in;
355
#endif
356
0
#ifdef IPV6_PKTINFO
357
0
  struct in6_pktinfo  *pkt6;
358
0
  struct sockaddr_in6 *in6;
359
0
#endif
360
0
  union {
361
0
    struct cmsghdr  hdr;
362
0
    char    inbuf[CMSG_SPACE(sizeof(struct in_addr))];
363
0
    char    in6buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
364
0
  } cmsgbuf;
365
366
0
  bzero(&msg, sizeof(msg));
367
0
  bzero(&cmsgbuf, sizeof(cmsgbuf));
368
369
0
  iov.iov_base = buf;
370
0
  iov.iov_len = len;
371
0
  msg.msg_iov = &iov;
372
0
  msg.msg_iovlen = 1;
373
0
  msg.msg_name = to;
374
0
  msg.msg_namelen = tolen;
375
0
  msg.msg_controllen = 0;
376
377
0
  switch (to->sa_family) {
378
0
  case AF_INET:
379
#ifdef IP_SENDSRCADDR
380
    in = (struct sockaddr_in *)from;
381
    if (in->sin_addr.s_addr == INADDR_ANY)
382
      break;
383
    msg.msg_control = &cmsgbuf;
384
    msg.msg_controllen += sizeof(cmsgbuf.inbuf);
385
    cmsg = CMSG_FIRSTHDR(&msg);
386
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
387
    cmsg->cmsg_level = IPPROTO_IP;
388
    cmsg->cmsg_type = IP_SENDSRCADDR;
389
    memcpy(CMSG_DATA(cmsg), &in->sin_addr, sizeof(struct in_addr));
390
#endif
391
0
    break;
392
0
  case AF_INET6:
393
0
#ifdef IPV6_PKTINFO
394
0
    msg.msg_control = &cmsgbuf;
395
0
    msg.msg_controllen += sizeof(cmsgbuf.in6buf);
396
0
    cmsg = CMSG_FIRSTHDR(&msg);
397
0
    cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
398
0
    cmsg->cmsg_level = IPPROTO_IPV6;
399
0
    cmsg->cmsg_type = IPV6_PKTINFO;
400
0
    in6 = (struct sockaddr_in6 *)from;
401
0
    pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
402
0
    pkt6->ipi6_addr = in6->sin6_addr;
403
0
#endif
404
0
    break;
405
0
  }
406
407
0
  return sendmsg(s, &msg, flags);
408
0
}
409
410
ssize_t
411
recvfromto(int s, void *buf, size_t len, int flags, struct sockaddr *from,
412
    socklen_t *fromlen, struct sockaddr *to, socklen_t *tolen)
413
0
{
414
0
  struct iovec     iov;
415
0
  struct msghdr    msg;
416
0
  struct cmsghdr    *cmsg;
417
#if !defined(IP_RECVORIGDSTADDR) && defined(IP_RECVDSTADDR)
418
  struct sockaddr_in  *in;
419
#endif
420
0
#ifdef IPV6_PKTINFO
421
0
  struct in6_pktinfo  *pkt6;
422
0
  struct sockaddr_in6 *in6;
423
0
#endif
424
0
  ssize_t      ret;
425
0
  union {
426
0
    struct cmsghdr hdr;
427
0
    char  buf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
428
0
  } cmsgbuf;
429
430
0
  bzero(&msg, sizeof(msg));
431
0
  bzero(&cmsgbuf.buf, sizeof(cmsgbuf.buf));
432
433
0
  iov.iov_base = buf;
434
0
  iov.iov_len = len;
435
0
  msg.msg_iov = &iov;
436
0
  msg.msg_iovlen = 1;
437
0
  msg.msg_name = from;
438
0
  msg.msg_namelen = *fromlen;
439
0
  msg.msg_control = &cmsgbuf.buf;
440
0
  msg.msg_controllen = sizeof(cmsgbuf.buf);
441
442
0
  if ((ret = recvmsg(s, &msg, flags)) == -1)
443
0
    return (-1);
444
445
0
  *fromlen = SA_LEN(from);
446
447
0
  if (getsockname(s, to, tolen) != 0)
448
0
    *tolen = 0;
449
450
0
  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
451
0
      cmsg = CMSG_NXTHDR(&msg, cmsg)) {
452
0
    switch (from->sa_family) {
453
0
    case AF_INET:
454
0
#if defined(IP_RECVORIGDSTADDR)
455
0
      if (cmsg->cmsg_level == IPPROTO_IP &&
456
0
          cmsg->cmsg_type == IP_RECVORIGDSTADDR) {
457
0
        memcpy(to, CMSG_DATA(cmsg),
458
0
            sizeof(struct sockaddr_in));
459
0
      }
460
#elif defined(IP_RECVDSTADDR)
461
      if (cmsg->cmsg_level == IPPROTO_IP &&
462
          cmsg->cmsg_type == IP_RECVDSTADDR) {
463
        in = (struct sockaddr_in *)to;
464
        in->sin_family = AF_INET;
465
#ifdef HAVE_SOCKADDR_SA_LEN
466
        in->sin_len = *tolen = sizeof(*in);
467
#endif
468
        memcpy(&in->sin_addr, CMSG_DATA(cmsg),
469
            sizeof(struct in_addr));
470
      }
471
#endif /* defined(IP_RECVDSTADDR) */
472
0
      break;
473
0
    case AF_INET6:
474
0
#ifdef IPV6_PKTINFO
475
0
      if (cmsg->cmsg_level == IPPROTO_IPV6 &&
476
0
          cmsg->cmsg_type == IPV6_PKTINFO) {
477
0
        in6 = (struct sockaddr_in6 *)to;
478
0
        in6->sin6_family = AF_INET6;
479
#ifdef HAVE_SOCKADDR_SA_LEN
480
        in6->sin6_len = *tolen = sizeof(*in6);
481
#endif
482
0
        pkt6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
483
0
        memcpy(&in6->sin6_addr, &pkt6->ipi6_addr,
484
0
            sizeof(struct in6_addr));
485
0
        if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
486
0
          in6->sin6_scope_id =
487
0
              pkt6->ipi6_ifindex;
488
0
      }
489
0
#endif
490
0
      break;
491
0
    }
492
0
  }
493
494
0
  return (ret);
495
0
}
496
497
const char *
498
print_spi(uint64_t spi, int size)
499
36.0k
{
500
36.0k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
36.0k
  static int     i = 0;
502
36.0k
  char      *ptr;
503
504
36.0k
  ptr = buf[i];
505
506
36.0k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
349
  case 4:
511
349
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
349
    break;
513
26.5k
  case 8:
514
26.5k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
26.5k
    break;
516
9.11k
  default:
517
9.11k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
9.11k
    break;
519
36.0k
  }
520
521
36.0k
  if (++i >= IKED_CYCLE_BUFFERS)
522
4.50k
    i = 0;
523
524
36.0k
  return (ptr);
525
36.0k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
672k
{
530
672k
  unsigned int     i;
531
672k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
672k
  static int     idx = 0;
533
672k
  const char    *name = NULL;
534
535
672k
  if (idx >= IKED_CYCLE_BUFFERS)
536
84.0k
    idx = 0;
537
672k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
14.2M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
13.5M
    if (map[i].cm_type == type)
541
467k
      name = map[i].cm_name;
542
13.5M
  }
543
544
672k
  if (name == NULL)
545
205k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
467k
  else
547
467k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
672k
  return (buf[idx++]);
550
672k
}
551
552
void
553
lc_idtype(char *str)
554
0
{
555
0
  for (; *str != '\0' && *str != '/'; str++)
556
0
    *str = tolower((unsigned char)*str);
557
0
}
558
559
void
560
print_hex(const uint8_t *buf, off_t offset, size_t length)
561
148k
{
562
148k
  unsigned int   i;
563
564
148k
  if (log_getverbose() < 3 || !length)
565
148k
    return;
566
567
0
  for (i = 0; i < length; i++) {
568
0
    if (i && (i % 4) == 0) {
569
0
      if ((i % 32) == 0)
570
0
        print_debug("\n");
571
0
      else
572
0
        print_debug(" ");
573
0
    }
574
0
    print_debug("%02x", buf[offset + i]);
575
0
  }
576
0
  print_debug("\n");
577
0
}
578
579
void
580
print_hexval(const uint8_t *buf, off_t offset, size_t length)
581
0
{
582
0
  unsigned int   i;
583
584
0
  if (log_getverbose() < 2 || !length)
585
0
    return;
586
587
0
  print_debug("0x");
588
0
  for (i = 0; i < length; i++)
589
0
    print_debug("%02x", buf[offset + i]);
590
0
  print_debug("\n");
591
0
}
592
593
void
594
print_hexbuf(struct ibuf *ibuf)
595
0
{
596
0
  print_hex(ibuf_data(ibuf), 0, ibuf_size(ibuf));
597
0
}
598
599
const char *
600
print_bits(unsigned short v, unsigned char *bits)
601
0
{
602
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
603
0
  static int   idx = 0;
604
0
  unsigned int   i, any = 0, j = 0;
605
0
  unsigned char  c;
606
607
0
  if (!bits)
608
0
    return ("");
609
610
0
  if (++idx >= IKED_CYCLE_BUFFERS)
611
0
    idx = 0;
612
613
0
  bzero(buf[idx], sizeof(buf[idx]));
614
615
0
  bits++;
616
0
  while ((i = *bits++)) {
617
0
    if (v & (1 << (i-1))) {
618
0
      if (any) {
619
0
        buf[idx][j++] = ',';
620
0
        if (j >= sizeof(buf[idx]))
621
0
          return (buf[idx]);
622
0
      }
623
0
      any = 1;
624
0
      for (; (c = *bits) > 32; bits++) {
625
0
        buf[idx][j++] = tolower((unsigned char)c);
626
0
        if (j >= sizeof(buf[idx]))
627
0
          return (buf[idx]);
628
0
      }
629
0
    } else
630
0
      for (; *bits > 32; bits++)
631
0
        ;
632
0
  }
633
634
0
  return (buf[idx]);
635
0
}
636
637
uint8_t
638
mask2prefixlen(struct sockaddr *sa)
639
0
{
640
0
  struct sockaddr_in  *sa_in = (struct sockaddr_in *)sa;
641
0
  in_addr_t    ina = sa_in->sin_addr.s_addr;
642
643
0
  if (ina == 0)
644
0
    return (0);
645
0
  else
646
0
    return (33 - ffs(ntohl(ina)));
647
0
}
648
649
uint8_t
650
mask2prefixlen6(struct sockaddr *sa)
651
0
{
652
0
  struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
653
0
  uint8_t     *ap, *ep;
654
0
  unsigned int     l = 0;
655
656
  /*
657
   * sin6_len is the size of the sockaddr so substract the offset of
658
   * the possibly truncated sin6_addr struct.
659
   */
660
0
  ap = (uint8_t *)&sa_in6->sin6_addr;
661
0
  ep = (uint8_t *)sa_in6 + SA_LEN(sa);
662
0
  for (; ap < ep; ap++) {
663
    /* this "beauty" is adopted from sbin/route/show.c ... */
664
0
    switch (*ap) {
665
0
    case 0xff:
666
0
      l += 8;
667
0
      break;
668
0
    case 0xfe:
669
0
      l += 7;
670
0
      goto done;
671
0
    case 0xfc:
672
0
      l += 6;
673
0
      goto done;
674
0
    case 0xf8:
675
0
      l += 5;
676
0
      goto done;
677
0
    case 0xf0:
678
0
      l += 4;
679
0
      goto done;
680
0
    case 0xe0:
681
0
      l += 3;
682
0
      goto done;
683
0
    case 0xc0:
684
0
      l += 2;
685
0
      goto done;
686
0
    case 0x80:
687
0
      l += 1;
688
0
      goto done;
689
0
    case 0x00:
690
0
      goto done;
691
0
    default:
692
0
      fatalx("non contiguous inet6 netmask");
693
0
    }
694
0
  }
695
696
0
done:
697
0
  if (l > sizeof(struct in6_addr) * 8)
698
0
    fatalx("%s: prefixlen %d out of bound", __func__, l);
699
0
  return (l);
700
0
}
701
702
uint32_t
703
prefixlen2mask(uint8_t prefixlen)
704
0
{
705
0
  if (prefixlen == 0)
706
0
    return (0);
707
708
0
  if (prefixlen > 32)
709
0
    prefixlen = 32;
710
711
0
  return (htonl(0xffffffff << (32 - prefixlen)));
712
0
}
713
714
struct in6_addr *
715
prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
716
0
{
717
0
  static struct in6_addr  s6;
718
0
  int     i;
719
720
0
  if (prefixlen > 128)
721
0
    prefixlen = 128;
722
723
0
  bzero(&s6, sizeof(s6));
724
0
  for (i = 0; i < prefixlen / 8; i++)
725
0
    s6.s6_addr[i] = 0xff;
726
0
  i = prefixlen % 8;
727
0
  if (i)
728
0
    s6.s6_addr[prefixlen / 8] = 0xff00 >> i;
729
730
0
  memcpy(mask, &s6, sizeof(s6));
731
732
0
  return (&s6);
733
0
}
734
735
const char *
736
print_addr(void *addr)
737
14.2k
{
738
14.2k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
14.2k
  static int   idx;
740
14.2k
  struct sockaddr *sa = addr;
741
14.2k
  char    *buf;
742
14.2k
  size_t     len;
743
14.2k
  char     pbuf[7];
744
14.2k
  in_port_t  port;
745
746
14.2k
  buf = sbuf[idx];
747
14.2k
  len = sizeof(sbuf[idx]);
748
14.2k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.78k
    idx = 0;
750
751
14.2k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
14.2k
  if (getnameinfo(sa, SA_LEN(sa),
757
14.2k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
14.2k
  if ((port = socket_getport(sa)) != 0) {
763
0
    snprintf(pbuf, sizeof(pbuf), ":%d", port);
764
0
    (void)strlcat(buf, pbuf, len);
765
0
  }
766
767
14.2k
  return (buf);
768
14.2k
}
769
770
char *
771
get_string(uint8_t *ptr, size_t len)
772
0
{
773
0
  size_t   i;
774
775
0
  for (i = 0; i < len; i++)
776
0
    if (!isprint(ptr[i]))
777
0
      break;
778
779
0
  return strndup(ptr, i);
780
0
}
781
782
const char *
783
print_proto(uint8_t proto)
784
0
{
785
0
  struct protoent *p;
786
0
  static char  buf[IKED_CYCLE_BUFFERS][BUFSIZ];
787
0
  static int   idx = 0;
788
789
0
  if (idx >= IKED_CYCLE_BUFFERS)
790
0
    idx = 0;
791
792
0
  if ((p = getprotobynumber(proto)) != NULL)
793
0
    strlcpy(buf[idx], p->p_name, sizeof(buf[idx]));
794
0
  else
795
0
    snprintf(buf[idx], sizeof(buf), "%u", proto);
796
797
798
0
  return (buf[idx++]);
799
0
}
800
801
int
802
expand_string(char *label, size_t len, const char *srch, const char *repl)
803
0
{
804
0
  char *tmp;
805
0
  char *p, *q;
806
807
0
  if ((tmp = calloc(1, len)) == NULL) {
808
0
    log_debug("%s: calloc", __func__);
809
0
    return (-1);
810
0
  }
811
0
  p = label;
812
0
  while ((q = strstr(p, srch)) != NULL) {
813
0
    *q = '\0';
814
0
    if ((strlcat(tmp, p, len) >= len) ||
815
0
        (strlcat(tmp, repl, len) >= len)) {
816
0
      log_debug("%s: string too long", __func__);
817
0
      free(tmp);
818
0
      return (-1);
819
0
    }
820
0
    q += strlen(srch);
821
0
    p = q;
822
0
  }
823
0
  if (strlcat(tmp, p, len) >= len) {
824
0
    log_debug("%s: string too long", __func__);
825
0
    free(tmp);
826
0
    return (-1);
827
0
  }
828
0
  strlcpy(label, tmp, len); /* always fits */
829
0
  free(tmp);
830
831
0
  return (0);
832
0
}
833
834
uint8_t *
835
string2unicode(const char *ascii, size_t *outlen)
836
0
{
837
0
  uint8_t   *uc = NULL;
838
0
  size_t     i, len = strlen(ascii);
839
840
0
  if ((uc = calloc(1, (len * 2) + 2)) == NULL)
841
0
    return (NULL);
842
843
0
  for (i = 0; i < len; i++) {
844
    /* XXX what about the byte order? */
845
0
    uc[i * 2] = ascii[i];
846
0
  }
847
0
  *outlen = len * 2;
848
849
0
  return (uc);
850
0
}
851
852
void
853
print_debug(const char *emsg, ...)
854
0
{
855
0
  va_list  ap;
856
857
0
  if (log_getverbose() > 2) {
858
0
    va_start(ap, emsg);
859
0
    vfprintf(stderr, emsg, ap);
860
0
    va_end(ap);
861
0
  }
862
0
}
863
864
void
865
print_verbose(const char *emsg, ...)
866
0
{
867
0
  va_list  ap;
868
869
0
  if (log_getverbose()) {
870
0
    va_start(ap, emsg);
871
0
    vfprintf(stderr, emsg, ap);
872
0
    va_end(ap);
873
0
  }
874
0
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html index 3fdd8218f..29b24d4ee 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/common.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/regress/parser-libfuzzer/common.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: common.c,v 1.9 2020/11/26 22:29:32 tobhe Exp $ */
2
/*
3
 * A bunch of stub functions so we can compile and link ikev2_pld.c
4
 * in a standalone program for testing purposes.
5
 *
6
 * Placed in the public domain
7
 */
8
9
#include <sys/socket.h>
10
#include <sys/time.h>
11
#include <sys/uio.h>
12
13
#include <event.h>
14
#include <limits.h>
15
16
#include "iked.h"
17
#include "types.h"
18
19
197k
#define IKEV2_FLAG_INITIATOR            0x08    /* Sent by the initiator */
20
21
int  eap_parse(struct iked *, const struct iked_sa *,
22
      struct iked_message *, void *, int);
23
int  ikev2_msg_frompeer(struct iked_message *);
24
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
25
      u_int8_t, u_int8_t, int);
26
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
27
struct iked_childsa *
28
   childsa_lookup(struct iked_sa *, u_int64_t, u_int8_t);
29
int   ikev2_childsa_delete(struct iked *, struct iked_sa *,
30
      u_int8_t, u_int64_t, u_int64_t *, int);
31
int  sa_stateok(const struct iked_sa *, int);
32
void   sa_state(struct iked *, struct iked_sa *, int);
33
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
34
void   ikev2_init_ike_sa(struct iked *, void *);
35
struct dh_group *
36
   group_get(u_int32_t);
37
void   timer_set(struct iked *, struct iked_timer *,
38
       void (*)(struct iked *, void *), void *);
39
void   timer_add(struct iked *, struct iked_timer *, int);
40
void   timer_del(struct iked *, struct iked_timer *);
41
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
42
       void *, size_t, u_int, int);
43
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
44
       u_int8_t, u_int8_t, u_int8_t *, size_t, enum privsep_procid);
45
int  ikev2_print_id(struct iked_id *, char *, size_t);
46
int  config_add_transform(struct iked_proposal *, u_int, u_int, u_int,
47
       u_int);
48
struct iked_proposal *
49
   config_add_proposal(struct iked_proposals *, u_int, u_int);
50
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
51
int  ikev2_send_informational(struct iked *, struct iked_message *);
52
struct ibuf *
53
   ikev2_msg_decrypt(struct iked *, struct iked_sa *, struct ibuf *,
54
       struct ibuf *);
55
void ikev2_msg_cleanup(struct iked *, struct iked_message *);
56
57
int
58
eap_parse(struct iked *env, const struct iked_sa *sa, struct iked_message *msg,
59
    void *data, int response)
60
3.20k
{
61
3.20k
  return (0);
62
3.20k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
197k
{
68
197k
  struct iked_sa    *sa = msg->msg_sa;
69
197k
  struct ike_header *hdr;
70
71
197k
  msg = msg->msg_parent;
72
73
197k
  if (sa == NULL ||
74
197k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
197k
  if (!sa->sa_hdr.sh_initiator &&
78
197k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
55.2k
    return (1);
80
142k
  else if (sa->sa_hdr.sh_initiator &&
81
142k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
142k
  return (0);
85
197k
}
86
87
int
88
ikev2_send_ike_e(struct iked *env, struct iked_sa *sa, struct ibuf *buf,
89
    u_int8_t firstpayload, u_int8_t exchange, int response)
90
0
{
91
0
  return (0);
92
0
}
93
94
void
95
ikev2_ikesa_recv_delete(struct iked *env, struct iked_sa *sa)
96
0
{
97
0
}
98
99
const char *
100
ikev2_ikesa_info(uint64_t spi, const char *msg)
101
7.69k
{
102
7.69k
  return "";
103
7.69k
}
104
105
struct iked_childsa *
106
childsa_lookup(struct iked_sa *a, u_int64_t b, u_int8_t c)
107
0
{
108
0
  return (NULL);
109
0
}
110
111
int
112
ikev2_childsa_delete(struct iked *a, struct iked_sa *b, u_int8_t c,
113
    u_int64_t d, u_int64_t *e , int f)
114
0
{
115
0
  return (0);
116
0
}
117
118
int
119
sa_stateok(const struct iked_sa *a, int b)
120
141
{
121
141
  return (0);
122
141
}
123
124
void
125
sa_state(struct iked * a, struct iked_sa *b, int c)
126
0
{
127
0
}
128
129
void
130
ikev2_disable_rekeying(struct iked *a, struct iked_sa *b)
131
0
{
132
0
}
133
134
void
135
ikev2_init_ike_sa(struct iked *a, void *b)
136
0
{
137
0
}
138
139
const struct group_id *
140
group_getid(u_int32_t id)
141
0
{
142
0
  return (NULL);
143
0
}
144
145
void
146
timer_set(struct iked *env, struct iked_timer *tmr,
147
    void (*cb)(struct iked *, void *), void *arg)
148
0
{
149
0
}
150
151
void
152
timer_add(struct iked *env, struct iked_timer *tmr, int timeout)
153
0
{
154
0
}
155
156
void
157
timer_del(struct iked *env, struct iked_timer *tmr)
158
0
{
159
0
}
160
161
ssize_t
162
ikev2_nat_detection(struct iked *env, struct iked_message *msg,
163
    void *ptr, size_t len, u_int type, int frompeer)
164
22.6k
{
165
22.6k
  return (0);
166
22.6k
}
167
168
int
169
ca_setreq(struct iked *env, struct iked_sa *sh, struct iked_static_id *localid,
170
    u_int8_t type, u_int8_t more, u_int8_t *data, size_t len,
171
    enum privsep_procid procid)
172
0
{
173
0
  return (0);
174
0
}
175
176
int
177
ikev2_print_id(struct iked_id *id, char *idstr, size_t idstrlen)
178
5.38k
{
179
5.38k
  return (0);
180
5.38k
}
181
182
int
183
config_add_transform(struct iked_proposal *prop, u_int type,
184
    u_int id, u_int length, u_int keylength)
185
0
{
186
0
  return (0);
187
0
}
188
189
struct iked_proposal *
190
config_add_proposal(struct iked_proposals *head, u_int id, u_int proto)
191
69
{
192
69
  return (NULL);
193
69
}
194
195
void
196
config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
197
0
{
198
0
  return;
199
0
}
200
201
void config_free_fragments(struct iked_frag *frag)
202
0
{
203
0
  return;
204
0
}
205
206
int
207
ikev2_send_informational(struct iked *env, struct iked_message *msg)
208
722
{
209
722
  return (0);
210
722
}
211
212
struct ibuf *
213
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
214
    struct ibuf *msg, struct ibuf *src)
215
0
{
216
0
  if (src == NULL){
217
0
                fprintf(stderr, "%s\n", "msg_decrypt: src == NULL!");
218
0
                exit(-1);
219
0
        }
220
221
  /*
222
   * Free src as caller uses ikev2_msg_decrypt() like this:
223
   * src = ikev2_msg_decrypt(..., src);
224
   */
225
0
  ibuf_free(src); 
226
0
  return (NULL);
227
0
}
228
229
void
230
ikev2_ike_sa_setreason(struct iked_sa *sa, char *r)
231
0
{
232
0
}
233
234
void
235
ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue,
236
    struct iked_msg_retransmit *mr)
237
0
{
238
0
}
239
240
struct iked_msg_retransmit *
241
ikev2_msg_lookup(struct iked *env, struct iked_msgqueue *queue,
242
    struct iked_message *msg, uint8_t exchange)
243
0
{
244
0
  return NULL;
245
0
}
246
247
/* copied from ikev2_msg.c */
248
void
249
ikev2_msg_cleanup(struct iked *env, struct iked_message *msg)
250
13.0k
{
251
13.0k
  struct iked_certreq *cr;
252
13.0k
  struct iked_proposal *prop, *proptmp;
253
13.0k
  int      i;
254
255
13.0k
  if (msg == msg->msg_parent) {
256
13.0k
    ibuf_free(msg->msg_nonce);
257
13.0k
    ibuf_free(msg->msg_ke);
258
13.0k
    ibuf_free(msg->msg_auth.id_buf);
259
13.0k
    ibuf_free(msg->msg_peerid.id_buf);
260
13.0k
    ibuf_free(msg->msg_localid.id_buf);
261
13.0k
    ibuf_free(msg->msg_cert.id_buf);
262
52.1k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
39.1k
      ibuf_free(msg->msg_scert[i].id_buf);
264
13.0k
    ibuf_free(msg->msg_cookie);
265
13.0k
    ibuf_free(msg->msg_cookie2);
266
13.0k
    ibuf_free(msg->msg_del_buf);
267
13.0k
    free(msg->msg_eap.eam_user);
268
13.0k
    free(msg->msg_cp_addr);
269
13.0k
    free(msg->msg_cp_addr6);
270
13.0k
    free(msg->msg_cp_dns);
271
272
13.0k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
13.0k
        proptmp) {
274
0
      TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry);
275
0
      if (prop->prop_nxforms)
276
0
        free(prop->prop_xforms);
277
0
      free(prop);
278
0
    }
279
280
13.0k
    msg->msg_nonce = NULL;
281
13.0k
    msg->msg_ke = NULL;
282
13.0k
    msg->msg_auth.id_buf = NULL;
283
13.0k
    msg->msg_peerid.id_buf = NULL;
284
13.0k
    msg->msg_localid.id_buf = NULL;
285
13.0k
    msg->msg_cert.id_buf = NULL;
286
52.1k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
39.1k
      msg->msg_scert[i].id_buf = NULL;
288
13.0k
    msg->msg_cookie = NULL;
289
13.0k
    msg->msg_cookie2 = NULL;
290
13.0k
    msg->msg_del_buf = NULL;
291
13.0k
    msg->msg_eap.eam_user = NULL;
292
13.0k
    msg->msg_cp_addr = NULL;
293
13.0k
    msg->msg_cp_addr6 = NULL;
294
13.0k
    msg->msg_cp_dns = NULL;
295
296
13.9k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
897
      ibuf_free(cr->cr_data);
298
897
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
897
      free(cr);
300
897
    }
301
13.0k
  }
302
303
13.0k
  if (msg->msg_data != NULL) {
304
13.0k
    ibuf_free(msg->msg_data);
305
13.0k
    msg->msg_data = NULL;
306
13.0k
  }
307
13.0k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/regress/parser-libfuzzer/common.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: common.c,v 1.9 2020/11/26 22:29:32 tobhe Exp $ */
2
/*
3
 * A bunch of stub functions so we can compile and link ikev2_pld.c
4
 * in a standalone program for testing purposes.
5
 *
6
 * Placed in the public domain
7
 */
8
9
#include <sys/socket.h>
10
#include <sys/time.h>
11
#include <sys/uio.h>
12
13
#include <event.h>
14
#include <limits.h>
15
16
#include "iked.h"
17
#include "types.h"
18
19
198k
#define IKEV2_FLAG_INITIATOR            0x08    /* Sent by the initiator */
20
21
int  eap_parse(struct iked *, const struct iked_sa *,
22
      struct iked_message *, void *, int);
23
int  ikev2_msg_frompeer(struct iked_message *);
24
int  ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
25
      u_int8_t, u_int8_t, int);
26
void   ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
27
struct iked_childsa *
28
   childsa_lookup(struct iked_sa *, u_int64_t, u_int8_t);
29
int   ikev2_childsa_delete(struct iked *, struct iked_sa *,
30
      u_int8_t, u_int64_t, u_int64_t *, int);
31
int  sa_stateok(const struct iked_sa *, int);
32
void   sa_state(struct iked *, struct iked_sa *, int);
33
void   ikev2_disable_rekeying(struct iked *, struct iked_sa *);
34
void   ikev2_init_ike_sa(struct iked *, void *);
35
struct dh_group *
36
   group_get(u_int32_t);
37
void   timer_set(struct iked *, struct iked_timer *,
38
       void (*)(struct iked *, void *), void *);
39
void   timer_add(struct iked *, struct iked_timer *, int);
40
void   timer_del(struct iked *, struct iked_timer *);
41
ssize_t  ikev2_nat_detection(struct iked *, struct iked_message *,
42
       void *, size_t, u_int, int);
43
int  ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
44
       u_int8_t, u_int8_t, u_int8_t *, size_t, enum privsep_procid);
45
int  ikev2_print_id(struct iked_id *, char *, size_t);
46
int  config_add_transform(struct iked_proposal *, u_int, u_int, u_int,
47
       u_int);
48
struct iked_proposal *
49
   config_add_proposal(struct iked_proposals *, u_int, u_int);
50
void   config_free_proposal(struct iked_proposals *, struct iked_proposal *);
51
int  ikev2_send_informational(struct iked *, struct iked_message *);
52
struct ibuf *
53
   ikev2_msg_decrypt(struct iked *, struct iked_sa *, struct ibuf *,
54
       struct ibuf *);
55
void ikev2_msg_cleanup(struct iked *, struct iked_message *);
56
57
int
58
eap_parse(struct iked *env, const struct iked_sa *sa, struct iked_message *msg,
59
    void *data, int response)
60
3.20k
{
61
3.20k
  return (0);
62
3.20k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
198k
{
68
198k
  struct iked_sa    *sa = msg->msg_sa;
69
198k
  struct ike_header *hdr;
70
71
198k
  msg = msg->msg_parent;
72
73
198k
  if (sa == NULL ||
74
198k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
198k
  if (!sa->sa_hdr.sh_initiator &&
78
198k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
55.9k
    return (1);
80
142k
  else if (sa->sa_hdr.sh_initiator &&
81
142k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
142k
  return (0);
85
198k
}
86
87
int
88
ikev2_send_ike_e(struct iked *env, struct iked_sa *sa, struct ibuf *buf,
89
    u_int8_t firstpayload, u_int8_t exchange, int response)
90
0
{
91
0
  return (0);
92
0
}
93
94
void
95
ikev2_ikesa_recv_delete(struct iked *env, struct iked_sa *sa)
96
0
{
97
0
}
98
99
const char *
100
ikev2_ikesa_info(uint64_t spi, const char *msg)
101
7.69k
{
102
7.69k
  return "";
103
7.69k
}
104
105
struct iked_childsa *
106
childsa_lookup(struct iked_sa *a, u_int64_t b, u_int8_t c)
107
0
{
108
0
  return (NULL);
109
0
}
110
111
int
112
ikev2_childsa_delete(struct iked *a, struct iked_sa *b, u_int8_t c,
113
    u_int64_t d, u_int64_t *e , int f)
114
0
{
115
0
  return (0);
116
0
}
117
118
int
119
sa_stateok(const struct iked_sa *a, int b)
120
141
{
121
141
  return (0);
122
141
}
123
124
void
125
sa_state(struct iked * a, struct iked_sa *b, int c)
126
0
{
127
0
}
128
129
void
130
ikev2_disable_rekeying(struct iked *a, struct iked_sa *b)
131
0
{
132
0
}
133
134
void
135
ikev2_init_ike_sa(struct iked *a, void *b)
136
0
{
137
0
}
138
139
const struct group_id *
140
group_getid(u_int32_t id)
141
0
{
142
0
  return (NULL);
143
0
}
144
145
void
146
timer_set(struct iked *env, struct iked_timer *tmr,
147
    void (*cb)(struct iked *, void *), void *arg)
148
0
{
149
0
}
150
151
void
152
timer_add(struct iked *env, struct iked_timer *tmr, int timeout)
153
0
{
154
0
}
155
156
void
157
timer_del(struct iked *env, struct iked_timer *tmr)
158
0
{
159
0
}
160
161
ssize_t
162
ikev2_nat_detection(struct iked *env, struct iked_message *msg,
163
    void *ptr, size_t len, u_int type, int frompeer)
164
22.9k
{
165
22.9k
  return (0);
166
22.9k
}
167
168
int
169
ca_setreq(struct iked *env, struct iked_sa *sh, struct iked_static_id *localid,
170
    u_int8_t type, u_int8_t more, u_int8_t *data, size_t len,
171
    enum privsep_procid procid)
172
0
{
173
0
  return (0);
174
0
}
175
176
int
177
ikev2_print_id(struct iked_id *id, char *idstr, size_t idstrlen)
178
5.38k
{
179
5.38k
  return (0);
180
5.38k
}
181
182
int
183
config_add_transform(struct iked_proposal *prop, u_int type,
184
    u_int id, u_int length, u_int keylength)
185
0
{
186
0
  return (0);
187
0
}
188
189
struct iked_proposal *
190
config_add_proposal(struct iked_proposals *head, u_int id, u_int proto)
191
69
{
192
69
  return (NULL);
193
69
}
194
195
void
196
config_free_proposal(struct iked_proposals *head, struct iked_proposal *prop)
197
0
{
198
0
  return;
199
0
}
200
201
void config_free_fragments(struct iked_frag *frag)
202
0
{
203
0
  return;
204
0
}
205
206
int
207
ikev2_send_informational(struct iked *env, struct iked_message *msg)
208
723
{
209
723
  return (0);
210
723
}
211
212
struct ibuf *
213
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
214
    struct ibuf *msg, struct ibuf *src)
215
0
{
216
0
  if (src == NULL){
217
0
                fprintf(stderr, "%s\n", "msg_decrypt: src == NULL!");
218
0
                exit(-1);
219
0
        }
220
221
  /*
222
   * Free src as caller uses ikev2_msg_decrypt() like this:
223
   * src = ikev2_msg_decrypt(..., src);
224
   */
225
0
  ibuf_free(src); 
226
0
  return (NULL);
227
0
}
228
229
void
230
ikev2_ike_sa_setreason(struct iked_sa *sa, char *r)
231
0
{
232
0
}
233
234
void
235
ikev2_msg_dispose(struct iked *env, struct iked_msgqueue *queue,
236
    struct iked_msg_retransmit *mr)
237
0
{
238
0
}
239
240
struct iked_msg_retransmit *
241
ikev2_msg_lookup(struct iked *env, struct iked_msgqueue *queue,
242
    struct iked_message *msg, uint8_t exchange)
243
0
{
244
0
  return NULL;
245
0
}
246
247
/* copied from ikev2_msg.c */
248
void
249
ikev2_msg_cleanup(struct iked *env, struct iked_message *msg)
250
13.1k
{
251
13.1k
  struct iked_certreq *cr;
252
13.1k
  struct iked_proposal *prop, *proptmp;
253
13.1k
  int      i;
254
255
13.1k
  if (msg == msg->msg_parent) {
256
13.1k
    ibuf_free(msg->msg_nonce);
257
13.1k
    ibuf_free(msg->msg_ke);
258
13.1k
    ibuf_free(msg->msg_auth.id_buf);
259
13.1k
    ibuf_free(msg->msg_peerid.id_buf);
260
13.1k
    ibuf_free(msg->msg_localid.id_buf);
261
13.1k
    ibuf_free(msg->msg_cert.id_buf);
262
52.7k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
39.5k
      ibuf_free(msg->msg_scert[i].id_buf);
264
13.1k
    ibuf_free(msg->msg_cookie);
265
13.1k
    ibuf_free(msg->msg_cookie2);
266
13.1k
    ibuf_free(msg->msg_del_buf);
267
13.1k
    free(msg->msg_eap.eam_user);
268
13.1k
    free(msg->msg_cp_addr);
269
13.1k
    free(msg->msg_cp_addr6);
270
13.1k
    free(msg->msg_cp_dns);
271
272
13.1k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
13.1k
        proptmp) {
274
0
      TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry);
275
0
      if (prop->prop_nxforms)
276
0
        free(prop->prop_xforms);
277
0
      free(prop);
278
0
    }
279
280
13.1k
    msg->msg_nonce = NULL;
281
13.1k
    msg->msg_ke = NULL;
282
13.1k
    msg->msg_auth.id_buf = NULL;
283
13.1k
    msg->msg_peerid.id_buf = NULL;
284
13.1k
    msg->msg_localid.id_buf = NULL;
285
13.1k
    msg->msg_cert.id_buf = NULL;
286
52.7k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
39.5k
      msg->msg_scert[i].id_buf = NULL;
288
13.1k
    msg->msg_cookie = NULL;
289
13.1k
    msg->msg_cookie2 = NULL;
290
13.1k
    msg->msg_del_buf = NULL;
291
13.1k
    msg->msg_eap.eam_user = NULL;
292
13.1k
    msg->msg_cp_addr = NULL;
293
13.1k
    msg->msg_cp_addr6 = NULL;
294
13.1k
    msg->msg_cp_dns = NULL;
295
296
14.0k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
897
      ibuf_free(cr->cr_data);
298
897
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
897
      free(cr);
300
897
    }
301
13.1k
  }
302
303
13.1k
  if (msg->msg_data != NULL) {
304
13.1k
    ibuf_free(msg->msg_data);
305
13.1k
    msg->msg_data = NULL;
306
13.1k
  }
307
13.1k
}
\ No newline at end of file diff --git a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html index 2eae6ac97..4ac711c5d 100644 --- a/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html +++ b/coverage/latest/report_target/test_libfuzzer/linux/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c.html @@ -1 +1 @@ -

Coverage Report

Created: 2023-11-30 00:58

/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD$ */
2
/*
3
 * Fuzz tests for payload parsing
4
 *
5
 * Placed in the public domain
6
 */
7
8
#include <sys/socket.h>
9
#include <sys/queue.h>
10
#include <sys/uio.h>
11
12
#include <event.h>
13
#include <imsg.h>
14
#include <string.h>
15
16
#include "iked.h"
17
#include "ikev2.h"
18
19
u_int8_t cookies[] = {
20
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x01, /* initator cookie */
21
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* responder cookie */
22
};
23
24
u_int8_t genhdr[] = {
25
  0x00, 0x20, 0x22, 0x08, /* next, major/minor, exchange type, flags */
26
  0x00, 0x00, 0x00, 0x00, /* message ID */
27
  0x00, 0x00, 0x00, 0x00  /* total length */
28
};
29
30
13.0k
#define OFFSET_ICOOKIE    0
31
13.0k
#define OFFSET_RCOOKIE    8
32
13.0k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
13.0k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
13.0k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
13.0k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
13.0k
{
40
13.0k
  return &data[OFFSET_ICOOKIE];
41
13.0k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
13.0k
{
46
13.0k
  return &data[OFFSET_RCOOKIE];
47
13.0k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
13.0k
{
52
13.0k
  return data[OFFSET_NEXTPAYLOAD];
53
13.0k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
13.0k
{
58
13.0k
  return data[OFFSET_VERSION];
59
13.0k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
13.0k
{
64
13.0k
  return data[OFFSET_EXCHANGE];
65
13.0k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
13.0k
{
70
13.0k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
13.0k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
13.0k
{
76
13.0k
  bzero(hdr, sizeof(*hdr));
77
13.0k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
13.0k
      sizeof(hdr->ike_ispi));
79
13.0k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
13.0k
      sizeof(hdr->ike_rspi));
81
13.0k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
13.0k
  hdr->ike_version = get_version(ibuf_data(data));
83
13.0k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
13.0k
  hdr->ike_length = get_length(ibuf_data(data));
85
13.0k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
13.0k
{
90
13.0k
  static struct iked_sa sa;
91
92
13.0k
  bzero(&sa, sizeof(sa));
93
13.0k
  bzero(msg, sizeof(*msg));
94
95
13.0k
  msg->msg_sa = &sa;
96
13.0k
  msg->msg_data = data;
97
13.0k
  msg->msg_e = 1;
98
13.0k
  msg->msg_parent = msg;
99
100
13.0k
  TAILQ_INIT(&msg->msg_proposals);
101
13.0k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
13.0k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
13.0k
{
108
13.0k
  struct ibuf   *fuzzed;
109
13.0k
  struct ike_header  hdr;
110
13.0k
  struct iked_message  msg;
111
112
13.0k
  bzero(&hdr, sizeof(hdr));
113
13.0k
  bzero(&msg, sizeof(msg));
114
115
13.0k
  fuzzed = ibuf_new(data, size);
116
13.0k
  if (fuzzed == NULL){
117
0
    fprintf(stderr, "%s\n", "ERROR: fuzzed == NULL! "
118
0
        "(hint: fuzz-input too long?)");
119
0
    return -1;
120
0
  }  
121
  
122
  /* size too small? */
123
13.0k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
13.0k
  prepare_header(&hdr, fuzzed);
129
13.0k
  prepare_message(&msg, fuzzed);
130
131
13.0k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
13.0k
  ikev2_msg_cleanup(NULL, &msg);
134
135
13.0k
  return 0;
136
13.0k
}
\ No newline at end of file +

Coverage Report

Created: 2023-12-01 01:03

/src/openiked-portable/regress/parser-libfuzzer/test_parser_fuzz.c
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD$ */
2
/*
3
 * Fuzz tests for payload parsing
4
 *
5
 * Placed in the public domain
6
 */
7
8
#include <sys/socket.h>
9
#include <sys/queue.h>
10
#include <sys/uio.h>
11
12
#include <event.h>
13
#include <imsg.h>
14
#include <string.h>
15
16
#include "iked.h"
17
#include "ikev2.h"
18
19
u_int8_t cookies[] = {
20
  0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x01, /* initator cookie */
21
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* responder cookie */
22
};
23
24
u_int8_t genhdr[] = {
25
  0x00, 0x20, 0x22, 0x08, /* next, major/minor, exchange type, flags */
26
  0x00, 0x00, 0x00, 0x00, /* message ID */
27
  0x00, 0x00, 0x00, 0x00  /* total length */
28
};
29
30
13.1k
#define OFFSET_ICOOKIE    0
31
13.1k
#define OFFSET_RCOOKIE    8
32
13.1k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
13.1k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
13.1k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
13.1k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
13.1k
{
40
13.1k
  return &data[OFFSET_ICOOKIE];
41
13.1k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
13.1k
{
46
13.1k
  return &data[OFFSET_RCOOKIE];
47
13.1k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
13.1k
{
52
13.1k
  return data[OFFSET_NEXTPAYLOAD];
53
13.1k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
13.1k
{
58
13.1k
  return data[OFFSET_VERSION];
59
13.1k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
13.1k
{
64
13.1k
  return data[OFFSET_EXCHANGE];
65
13.1k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
13.1k
{
70
13.1k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
13.1k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
13.1k
{
76
13.1k
  bzero(hdr, sizeof(*hdr));
77
13.1k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
13.1k
      sizeof(hdr->ike_ispi));
79
13.1k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
13.1k
      sizeof(hdr->ike_rspi));
81
13.1k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
13.1k
  hdr->ike_version = get_version(ibuf_data(data));
83
13.1k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
13.1k
  hdr->ike_length = get_length(ibuf_data(data));
85
13.1k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
13.1k
{
90
13.1k
  static struct iked_sa sa;
91
92
13.1k
  bzero(&sa, sizeof(sa));
93
13.1k
  bzero(msg, sizeof(*msg));
94
95
13.1k
  msg->msg_sa = &sa;
96
13.1k
  msg->msg_data = data;
97
13.1k
  msg->msg_e = 1;
98
13.1k
  msg->msg_parent = msg;
99
100
13.1k
  TAILQ_INIT(&msg->msg_proposals);
101
13.1k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
13.1k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
13.1k
{
108
13.1k
  struct ibuf   *fuzzed;
109
13.1k
  struct ike_header  hdr;
110
13.1k
  struct iked_message  msg;
111
112
13.1k
  bzero(&hdr, sizeof(hdr));
113
13.1k
  bzero(&msg, sizeof(msg));
114
115
13.1k
  fuzzed = ibuf_new(data, size);
116
13.1k
  if (fuzzed == NULL){
117
0
    fprintf(stderr, "%s\n", "ERROR: fuzzed == NULL! "
118
0
        "(hint: fuzz-input too long?)");
119
0
    return -1;
120
0
  }  
121
  
122
  /* size too small? */
123
13.1k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
13.1k
  prepare_header(&hdr, fuzzed);
129
13.1k
  prepare_message(&msg, fuzzed);
130
131
13.1k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
13.1k
  ikev2_msg_cleanup(NULL, &msg);
134
135
13.1k
  return 0;
136
13.1k
}
\ No newline at end of file diff --git a/coverage/latest/textcov_reports/test_libfuzzer.covreport b/coverage/latest/textcov_reports/test_libfuzzer.covreport index 5fa2acc2e..54313716d 100644 --- a/coverage/latest/textcov_reports/test_libfuzzer.covreport +++ b/coverage/latest/textcov_reports/test_libfuzzer.covreport @@ -1,66 +1,66 @@ freezero: - 25| 20.3k|{ + 25| 20.4k|{ 26| | /* This is legal. */ - 27| 20.3k| if (ptr == NULL) + 27| 20.4k| if (ptr == NULL) ------------------ - | Branch (27:6): [True: 1.41k, False: 18.9k] + | Branch (27:6): [True: 1.41k, False: 19.0k] ------------------ 28| 1.41k| return; 29| | - 30| 18.9k| explicit_bzero(ptr, sz); - 31| 18.9k| free(ptr); - 32| 18.9k|} + 30| 19.0k| explicit_bzero(ptr, sz); + 31| 19.0k| free(ptr); + 32| 19.0k|} ibuf_dynamic: - 62| 20.3k|{ - 63| 20.3k| struct ibuf *buf; + 62| 20.4k|{ + 63| 20.4k| struct ibuf *buf; 64| | - 65| 20.3k| if (max < len) { + 65| 20.4k| if (max < len) { ------------------ - | Branch (65:6): [True: 0, False: 20.3k] + | Branch (65:6): [True: 0, False: 20.4k] ------------------ 66| 0| errno = EINVAL; 67| 0| return (NULL); 68| 0| } 69| | - 70| 20.3k| if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) + 70| 20.4k| if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) ------------------ - | Branch (70:6): [True: 0, False: 20.3k] + | Branch (70:6): [True: 0, False: 20.4k] ------------------ 71| 0| return (NULL); - 72| 20.3k| if (len > 0) { + 72| 20.4k| if (len > 0) { ------------------ - | Branch (72:6): [True: 18.9k, False: 1.41k] + | Branch (72:6): [True: 19.0k, False: 1.41k] ------------------ - 73| 18.9k| if ((buf->buf = calloc(len, 1)) == NULL) { + 73| 19.0k| if ((buf->buf = calloc(len, 1)) == NULL) { ------------------ - | Branch (73:7): [True: 0, False: 18.9k] + | Branch (73:7): [True: 0, False: 19.0k] ------------------ 74| 0| free(buf); 75| 0| return (NULL); 76| 0| } - 77| 18.9k| } - 78| 20.3k| buf->size = len; - 79| 20.3k| buf->max = max; - 80| 20.3k| buf->fd = -1; + 77| 19.0k| } + 78| 20.4k| buf->size = len; + 79| 20.4k| buf->max = max; + 80| 20.4k| buf->fd = -1; 81| | - 82| 20.3k| return (buf); - 83| 20.3k|} + 82| 20.4k| return (buf); + 83| 20.4k|} ibuf_reserve: - 107| 18.9k|{ - 108| 18.9k| void *b; + 107| 19.0k|{ + 108| 19.0k| void *b; 109| | - 110| 18.9k| if (len > SIZE_MAX - buf->wpos) { + 110| 19.0k| if (len > SIZE_MAX - buf->wpos) { ------------------ - | Branch (110:6): [True: 0, False: 18.9k] + | Branch (110:6): [True: 0, False: 19.0k] ------------------ 111| 0| errno = ERANGE; 112| 0| return (NULL); 113| 0| } 114| | - 115| 18.9k| if (buf->wpos + len > buf->size) + 115| 19.0k| if (buf->wpos + len > buf->size) ------------------ - | Branch (115:6): [True: 0, False: 18.9k] + | Branch (115:6): [True: 0, False: 19.0k] ------------------ 116| 0| if (ibuf_realloc(buf, len) == -1) ------------------ @@ -68,87 +68,87 @@ ibuf_reserve: ------------------ 117| 0| return (NULL); 118| | - 119| 18.9k| b = buf->buf + buf->wpos; - 120| 18.9k| buf->wpos += len; - 121| 18.9k| memset(b, 0, len); - 122| 18.9k| return (b); - 123| 18.9k|} + 119| 19.0k| b = buf->buf + buf->wpos; + 120| 19.0k| buf->wpos += len; + 121| 19.0k| memset(b, 0, len); + 122| 19.0k| return (b); + 123| 19.0k|} ibuf_add: - 127| 18.9k|{ - 128| 18.9k| void *b; + 127| 19.0k|{ + 128| 19.0k| void *b; 129| | - 130| 18.9k| if ((b = ibuf_reserve(buf, len)) == NULL) + 130| 19.0k| if ((b = ibuf_reserve(buf, len)) == NULL) ------------------ - | Branch (130:6): [True: 0, False: 18.9k] + | Branch (130:6): [True: 0, False: 19.0k] ------------------ 131| 0| return (-1); 132| | - 133| 18.9k| memcpy(b, data, len); - 134| 18.9k| return (0); - 135| 18.9k|} + 133| 19.0k| memcpy(b, data, len); + 134| 19.0k| return (0); + 135| 19.0k|} ibuf_seek: - 202| 232k|{ + 202| 233k|{ 203| | /* only allowed to seek in already written parts */ - 204| 232k| if (len > SIZE_MAX - pos || pos + len > buf->wpos) { + 204| 233k| if (len > SIZE_MAX - pos || pos + len > buf->wpos) { ------------------ - | Branch (204:6): [True: 0, False: 232k] - | Branch (204:30): [True: 3.28k, False: 229k] + | Branch (204:6): [True: 0, False: 233k] + | Branch (204:30): [True: 3.28k, False: 230k] ------------------ 205| 3.28k| errno = ERANGE; 206| 3.28k| return (NULL); 207| 3.28k| } 208| | - 209| 229k| return (buf->buf + pos); - 210| 232k|} + 209| 230k| return (buf->buf + pos); + 210| 233k|} ibuf_data: - 272| 707k|{ - 273| 707k| return (buf->buf); - 274| 707k|} + 272| 711k|{ + 273| 711k| return (buf->buf); + 274| 711k|} ibuf_size: - 278| 13.0k|{ - 279| 13.0k| return (buf->wpos); - 280| 13.0k|} + 278| 13.1k|{ + 279| 13.1k| return (buf->wpos); + 280| 13.1k|} ibuf_free: - 296| 175k|{ - 297| 175k| if (buf == NULL) + 296| 177k|{ + 297| 177k| if (buf == NULL) ------------------ - | Branch (297:6): [True: 155k, False: 20.3k] + | Branch (297:6): [True: 157k, False: 20.4k] ------------------ - 298| 155k| return; + 298| 157k| return; 299| |#ifdef NOTYET 300| | if (buf->fd != -1) 301| | close(buf->fd); 302| |#endif - 303| 20.3k| freezero(buf->buf, buf->size); - 304| 20.3k| free(buf); - 305| 20.3k|} + 303| 20.4k| freezero(buf->buf, buf->size); + 304| 20.4k| free(buf); + 305| 20.4k|} strlcpy: - 29| 468k|{ - 30| 468k| const char *osrc = src; - 31| 468k| size_t nleft = dsize; + 29| 471k|{ + 30| 471k| const char *osrc = src; + 31| 471k| size_t nleft = dsize; 32| | 33| | /* Copy as many bytes as will fit. */ - 34| 468k| if (nleft != 0) { + 34| 471k| if (nleft != 0) { ------------------ - | Branch (34:6): [True: 468k, False: 0] + | Branch (34:6): [True: 471k, False: 0] ------------------ - 35| 3.67M| while (--nleft != 0) { + 35| 3.70M| while (--nleft != 0) { ------------------ - | Branch (35:10): [True: 3.67M, False: 1.45k] + | Branch (35:10): [True: 3.70M, False: 1.45k] ------------------ - 36| 3.67M| if ((*dst++ = *src++) == '\0') + 36| 3.70M| if ((*dst++ = *src++) == '\0') ------------------ - | Branch (36:8): [True: 467k, False: 3.20M] + | Branch (36:8): [True: 469k, False: 3.23M] ------------------ - 37| 467k| break; - 38| 3.67M| } - 39| 468k| } + 37| 469k| break; + 38| 3.70M| } + 39| 471k| } 40| | 41| | /* Not enough room in dst, add NUL and traverse rest of src. */ - 42| 468k| if (nleft == 0) { + 42| 471k| if (nleft == 0) { ------------------ - | Branch (42:6): [True: 1.45k, False: 467k] + | Branch (42:6): [True: 1.45k, False: 469k] ------------------ 43| 1.45k| if (dsize != 0) ------------------ @@ -162,157 +162,157 @@ strlcpy: 46| 0| ; 47| 1.45k| } 48| | - 49| 468k| return(src - osrc - 1); /* count does not include NUL */ - 50| 468k|} + 49| 471k| return(src - osrc - 1); /* count does not include NUL */ + 50| 471k|} ikev2_pld_parse: - 118| 13.0k|{ - 119| 13.0k| log_debug("%s: header ispi %s rspi %s" - 120| 13.0k| " nextpayload %s version 0x%02x exchange %s flags 0x%02x" - 121| 13.0k| " msgid %d length %u response %d", __func__, - 122| 13.0k| print_spi(betoh64(hdr->ike_ispi), 8), - 123| 13.0k| print_spi(betoh64(hdr->ike_rspi), 8), - 124| 13.0k| print_map(hdr->ike_nextpayload, ikev2_payload_map), - 125| 13.0k| hdr->ike_version, - 126| 13.0k| print_map(hdr->ike_exchange, ikev2_exchange_map), - 127| 13.0k| hdr->ike_flags, - 128| 13.0k| betoh32(hdr->ike_msgid), - 129| 13.0k| betoh32(hdr->ike_length), - 130| 13.0k| msg->msg_response); + 118| 13.1k|{ + 119| 13.1k| log_debug("%s: header ispi %s rspi %s" + 120| 13.1k| " nextpayload %s version 0x%02x exchange %s flags 0x%02x" + 121| 13.1k| " msgid %d length %u response %d", __func__, + 122| 13.1k| print_spi(betoh64(hdr->ike_ispi), 8), + 123| 13.1k| print_spi(betoh64(hdr->ike_rspi), 8), + 124| 13.1k| print_map(hdr->ike_nextpayload, ikev2_payload_map), + 125| 13.1k| hdr->ike_version, + 126| 13.1k| print_map(hdr->ike_exchange, ikev2_exchange_map), + 127| 13.1k| hdr->ike_flags, + 128| 13.1k| betoh32(hdr->ike_msgid), + 129| 13.1k| betoh32(hdr->ike_length), + 130| 13.1k| msg->msg_response); 131| | - 132| 13.0k| if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) { + 132| 13.1k| if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) { ------------------ - | Branch (132:6): [True: 4, False: 13.0k] + | Branch (132:6): [True: 4, False: 13.1k] ------------------ 133| 4| log_debug("%s: short message", __func__); 134| 4| return (-1); 135| 4| } 136| | - 137| 13.0k| offset += sizeof(*hdr); + 137| 13.1k| offset += sizeof(*hdr); 138| | - 139| 13.0k| return (ikev2_pld_payloads(env, msg, offset, - 140| 13.0k| betoh32(hdr->ike_length), hdr->ike_nextpayload)); - 141| 13.0k|} + 139| 13.1k| return (ikev2_pld_payloads(env, msg, offset, + 140| 13.1k| betoh32(hdr->ike_length), hdr->ike_nextpayload)); + 141| 13.1k|} ikev2_validate_pld: - 146| 234k|{ - 147| 234k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 148| 234k| size_t pld_length; + 146| 235k|{ + 147| 235k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 148| 235k| size_t pld_length; 149| | 150| | /* We need at least the generic header. */ - 151| 234k| if (left < sizeof(*pld)) { + 151| 235k| if (left < sizeof(*pld)) { ------------------ - | Branch (151:6): [True: 1.71k, False: 232k] + | Branch (151:6): [True: 1.73k, False: 233k] ------------------ - 152| 1.71k| log_debug("%s: malformed payload: too short for generic " - 153| 1.71k| "header (%zu < %zu)", __func__, left, sizeof(*pld)); - 154| 1.71k| return (-1); - 155| 1.71k| } - 156| 232k| memcpy(pld, msgbuf + offset, sizeof(*pld)); + 152| 1.73k| log_debug("%s: malformed payload: too short for generic " + 153| 1.73k| "header (%zu < %zu)", __func__, left, sizeof(*pld)); + 154| 1.73k| return (-1); + 155| 1.73k| } + 156| 233k| memcpy(pld, msgbuf + offset, sizeof(*pld)); 157| | 158| | /* 159| | * We need at least the specified number of bytes. 160| | * pld_length is the full size of the payload including 161| | * the generic payload header. 162| | */ - 163| 232k| pld_length = betoh16(pld->pld_length); - 164| 232k| if (left < pld_length) { + 163| 233k| pld_length = betoh16(pld->pld_length); + 164| 233k| if (left < pld_length) { ------------------ - | Branch (164:6): [True: 5.81k, False: 227k] + | Branch (164:6): [True: 5.87k, False: 228k] ------------------ - 165| 5.81k| log_debug("%s: malformed payload: shorter than specified " - 166| 5.81k| "(%zu < %zu)", __func__, left, pld_length); - 167| 5.81k| return (-1); - 168| 5.81k| } + 165| 5.87k| log_debug("%s: malformed payload: shorter than specified " + 166| 5.87k| "(%zu < %zu)", __func__, left, pld_length); + 167| 5.87k| return (-1); + 168| 5.87k| } 169| | /* 170| | * Sanity check the specified payload size, it must 171| | * be at least the size of the generic payload header. 172| | */ - 173| 227k| if (pld_length < sizeof(*pld)) { + 173| 228k| if (pld_length < sizeof(*pld)) { ------------------ - | Branch (173:6): [True: 2.33k, False: 224k] + | Branch (173:6): [True: 2.36k, False: 225k] ------------------ - 174| 2.33k| log_debug("%s: malformed payload: shorter than minimum " - 175| 2.33k| "header size (%zu < %zu)", __func__, pld_length, - 176| 2.33k| sizeof(*pld)); - 177| 2.33k| return (-1); - 178| 2.33k| } + 174| 2.36k| log_debug("%s: malformed payload: shorter than minimum " + 175| 2.36k| "header size (%zu < %zu)", __func__, pld_length, + 176| 2.36k| sizeof(*pld)); + 177| 2.36k| return (-1); + 178| 2.36k| } 179| | - 180| 224k| return (0); - 181| 227k|} + 180| 225k| return (0); + 181| 228k|} ikev2_pld_payloads: - 186| 13.0k|{ - 187| 13.0k| struct ikev2_payload pld; - 188| 13.0k| unsigned int e; - 189| 13.0k| int ret; - 190| 13.0k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 191| 13.0k| size_t total, left; + 186| 13.1k|{ + 187| 13.1k| struct ikev2_payload pld; + 188| 13.1k| unsigned int e; + 189| 13.1k| int ret; + 190| 13.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 191| 13.1k| size_t total, left; 192| | 193| | /* Check if message was decrypted in an E payload */ - 194| 13.0k| e = msg->msg_e ? IKED_E : 0; + 194| 13.1k| e = msg->msg_e ? IKED_E : 0; ------------------ - | | 76| 13.0k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 13.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (194:6): [True: 13.0k, False: 0] + | Branch (194:6): [True: 13.1k, False: 0] ------------------ 195| | 196| | /* Bytes left in datagram. */ - 197| 13.0k| total = length - offset; + 197| 13.1k| total = length - offset; 198| | - 199| 237k| while (payload != 0 && offset < length) { + 199| 238k| while (payload != 0 && offset < length) { ------------------ - | Branch (199:9): [True: 236k, False: 522] - | Branch (199:25): [True: 234k, False: 1.93k] + | Branch (199:9): [True: 237k, False: 525] + | Branch (199:25): [True: 235k, False: 1.94k] ------------------ - 200| 234k| if (ikev2_validate_pld(msg, offset, total, &pld)) + 200| 235k| if (ikev2_validate_pld(msg, offset, total, &pld)) ------------------ - | Branch (200:7): [True: 9.86k, False: 224k] + | Branch (200:7): [True: 9.97k, False: 225k] ------------------ - 201| 9.86k| return (-1); + 201| 9.97k| return (-1); 202| | - 203| 224k| log_debug("%s: %spayload %s" - 204| 224k| " nextpayload %s critical 0x%02x length %d", - 205| 224k| __func__, e ? "decrypted " : "", + 203| 225k| log_debug("%s: %spayload %s" + 204| 225k| " nextpayload %s critical 0x%02x length %d", + 205| 225k| __func__, e ? "decrypted " : "", ------------------ - | Branch (205:17): [True: 224k, False: 0] + | Branch (205:17): [True: 225k, False: 0] ------------------ - 206| 224k| print_map(payload, ikev2_payload_map), - 207| 224k| print_map(pld.pld_nextpayload, ikev2_payload_map), - 208| 224k| pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD, + 206| 225k| print_map(payload, ikev2_payload_map), + 207| 225k| print_map(pld.pld_nextpayload, ikev2_payload_map), + 208| 225k| pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD, ------------------ - | | 89| 224k|#define IKEV2_CRITICAL_PAYLOAD 0x01 /* First bit in the reserved field */ + | | 89| 225k|#define IKEV2_CRITICAL_PAYLOAD 0x01 /* First bit in the reserved field */ ------------------ - 209| 224k| betoh16(pld.pld_length)); + 209| 225k| betoh16(pld.pld_length)); 210| | 211| | /* Skip over generic payload header. */ - 212| 224k| offset += sizeof(pld); - 213| 224k| total -= sizeof(pld); - 214| 224k| left = betoh16(pld.pld_length) - sizeof(pld); - 215| 224k| ret = 0; + 212| 225k| offset += sizeof(pld); + 213| 225k| total -= sizeof(pld); + 214| 225k| left = betoh16(pld.pld_length) - sizeof(pld); + 215| 225k| ret = 0; 216| | - 217| 224k| switch (payload | e) { + 217| 225k| switch (payload | e) { 218| 0| case IKEV2_PAYLOAD_SA: ------------------ | | 93| 0|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ ------------------ - | Branch (218:3): [True: 0, False: 224k] + | Branch (218:3): [True: 0, False: 225k] ------------------ - 219| 28.1k| case IKEV2_PAYLOAD_SA | IKED_E: + 219| 28.2k| case IKEV2_PAYLOAD_SA | IKED_E: ------------------ - | | 93| 28.1k|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ + | | 93| 28.2k|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ ------------------ case IKEV2_PAYLOAD_SA | IKED_E: ------------------ - | | 76| 28.1k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 28.2k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (219:3): [True: 28.1k, False: 196k] + | Branch (219:3): [True: 28.2k, False: 197k] ------------------ - 220| 28.1k| ret = ikev2_pld_sa(env, &pld, msg, offset, left); - 221| 28.1k| break; + 220| 28.2k| ret = ikev2_pld_sa(env, &pld, msg, offset, left); + 221| 28.2k| break; 222| 0| case IKEV2_PAYLOAD_KE: ------------------ | | 94| 0|#define IKEV2_PAYLOAD_KE 34 /* Key Exchange */ ------------------ - | Branch (222:3): [True: 0, False: 224k] + | Branch (222:3): [True: 0, False: 225k] ------------------ 223| 8.28k| case IKEV2_PAYLOAD_KE | IKED_E: ------------------ @@ -322,19 +322,19 @@ ikev2_pld_payloads: ------------------ | | 76| 8.28k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (223:3): [True: 8.28k, False: 216k] + | Branch (223:3): [True: 8.28k, False: 217k] ------------------ 224| 8.28k| ret = ikev2_pld_ke(env, &pld, msg, offset, left); 225| 8.28k| break; - 226| 12.8k| case IKEV2_PAYLOAD_IDi | IKED_E: + 226| 12.9k| case IKEV2_PAYLOAD_IDi | IKED_E: ------------------ - | | 95| 12.8k|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ + | | 95| 12.9k|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ ------------------ case IKEV2_PAYLOAD_IDi | IKED_E: ------------------ - | | 76| 12.8k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 12.9k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (226:3): [True: 12.8k, False: 211k] + | Branch (226:3): [True: 12.9k, False: 212k] ------------------ 227| 19.4k| case IKEV2_PAYLOAD_IDr | IKED_E: ------------------ @@ -344,7 +344,7 @@ ikev2_pld_payloads: ------------------ | | 76| 19.4k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (227:3): [True: 6.57k, False: 218k] + | Branch (227:3): [True: 6.57k, False: 219k] ------------------ 228| 19.4k| ret = ikev2_pld_id(env, &pld, msg, offset, left, 229| 19.4k| payload); @@ -357,7 +357,7 @@ ikev2_pld_payloads: ------------------ | | 76| 5.80k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (231:3): [True: 5.80k, False: 218k] + | Branch (231:3): [True: 5.80k, False: 219k] ------------------ 232| 5.80k| ret = ikev2_pld_cert(env, &pld, msg, offset, left); 233| 5.80k| break; @@ -365,7 +365,7 @@ ikev2_pld_payloads: ------------------ | | 98| 0|#define IKEV2_PAYLOAD_CERTREQ 38 /* Certificate Request */ ------------------ - | Branch (234:3): [True: 0, False: 224k] + | Branch (234:3): [True: 0, False: 225k] ------------------ 235| 12.1k| case IKEV2_PAYLOAD_CERTREQ | IKED_E: ------------------ @@ -375,7 +375,7 @@ ikev2_pld_payloads: ------------------ | | 76| 12.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (235:3): [True: 12.1k, False: 212k] + | Branch (235:3): [True: 12.1k, False: 213k] ------------------ 236| 12.1k| ret = ikev2_pld_certreq(env, &pld, msg, offset, left); 237| 12.1k| break; @@ -387,7 +387,7 @@ ikev2_pld_payloads: ------------------ | | 76| 8.17k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (238:3): [True: 8.17k, False: 216k] + | Branch (238:3): [True: 8.17k, False: 217k] ------------------ 239| 8.17k| ret = ikev2_pld_auth(env, &pld, msg, offset, left); 240| 8.17k| break; @@ -395,7 +395,7 @@ ikev2_pld_payloads: ------------------ | | 100| 0|#define IKEV2_PAYLOAD_NONCE 40 /* Nonce */ ------------------ - | Branch (241:3): [True: 0, False: 224k] + | Branch (241:3): [True: 0, False: 225k] ------------------ 242| 242| case IKEV2_PAYLOAD_NONCE | IKED_E: ------------------ @@ -405,7 +405,7 @@ ikev2_pld_payloads: ------------------ | | 76| 242|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (242:3): [True: 242, False: 224k] + | Branch (242:3): [True: 242, False: 225k] ------------------ 243| 242| ret = ikev2_pld_nonce(env, &pld, msg, offset, left); 244| 242| break; @@ -413,20 +413,20 @@ ikev2_pld_payloads: ------------------ | | 101| 0|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ ------------------ - | Branch (245:3): [True: 0, False: 224k] + | Branch (245:3): [True: 0, False: 225k] ------------------ - 246| 32.0k| case IKEV2_PAYLOAD_NOTIFY | IKED_E: + 246| 32.4k| case IKEV2_PAYLOAD_NOTIFY | IKED_E: ------------------ - | | 101| 32.0k|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ + | | 101| 32.4k|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ ------------------ case IKEV2_PAYLOAD_NOTIFY | IKED_E: ------------------ - | | 76| 32.0k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 32.4k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (246:3): [True: 32.0k, False: 192k] + | Branch (246:3): [True: 32.4k, False: 193k] ------------------ - 247| 32.0k| ret = ikev2_pld_notify(env, &pld, msg, offset, left); - 248| 32.0k| break; + 247| 32.4k| ret = ikev2_pld_notify(env, &pld, msg, offset, left); + 248| 32.4k| break; 249| 7.11k| case IKEV2_PAYLOAD_DELETE | IKED_E: ------------------ | | 102| 7.11k|#define IKEV2_PAYLOAD_DELETE 42 /* Delete */ @@ -435,37 +435,37 @@ ikev2_pld_payloads: ------------------ | | 76| 7.11k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (249:3): [True: 7.11k, False: 217k] + | Branch (249:3): [True: 7.11k, False: 218k] ------------------ 250| 7.11k| ret = ikev2_pld_delete(env, &pld, msg, offset, left); 251| 7.11k| break; - 252| 4.64k| case IKEV2_PAYLOAD_TSi | IKED_E: + 252| 4.65k| case IKEV2_PAYLOAD_TSi | IKED_E: ------------------ - | | 104| 4.64k|#define IKEV2_PAYLOAD_TSi 44 /* Traffic Selector - Initiator */ + | | 104| 4.65k|#define IKEV2_PAYLOAD_TSi 44 /* Traffic Selector - Initiator */ ------------------ case IKEV2_PAYLOAD_TSi | IKED_E: ------------------ - | | 76| 4.64k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 4.65k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (252:3): [True: 4.64k, False: 220k] + | Branch (252:3): [True: 4.65k, False: 221k] ------------------ - 253| 18.0k| case IKEV2_PAYLOAD_TSr | IKED_E: + 253| 18.1k| case IKEV2_PAYLOAD_TSr | IKED_E: ------------------ - | | 105| 18.0k|#define IKEV2_PAYLOAD_TSr 45 /* Traffic Selector - Responder */ + | | 105| 18.1k|#define IKEV2_PAYLOAD_TSr 45 /* Traffic Selector - Responder */ ------------------ case IKEV2_PAYLOAD_TSr | IKED_E: ------------------ - | | 76| 18.0k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 18.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (253:3): [True: 13.4k, False: 211k] + | Branch (253:3): [True: 13.5k, False: 212k] ------------------ - 254| 18.0k| ret = ikev2_pld_tss(env, &pld, msg, offset, left); - 255| 18.0k| break; + 254| 18.1k| ret = ikev2_pld_tss(env, &pld, msg, offset, left); + 255| 18.1k| break; 256| 0| case IKEV2_PAYLOAD_SK: ------------------ | | 106| 0|#define IKEV2_PAYLOAD_SK 46 /* Encrypted */ ------------------ - | Branch (256:3): [True: 0, False: 224k] + | Branch (256:3): [True: 0, False: 225k] ------------------ 257| 0| ret = ikev2_pld_e(env, &pld, msg, offset, left); 258| 0| break; @@ -473,7 +473,7 @@ ikev2_pld_payloads: ------------------ | | 110| 0|#define IKEV2_PAYLOAD_SKF 53 /* RFC7383 Encrypted Fragment Payload */ ------------------ - | Branch (259:3): [True: 0, False: 224k] + | Branch (259:3): [True: 0, False: 225k] ------------------ 260| 0| ret = ikev2_pld_ef(env, &pld, msg, offset, left); 261| 0| break; @@ -485,39 +485,39 @@ ikev2_pld_payloads: ------------------ | | 76| 9.77k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (262:3): [True: 9.77k, False: 214k] + | Branch (262:3): [True: 9.77k, False: 215k] ------------------ 263| 9.77k| ret = ikev2_pld_cp(env, &pld, msg, offset, left); 264| 9.77k| break; - 265| 17.0k| case IKEV2_PAYLOAD_EAP | IKED_E: + 265| 17.1k| case IKEV2_PAYLOAD_EAP | IKED_E: ------------------ - | | 108| 17.0k|#define IKEV2_PAYLOAD_EAP 48 /* Extensible Authentication */ + | | 108| 17.1k|#define IKEV2_PAYLOAD_EAP 48 /* Extensible Authentication */ ------------------ case IKEV2_PAYLOAD_EAP | IKED_E: ------------------ - | | 76| 17.0k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 17.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (265:3): [True: 17.0k, False: 207k] + | Branch (265:3): [True: 17.1k, False: 208k] ------------------ - 266| 17.0k| ret = ikev2_pld_eap(env, &pld, msg, offset, left); - 267| 17.0k| break; - 268| 58.3k| default: + 266| 17.1k| ret = ikev2_pld_eap(env, &pld, msg, offset, left); + 267| 17.1k| break; + 268| 58.8k| default: ------------------ - | Branch (268:3): [True: 58.3k, False: 166k] + | Branch (268:3): [True: 58.8k, False: 166k] ------------------ - 269| 58.3k| print_hex(msgbuf, offset, - 270| 58.3k| betoh16(pld.pld_length) - sizeof(pld)); - 271| 58.3k| break; - 272| 224k| } + 269| 58.8k| print_hex(msgbuf, offset, + 270| 58.8k| betoh16(pld.pld_length) - sizeof(pld)); + 271| 58.8k| break; + 272| 225k| } 273| | - 274| 224k| if (ret != 0 && ikev2_msg_frompeer(msg)) { + 274| 225k| if (ret != 0 && ikev2_msg_frompeer(msg)) { ------------------ - | Branch (274:7): [True: 95.0k, False: 129k] - | Branch (274:19): [True: 722, False: 94.3k] + | Branch (274:7): [True: 95.2k, False: 130k] + | Branch (274:19): [True: 723, False: 94.5k] ------------------ - 275| 722| (void)ikev2_send_informational(env, msg); - 276| 722| return (-1); - 277| 722| } + 275| 723| (void)ikev2_send_informational(env, msg); + 276| 723| return (-1); + 277| 723| } 278| | 279| | /* Encrypted payloads must appear last */ 280| 224k| if ((payload == IKEV2_PAYLOAD_SK) || @@ -539,25 +539,25 @@ ikev2_pld_payloads: 286| 224k| total -= left; 287| 224k| } 288| | - 289| 2.45k| return (0); - 290| 13.0k|} + 289| 2.47k| return (0); + 290| 13.1k|} ikev2_validate_sa: - 295| 32.5k|{ - 296| 32.5k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 297| 32.5k| size_t sap_length; + 295| 32.6k|{ + 296| 32.6k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 297| 32.6k| size_t sap_length; 298| | - 299| 32.5k| if (left < sizeof(*sap)) { + 299| 32.6k| if (left < sizeof(*sap)) { ------------------ - | Branch (299:6): [True: 13.8k, False: 18.6k] + | Branch (299:6): [True: 13.9k, False: 18.7k] ------------------ - 300| 13.8k| log_debug("%s: malformed payload: too short for header " - 301| 13.8k| "(%zu < %zu)", __func__, left, sizeof(*sap)); - 302| 13.8k| return (-1); - 303| 13.8k| } - 304| 18.6k| memcpy(sap, msgbuf + offset, sizeof(*sap)); + 300| 13.9k| log_debug("%s: malformed payload: too short for header " + 301| 13.9k| "(%zu < %zu)", __func__, left, sizeof(*sap)); + 302| 13.9k| return (-1); + 303| 13.9k| } + 304| 18.7k| memcpy(sap, msgbuf + offset, sizeof(*sap)); 305| | - 306| 18.6k| sap_length = betoh16(sap->sap_length); - 307| 18.6k| if (sap_length < sizeof(*sap)) { + 306| 18.7k| sap_length = betoh16(sap->sap_length); + 307| 18.7k| if (sap_length < sizeof(*sap)) { ------------------ | Branch (307:6): [True: 5.01k, False: 13.6k] ------------------ @@ -579,7 +579,7 @@ ikev2_validate_sa: 320| | */ 321| 11.3k| if (!sap->sap_more && left != sap_length) { ------------------ - | Branch (321:6): [True: 1.60k, False: 9.76k] + | Branch (321:6): [True: 1.60k, False: 9.78k] | Branch (321:24): [True: 30, False: 1.57k] ------------------ 322| 30| log_debug("%s: malformed payload: SA payload length mismatches " @@ -593,8 +593,8 @@ ikev2_validate_sa: 330| | */ 331| 11.3k| if (sap->sap_more && left <= sap_length) { ------------------ - | Branch (331:6): [True: 9.76k, False: 1.57k] - | Branch (331:23): [True: 839, False: 8.93k] + | Branch (331:6): [True: 9.78k, False: 1.57k] + | Branch (331:23): [True: 839, False: 8.94k] ------------------ 332| 839| log_debug("%s: malformed payload: SA payload too small for " 333| 839| "further proposals (%zu <= %zu)", __func__, @@ -604,18 +604,18 @@ ikev2_validate_sa: 337| 10.5k| return (0); 338| 11.3k|} ikev2_pld_sa: - 343| 28.1k|{ - 344| 28.1k| struct ikev2_sa_proposal sap; - 345| 28.1k| struct iked_proposal *prop = NULL; - 346| 28.1k| uint32_t spi32; - 347| 28.1k| uint64_t spi = 0, spi64; - 348| 28.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 349| 28.1k| int r; - 350| 28.1k| struct iked_proposals *props; - 351| 28.1k| size_t total; + 343| 28.2k|{ + 344| 28.2k| struct ikev2_sa_proposal sap; + 345| 28.2k| struct iked_proposal *prop = NULL; + 346| 28.2k| uint32_t spi32; + 347| 28.2k| uint64_t spi = 0, spi64; + 348| 28.2k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 349| 28.2k| int r; + 350| 28.2k| struct iked_proposals *props; + 351| 28.2k| size_t total; 352| | - 353| 32.5k| do { - 354| 32.5k| if (ikev2_validate_sa(msg, offset, left, &sap)) + 353| 32.6k| do { + 354| 32.6k| if (ikev2_validate_sa(msg, offset, left, &sap)) ------------------ | Branch (354:7): [True: 22.0k, False: 10.5k] ------------------ @@ -631,7 +631,7 @@ ikev2_pld_sa: 364| | 365| 10.5k| if (sap.sap_spisize) { ------------------ - | Branch (365:7): [True: 1.40k, False: 9.10k] + | Branch (365:7): [True: 1.40k, False: 9.11k] ------------------ 366| 1.40k| if (left < sap.sap_spisize) { ------------------ @@ -686,25 +686,25 @@ ikev2_pld_sa: 401| | * As we verified sanity of packet headers, this check will 402| | * be always false, but just to be sure we keep it. 403| | */ - 404| 9.59k| if (left < total) { + 404| 9.60k| if (left < total) { ------------------ - | Branch (404:7): [True: 0, False: 9.59k] + | Branch (404:7): [True: 0, False: 9.60k] ------------------ 405| 0| log_debug("%s: malformed payload: too long for payload " 406| 0| "(%zu < %zu)", __func__, left, total); 407| 0| return (-1); 408| 0| } 409| | - 410| 9.59k| log_debug("%s: more %d reserved %d length %d" - 411| 9.59k| " proposal #%d protoid %s spisize %d xforms %d spi %s", - 412| 9.59k| __func__, sap.sap_more, sap.sap_reserved, - 413| 9.59k| betoh16(sap.sap_length), sap.sap_proposalnr, - 414| 9.59k| print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize, - 415| 9.59k| sap.sap_transforms, print_spi(spi, sap.sap_spisize)); + 410| 9.60k| log_debug("%s: more %d reserved %d length %d" + 411| 9.60k| " proposal #%d protoid %s spisize %d xforms %d spi %s", + 412| 9.60k| __func__, sap.sap_more, sap.sap_reserved, + 413| 9.60k| betoh16(sap.sap_length), sap.sap_proposalnr, + 414| 9.60k| print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize, + 415| 9.60k| sap.sap_transforms, print_spi(spi, sap.sap_spisize)); 416| | - 417| 9.59k| if (ikev2_msg_frompeer(msg)) { + 417| 9.60k| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (417:7): [True: 69, False: 9.52k] + | Branch (417:7): [True: 69, False: 9.53k] ------------------ 418| 69| if ((msg->msg_parent->msg_prop = config_add_proposal(props, ------------------ @@ -726,14 +726,14 @@ ikev2_pld_sa: 432| | /* 433| | * Parse the attached transforms 434| | */ - 435| 9.52k| if (sap.sap_transforms) { + 435| 9.53k| if (sap.sap_transforms) { ------------------ - | Branch (435:7): [True: 5.44k, False: 4.07k] + | Branch (435:7): [True: 5.45k, False: 4.08k] ------------------ - 436| 5.44k| r = ikev2_pld_xform(env, msg, offset, total); - 437| 5.44k| if ((r == -2) && ikev2_msg_frompeer(msg)) { + 436| 5.45k| r = ikev2_pld_xform(env, msg, offset, total); + 437| 5.45k| if ((r == -2) && ikev2_msg_frompeer(msg)) { ------------------ - | Branch (437:8): [True: 0, False: 5.44k] + | Branch (437:8): [True: 0, False: 5.45k] | Branch (437:21): [True: 0, False: 0] ------------------ 438| 0| log_debug("%s: invalid proposal transform", @@ -742,7 +742,7 @@ ikev2_pld_sa: 441| | /* cleanup and ignore proposal */ 442| 0| config_free_proposal(props, prop); 443| 0| prop = msg->msg_parent->msg_prop = NULL; - 444| 5.44k| } else if (r != 0) { + 444| 5.45k| } else if (r != 0) { ------------------ | Branch (444:15): [True: 4.37k, False: 1.07k] ------------------ @@ -750,23 +750,23 @@ ikev2_pld_sa: 446| 4.37k| __func__); 447| 4.37k| return (-1); 448| 4.37k| } - 449| 5.44k| } + 449| 5.45k| } 450| | - 451| 5.14k| offset += total; - 452| 5.14k| left -= total; - 453| 5.14k| } while (sap.sap_more); + 451| 5.16k| offset += total; + 452| 5.16k| left -= total; + 453| 5.16k| } while (sap.sap_more); ------------------ - | Branch (453:11): [True: 4.39k, False: 747] + | Branch (453:11): [True: 4.41k, False: 750] ------------------ 454| | - 455| 747| return (0); - 456| 28.1k|} + 455| 750| return (0); + 456| 28.2k|} ikev2_validate_xform: - 461| 7.29k|{ - 462| 7.29k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 463| 7.29k| size_t xfrm_length; + 461| 7.30k|{ + 462| 7.30k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 463| 7.30k| size_t xfrm_length; 464| | - 465| 7.29k| if (total < sizeof(*xfrm)) { + 465| 7.30k| if (total < sizeof(*xfrm)) { ------------------ | Branch (465:6): [True: 625, False: 6.67k] ------------------ @@ -797,14 +797,14 @@ ikev2_validate_xform: 484| 4.90k| return (0); 485| 5.54k|} ikev2_pld_xform: - 490| 7.29k|{ - 491| 7.29k| struct ikev2_transform xfrm; - 492| 7.29k| char id[BUFSIZ]; - 493| 7.29k| int ret = 0; - 494| 7.29k| int r; - 495| 7.29k| size_t xfrm_length; + 490| 7.30k|{ + 491| 7.30k| struct ikev2_transform xfrm; + 492| 7.30k| char id[BUFSIZ]; + 493| 7.30k| int ret = 0; + 494| 7.30k| int r; + 495| 7.30k| size_t xfrm_length; 496| | - 497| 7.29k| if (ikev2_validate_xform(msg, offset, total, &xfrm)) + 497| 7.30k| if (ikev2_validate_xform(msg, offset, total, &xfrm)) ------------------ | Branch (497:6): [True: 2.39k, False: 4.90k] ------------------ @@ -835,7 +835,7 @@ ikev2_pld_xform: ------------------ | | 158| 154|#define IKEV2_XFORMTYPE_INTEGR 3 /* Integrity Algorithm */ ------------------ - | Branch (511:2): [True: 154, False: 4.74k] + | Branch (511:2): [True: 154, False: 4.75k] ------------------ 512| 154| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), 513| 154| ikev2_xformauth_map), sizeof(id)); @@ -853,7 +853,7 @@ ikev2_pld_xform: ------------------ | | 160| 1.00k|#define IKEV2_XFORMTYPE_ESN 5 /* Extended Sequence Numbers */ ------------------ - | Branch (519:2): [True: 1.00k, False: 3.89k] + | Branch (519:2): [True: 1.00k, False: 3.90k] ------------------ 520| 1.00k| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), 521| 1.00k| ikev2_xformesn_map), sizeof(id)); @@ -877,7 +877,7 @@ ikev2_pld_xform: 536| 4.90k| msg->msg_attrlength = 0; 537| 4.90k| if (xfrm_length > sizeof(xfrm)) { ------------------ - | Branch (537:6): [True: 2.34k, False: 2.55k] + | Branch (537:6): [True: 2.34k, False: 2.56k] ------------------ 538| 2.34k| if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm), ------------------ @@ -888,9 +888,9 @@ ikev2_pld_xform: 541| 1.80k| } 542| 2.34k| } 543| | - 544| 3.09k| if (ikev2_msg_frompeer(msg)) { + 544| 3.10k| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (544:6): [True: 0, False: 3.09k] + | Branch (544:6): [True: 0, False: 3.10k] ------------------ 545| 0| r = config_add_transform(msg->msg_parent->msg_prop, 546| 0| xfrm.xfrm_type, betoh16(xfrm.xfrm_id), @@ -913,16 +913,16 @@ ikev2_pld_xform: 557| 0| } 558| | 559| | /* Next transform */ - 560| 3.09k| offset += xfrm_length; - 561| 3.09k| total -= xfrm_length; - 562| 3.09k| if (xfrm.xfrm_more == IKEV2_XFORM_MORE) + 560| 3.10k| offset += xfrm_length; + 561| 3.10k| total -= xfrm_length; + 562| 3.10k| if (xfrm.xfrm_more == IKEV2_XFORM_MORE) ------------------ - | | 154| 3.09k|#define IKEV2_XFORM_MORE 3 + | | 154| 3.10k|#define IKEV2_XFORM_MORE 3 ------------------ - | Branch (562:6): [True: 1.85k, False: 1.24k] + | Branch (562:6): [True: 1.85k, False: 1.25k] ------------------ 563| 1.85k| ret = ikev2_pld_xform(env, msg, offset, total); - 564| 1.24k| else if (total != 0) { + 564| 1.25k| else if (total != 0) { ------------------ | Branch (564:11): [True: 177, False: 1.07k] ------------------ @@ -932,8 +932,8 @@ ikev2_pld_xform: 568| 177| ret = -1; 569| 177| } 570| | - 571| 3.09k| return (ret); - 572| 3.09k|} + 571| 3.10k| return (ret); + 572| 3.10k|} ikev2_validate_attr: 577| 29.4k|{ 578| 29.4k| uint8_t *msgbuf = ibuf_data(msg->msg_data); @@ -1033,12 +1033,12 @@ ikev2_validate_ke: 650| | 651| 8.28k| if (left < sizeof(*kex)) { ------------------ - | Branch (651:6): [True: 5.11k, False: 3.16k] + | Branch (651:6): [True: 5.12k, False: 3.16k] ------------------ - 652| 5.11k| log_debug("%s: malformed payload: too short for header " - 653| 5.11k| "(%zu < %zu)", __func__, left, sizeof(*kex)); - 654| 5.11k| return (-1); - 655| 5.11k| } + 652| 5.12k| log_debug("%s: malformed payload: too short for header " + 653| 5.12k| "(%zu < %zu)", __func__, left, sizeof(*kex)); + 654| 5.12k| return (-1); + 655| 5.12k| } 656| 3.16k| memcpy(kex, msgbuf + offset, sizeof(*kex)); 657| | 658| 3.16k| return (0); @@ -1052,9 +1052,9 @@ ikev2_pld_ke: 669| | 670| 8.28k| if (ikev2_validate_ke(msg, offset, left, &kex)) ------------------ - | Branch (670:6): [True: 5.11k, False: 3.16k] + | Branch (670:6): [True: 5.12k, False: 3.16k] ------------------ - 671| 5.11k| return (-1); + 671| 5.12k| return (-1); 672| | 673| 3.16k| log_debug("%s: dh group %s reserved %d", __func__, 674| 3.16k| print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map), @@ -1102,12 +1102,12 @@ ikev2_validate_id: 707| | 708| 19.4k| if (left < sizeof(*id)) { ------------------ - | Branch (708:6): [True: 7.62k, False: 11.8k] + | Branch (708:6): [True: 7.63k, False: 11.8k] ------------------ - 709| 7.62k| log_debug("%s: malformed payload: too short for header " - 710| 7.62k| "(%zu < %zu)", __func__, left, sizeof(*id)); - 711| 7.62k| return (-1); - 712| 7.62k| } + 709| 7.63k| log_debug("%s: malformed payload: too short for header " + 710| 7.63k| "(%zu < %zu)", __func__, left, sizeof(*id)); + 711| 7.63k| return (-1); + 712| 7.63k| } 713| 11.8k| memcpy(id, msgbuf + offset, sizeof(*id)); 714| | 715| 11.8k| if (id->id_type == IKEV2_ID_NONE) { @@ -1552,122 +1552,122 @@ ikev2_pld_nonce: 1026| 141| return (0); 1027| 160|} ikev2_validate_notify: - 1032| 32.0k|{ - 1033| 32.0k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1032| 32.4k|{ + 1033| 32.4k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1034| | - 1035| 32.0k| if (left < sizeof(*n)) { + 1035| 32.4k| if (left < sizeof(*n)) { ------------------ - | Branch (1035:6): [True: 3.51k, False: 28.5k] + | Branch (1035:6): [True: 3.51k, False: 28.8k] ------------------ 1036| 3.51k| log_debug("%s: malformed payload: too short for header " 1037| 3.51k| "(%zu < %zu)", __func__, left, sizeof(*n)); 1038| 3.51k| return (-1); 1039| 3.51k| } - 1040| 28.5k| memcpy(n, msgbuf + offset, sizeof(*n)); + 1040| 28.8k| memcpy(n, msgbuf + offset, sizeof(*n)); 1041| | - 1042| 28.5k| return (0); - 1043| 32.0k|} + 1042| 28.8k| return (0); + 1043| 32.4k|} ikev2_pld_notify: - 1048| 32.0k|{ - 1049| 32.0k| struct ikev2_notify n; - 1050| 32.0k| const struct iked_sa *sa = msg->msg_sa; - 1051| 32.0k| uint8_t *buf, md[SHA_DIGEST_LENGTH]; - 1052| 32.0k| uint32_t spi32; - 1053| 32.0k| uint64_t spi64; - 1054| 32.0k| struct iked_spi *rekey; - 1055| 32.0k| uint16_t type; - 1056| 32.0k| uint16_t signature_hash; + 1048| 32.4k|{ + 1049| 32.4k| struct ikev2_notify n; + 1050| 32.4k| const struct iked_sa *sa = msg->msg_sa; + 1051| 32.4k| uint8_t *buf, md[SHA_DIGEST_LENGTH]; + 1052| 32.4k| uint32_t spi32; + 1053| 32.4k| uint64_t spi64; + 1054| 32.4k| struct iked_spi *rekey; + 1055| 32.4k| uint16_t type; + 1056| 32.4k| uint16_t signature_hash; 1057| | - 1058| 32.0k| if (ikev2_validate_notify(msg, offset, left, &n)) + 1058| 32.4k| if (ikev2_validate_notify(msg, offset, left, &n)) ------------------ - | Branch (1058:6): [True: 3.51k, False: 28.5k] + | Branch (1058:6): [True: 3.51k, False: 28.8k] ------------------ 1059| 3.51k| return (-1); - 1060| 28.5k| type = betoh16(n.n_type); + 1060| 28.8k| type = betoh16(n.n_type); 1061| | - 1062| 28.5k| log_debug("%s: protoid %s spisize %d type %s", - 1063| 28.5k| __func__, - 1064| 28.5k| print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize, - 1065| 28.5k| print_map(type, ikev2_n_map)); + 1062| 28.8k| log_debug("%s: protoid %s spisize %d type %s", + 1063| 28.8k| __func__, + 1064| 28.8k| print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize, + 1065| 28.8k| print_map(type, ikev2_n_map)); 1066| | - 1067| 28.5k| left -= sizeof(n); - 1068| 28.5k| if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL) + 1067| 28.8k| left -= sizeof(n); + 1068| 28.8k| if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL) ------------------ - | Branch (1068:6): [True: 0, False: 28.5k] + | Branch (1068:6): [True: 0, False: 28.8k] ------------------ 1069| 0| return (-1); 1070| | - 1071| 28.5k| print_hex(buf, 0, left); + 1071| 28.8k| print_hex(buf, 0, left); 1072| | - 1073| 28.5k| if (!ikev2_msg_frompeer(msg)) + 1073| 28.8k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (1073:6): [True: 1.44k, False: 27.0k] + | Branch (1073:6): [True: 1.44k, False: 27.4k] ------------------ 1074| 1.44k| return (0); 1075| | - 1076| 27.0k| switch (type) { + 1076| 27.4k| switch (type) { ------------------ - | Branch (1076:10): [True: 2.05k, False: 25.0k] + | Branch (1076:10): [True: 2.07k, False: 25.3k] ------------------ 1077| 3.05k| case IKEV2_N_NAT_DETECTION_SOURCE_IP: ------------------ | | 330| 3.05k|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ ------------------ - | Branch (1077:2): [True: 3.05k, False: 24.0k] + | Branch (1077:2): [True: 3.05k, False: 24.3k] ------------------ - 1078| 22.6k| case IKEV2_N_NAT_DETECTION_DESTINATION_IP: + 1078| 23.0k| case IKEV2_N_NAT_DETECTION_DESTINATION_IP: ------------------ - | | 331| 22.6k|#define IKEV2_N_NAT_DETECTION_DESTINATION_IP 16389 /* RFC7296 */ + | | 331| 23.0k|#define IKEV2_N_NAT_DETECTION_DESTINATION_IP 16389 /* RFC7296 */ ------------------ - | Branch (1078:2): [True: 19.6k, False: 7.47k] + | Branch (1078:2): [True: 19.9k, False: 7.49k] ------------------ - 1079| 22.6k| if (left != sizeof(md)) { + 1079| 23.0k| if (left != sizeof(md)) { ------------------ - | Branch (1079:7): [True: 16, False: 22.6k] + | Branch (1079:7): [True: 16, False: 22.9k] ------------------ 1080| 16| log_debug("%s: malformed payload: hash size mismatch" 1081| 16| " (%zu != %zu)", __func__, left, sizeof(md)); 1082| 16| return (-1); 1083| 16| } - 1084| 22.6k| if (ikev2_nat_detection(env, msg, md, sizeof(md), type, + 1084| 22.9k| if (ikev2_nat_detection(env, msg, md, sizeof(md), type, ------------------ - | Branch (1084:7): [True: 0, False: 22.6k] + | Branch (1084:7): [True: 0, False: 22.9k] ------------------ - 1085| 22.6k| ikev2_msg_frompeer(msg)) == -1) + 1085| 22.9k| ikev2_msg_frompeer(msg)) == -1) 1086| 0| return (-1); - 1087| 22.6k| if (memcmp(buf, md, left) != 0) { + 1087| 22.9k| if (memcmp(buf, md, left) != 0) { ------------------ - | Branch (1087:7): [True: 22.6k, False: 0] + | Branch (1087:7): [True: 22.9k, False: 0] ------------------ - 1088| 22.6k| log_debug("%s: %s detected NAT", __func__, - 1089| 22.6k| print_map(type, ikev2_n_map)); - 1090| 22.6k| if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP) + 1088| 22.9k| log_debug("%s: %s detected NAT", __func__, + 1089| 22.9k| print_map(type, ikev2_n_map)); + 1090| 22.9k| if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP) ------------------ - | | 330| 22.6k|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ + | | 330| 22.9k|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ ------------------ - | Branch (1090:8): [True: 3.04k, False: 19.5k] + | Branch (1090:8): [True: 3.05k, False: 19.9k] ------------------ - 1091| 3.04k| msg->msg_parent->msg_nat_detected - 1092| 3.04k| |= IKED_MSG_NAT_SRC_IP; + 1091| 3.05k| msg->msg_parent->msg_nat_detected + 1092| 3.05k| |= IKED_MSG_NAT_SRC_IP; ------------------ - | | 687| 3.04k|#define IKED_MSG_NAT_SRC_IP 0x01 + | | 687| 3.05k|#define IKED_MSG_NAT_SRC_IP 0x01 ------------------ - 1093| 19.5k| else - 1094| 19.5k| msg->msg_parent->msg_nat_detected - 1095| 19.5k| |= IKED_MSG_NAT_DST_IP; + 1093| 19.9k| else + 1094| 19.9k| msg->msg_parent->msg_nat_detected + 1095| 19.9k| |= IKED_MSG_NAT_DST_IP; ------------------ - | | 688| 19.5k|#define IKED_MSG_NAT_DST_IP 0x02 + | | 688| 19.9k|#define IKED_MSG_NAT_DST_IP 0x02 ------------------ - 1096| 22.6k| } - 1097| 22.6k| print_hex(md, 0, sizeof(md)); + 1096| 22.9k| } + 1097| 22.9k| print_hex(md, 0, sizeof(md)); 1098| | /* remember for MOBIKE */ - 1099| 22.6k| msg->msg_parent->msg_natt_rcvd = 1; - 1100| 22.6k| break; + 1099| 22.9k| msg->msg_parent->msg_natt_rcvd = 1; + 1100| 22.9k| break; 1101| 6| case IKEV2_N_AUTHENTICATION_FAILED: ------------------ | | 314| 6|#define IKEV2_N_AUTHENTICATION_FAILED 24 /* RFC7296 */ ------------------ - | Branch (1101:2): [True: 6, False: 27.0k] + | Branch (1101:2): [True: 6, False: 27.4k] ------------------ 1102| 6| if (!msg->msg_e) { ------------------ @@ -1720,7 +1720,7 @@ ikev2_pld_notify: ------------------ | | 313| 135|#define IKEV2_N_INVALID_KE_PAYLOAD 17 /* RFC7296 */ ------------------ - | Branch (1130:2): [True: 135, False: 26.9k] + | Branch (1130:2): [True: 135, False: 27.3k] ------------------ 1131| 135| if (sa_stateok(sa, IKEV2_STATE_VALID) && ------------------ @@ -1755,7 +1755,7 @@ ikev2_pld_notify: ------------------ | | 316| 241|#define IKEV2_N_NO_ADDITIONAL_SAS 35 /* RFC7296 */ ------------------ - | Branch (1146:2): [True: 241, False: 26.8k] + | Branch (1146:2): [True: 241, False: 27.1k] ------------------ 1147| 241| if (!msg->msg_e) { ------------------ @@ -1774,7 +1774,7 @@ ikev2_pld_notify: ------------------ | | 335| 75|#define IKEV2_N_REKEY_SA 16393 /* RFC7296 */ ------------------ - | Branch (1154:2): [True: 75, False: 27.0k] + | Branch (1154:2): [True: 75, False: 27.3k] ------------------ 1155| 75| if (!msg->msg_e) { ------------------ @@ -1833,7 +1833,7 @@ ikev2_pld_notify: ------------------ | | 324| 348|#define IKEV2_N_TEMPORARY_FAILURE 43 /* RFC7296 */ ------------------ - | Branch (1190:2): [True: 348, False: 26.7k] + | Branch (1190:2): [True: 348, False: 27.0k] ------------------ 1191| 348| if (!msg->msg_e) { ------------------ @@ -1852,7 +1852,7 @@ ikev2_pld_notify: ------------------ | | 329| 255|#define IKEV2_N_IPCOMP_SUPPORTED 16387 /* RFC7296 */ ------------------ - | Branch (1198:2): [True: 255, False: 26.8k] + | Branch (1198:2): [True: 255, False: 27.1k] ------------------ 1199| 255| if (!msg->msg_e) { ------------------ @@ -1895,7 +1895,7 @@ ikev2_pld_notify: ------------------ | | 325| 73|#define IKEV2_N_CHILD_SA_NOT_FOUND 44 /* RFC7296 */ ------------------ - | Branch (1224:2): [True: 73, False: 27.0k] + | Branch (1224:2): [True: 73, False: 27.3k] ------------------ 1225| 73| if (!msg->msg_e) { ------------------ @@ -1914,7 +1914,7 @@ ikev2_pld_notify: ------------------ | | 312| 36|#define IKEV2_N_NO_PROPOSAL_CHOSEN 14 /* RFC7296 */ ------------------ - | Branch (1232:2): [True: 36, False: 27.0k] + | Branch (1232:2): [True: 36, False: 27.4k] ------------------ 1233| 36| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN; ------------------ @@ -1925,7 +1925,7 @@ ikev2_pld_notify: ------------------ | | 338| 267|#define IKEV2_N_MOBIKE_SUPPORTED 16396 /* RFC4555 */ ------------------ - | Branch (1235:2): [True: 267, False: 26.8k] + | Branch (1235:2): [True: 267, False: 27.1k] ------------------ 1236| 267| if (!msg->msg_e) { ------------------ @@ -1952,7 +1952,7 @@ ikev2_pld_notify: ------------------ | | 333| 316|#define IKEV2_N_USE_TRANSPORT_MODE 16391 /* RFC7296 */ ------------------ - | Branch (1248:2): [True: 316, False: 26.7k] + | Branch (1248:2): [True: 316, False: 27.1k] ------------------ 1249| 316| if (!msg->msg_e) { ------------------ @@ -1994,7 +1994,7 @@ ikev2_pld_notify: ------------------ | | 342| 388|#define IKEV2_N_UPDATE_SA_ADDRESSES 16400 /* RFC4555 */ ------------------ - | Branch (1268:2): [True: 388, False: 26.6k] + | Branch (1268:2): [True: 388, False: 27.0k] ------------------ 1269| 388| if (!msg->msg_e) { ------------------ @@ -2026,7 +2026,7 @@ ikev2_pld_notify: ------------------ | | 343| 202|#define IKEV2_N_COOKIE2 16401 /* RFC4555 */ ------------------ - | Branch (1286:2): [True: 202, False: 26.8k] + | Branch (1286:2): [True: 202, False: 27.2k] ------------------ 1287| 202| if (!msg->msg_e) { ------------------ @@ -2073,7 +2073,7 @@ ikev2_pld_notify: ------------------ | | 332| 2|#define IKEV2_N_COOKIE 16390 /* RFC7296 */ ------------------ - | Branch (1309:2): [True: 2, False: 27.0k] + | Branch (1309:2): [True: 2, False: 27.4k] ------------------ 1310| 2| if (msg->msg_e) { ------------------ @@ -2115,7 +2115,7 @@ ikev2_pld_notify: ------------------ | | 371| 14|#define IKEV2_N_FRAGMENTATION_SUPPORTED 16430 /* RFC7383 */ ------------------ - | Branch (1330:2): [True: 14, False: 27.0k] + | Branch (1330:2): [True: 14, False: 27.4k] ------------------ 1331| 14| if (msg->msg_e) { ------------------ @@ -2142,7 +2142,7 @@ ikev2_pld_notify: ------------------ | | 372| 7|#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431 /* RFC7427 */ ------------------ - | Branch (1343:2): [True: 7, False: 27.0k] + | Branch (1343:2): [True: 7, False: 27.4k] ------------------ 1344| 7| if (msg->msg_e) { ------------------ @@ -2204,10 +2204,10 @@ ikev2_pld_notify: ------------------ 1376| 0| } 1377| 0| break; - 1378| 27.0k| } + 1378| 27.4k| } 1379| | - 1380| 26.0k| return (0); - 1381| 27.0k|} + 1380| 26.4k| return (0); + 1381| 27.4k|} ikev2_validate_delete: 1386| 7.11k|{ 1387| 7.11k| uint8_t *msgbuf = ibuf_data(msg->msg_data); @@ -2224,13 +2224,13 @@ ikev2_validate_delete: 1395| | 1396| 5.72k| if (del->del_protoid == 0) { ------------------ - | Branch (1396:6): [True: 84, False: 5.63k] + | Branch (1396:6): [True: 84, False: 5.64k] ------------------ 1397| 84| log_info("%s: malformed payload: invalid protoid", __func__); 1398| 84| return (-1); 1399| 84| } 1400| | - 1401| 5.63k| return (0); + 1401| 5.64k| return (0); 1402| 5.72k|} ikev2_pld_delete: 1407| 7.11k|{ @@ -2240,49 +2240,49 @@ ikev2_pld_delete: 1411| | 1412| 7.11k| if (ikev2_validate_delete(msg, offset, left, &del)) ------------------ - | Branch (1412:6): [True: 1.47k, False: 5.63k] + | Branch (1412:6): [True: 1.47k, False: 5.64k] ------------------ 1413| 1.47k| return (-1); 1414| | 1415| | /* Skip if it's a response, then we don't have to deal with it */ - 1416| 5.63k| if (ikev2_msg_frompeer(msg) && + 1416| 5.64k| if (ikev2_msg_frompeer(msg) && ------------------ - | Branch (1416:6): [True: 168, False: 5.46k] + | Branch (1416:6): [True: 168, False: 5.47k] ------------------ - 1417| 5.63k| msg->msg_parent->msg_response) + 1417| 5.64k| msg->msg_parent->msg_response) ------------------ | Branch (1417:6): [True: 0, False: 168] ------------------ 1418| 0| return (0); 1419| | - 1420| 5.63k| cnt = betoh16(del.del_nspi); - 1421| 5.63k| sz = del.del_spisize; + 1420| 5.64k| cnt = betoh16(del.del_nspi); + 1421| 5.64k| sz = del.del_spisize; 1422| | - 1423| 5.63k| log_debug("%s: proto %s spisize %zu nspi %zu", - 1424| 5.63k| __func__, print_map(del.del_protoid, ikev2_saproto_map), - 1425| 5.63k| sz, cnt); + 1423| 5.64k| log_debug("%s: proto %s spisize %zu nspi %zu", + 1424| 5.64k| __func__, print_map(del.del_protoid, ikev2_saproto_map), + 1425| 5.64k| sz, cnt); 1426| | - 1427| 5.63k| if (msg->msg_parent->msg_del_protoid) { + 1427| 5.64k| if (msg->msg_parent->msg_del_protoid) { ------------------ - | Branch (1427:6): [True: 5.32k, False: 315] + | Branch (1427:6): [True: 5.32k, False: 316] ------------------ 1428| 5.32k| log_debug("%s: duplicate delete payload", __func__); 1429| 5.32k| return (0); 1430| 5.32k| } 1431| | - 1432| 315| msg->msg_parent->msg_del_protoid = del.del_protoid; - 1433| 315| msg->msg_parent->msg_del_cnt = cnt; - 1434| 315| msg->msg_parent->msg_del_spisize = sz; + 1432| 316| msg->msg_parent->msg_del_protoid = del.del_protoid; + 1433| 316| msg->msg_parent->msg_del_cnt = cnt; + 1434| 316| msg->msg_parent->msg_del_spisize = sz; 1435| | - 1436| 315| buf = msgbuf + offset + sizeof(del); - 1437| 315| len = left - sizeof(del); - 1438| 315| if (len == 0 || sz == 0 || cnt == 0) + 1436| 316| buf = msgbuf + offset + sizeof(del); + 1437| 316| len = left - sizeof(del); + 1438| 316| if (len == 0 || sz == 0 || cnt == 0) ------------------ - | Branch (1438:6): [True: 13, False: 302] - | Branch (1438:18): [True: 228, False: 74] + | Branch (1438:6): [True: 13, False: 303] + | Branch (1438:18): [True: 229, False: 74] | Branch (1438:29): [True: 51, False: 23] ------------------ - 1439| 292| return (0); + 1439| 293| return (0); 1440| | 1441| 23| if ((len / sz) != cnt) { ------------------ @@ -2300,126 +2300,126 @@ ikev2_pld_delete: 1451| 2| return (0); 1452| 23|} ikev2_validate_tss: - 1457| 18.0k|{ - 1458| 18.0k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1457| 18.1k|{ + 1458| 18.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1459| | - 1460| 18.0k| if (left < sizeof(*tsp)) { + 1460| 18.1k| if (left < sizeof(*tsp)) { ------------------ - | Branch (1460:6): [True: 2.39k, False: 15.6k] + | Branch (1460:6): [True: 2.39k, False: 15.7k] ------------------ 1461| 2.39k| log_debug("%s: malformed payload: too short for header " 1462| 2.39k| "(%zu < %zu)", __func__, left, sizeof(*tsp)); 1463| 2.39k| return (-1); 1464| 2.39k| } - 1465| 15.6k| memcpy(tsp, msgbuf + offset, sizeof(*tsp)); + 1465| 15.7k| memcpy(tsp, msgbuf + offset, sizeof(*tsp)); 1466| | - 1467| 15.6k| return (0); - 1468| 18.0k|} + 1467| 15.7k| return (0); + 1468| 18.1k|} ikev2_pld_tss: - 1473| 18.0k|{ - 1474| 18.0k| struct ikev2_tsp tsp; - 1475| 18.0k| struct ikev2_ts ts; - 1476| 18.0k| size_t ts_len, i; + 1473| 18.1k|{ + 1474| 18.1k| struct ikev2_tsp tsp; + 1475| 18.1k| struct ikev2_ts ts; + 1476| 18.1k| size_t ts_len, i; 1477| | - 1478| 18.0k| if (ikev2_validate_tss(msg, offset, left, &tsp)) + 1478| 18.1k| if (ikev2_validate_tss(msg, offset, left, &tsp)) ------------------ - | Branch (1478:6): [True: 2.39k, False: 15.6k] + | Branch (1478:6): [True: 2.39k, False: 15.7k] ------------------ 1479| 2.39k| return (-1); 1480| | - 1481| 15.6k| offset += sizeof(tsp); - 1482| 15.6k| left -= sizeof(tsp); + 1481| 15.7k| offset += sizeof(tsp); + 1482| 15.7k| left -= sizeof(tsp); 1483| | - 1484| 15.6k| log_debug("%s: count %d length %zu", __func__, - 1485| 15.6k| tsp.tsp_count, left); + 1484| 15.7k| log_debug("%s: count %d length %zu", __func__, + 1485| 15.7k| tsp.tsp_count, left); 1486| | - 1487| 30.8k| for (i = 0; i < tsp.tsp_count; i++) { + 1487| 31.1k| for (i = 0; i < tsp.tsp_count; i++) { ------------------ - | Branch (1487:14): [True: 29.2k, False: 1.59k] + | Branch (1487:14): [True: 29.5k, False: 1.59k] ------------------ - 1488| 29.2k| if (ikev2_validate_ts(msg, offset, left, &ts)) + 1488| 29.5k| if (ikev2_validate_ts(msg, offset, left, &ts)) ------------------ - | Branch (1488:7): [True: 12.3k, False: 16.8k] + | Branch (1488:7): [True: 12.4k, False: 17.1k] ------------------ - 1489| 12.3k| return (-1); + 1489| 12.4k| return (-1); 1490| | - 1491| 16.8k| log_debug("%s: type %s protoid %u length %d " - 1492| 16.8k| "startport %u endport %u", __func__, - 1493| 16.8k| print_map(ts.ts_type, ikev2_ts_map), - 1494| 16.8k| ts.ts_protoid, betoh16(ts.ts_length), - 1495| 16.8k| betoh16(ts.ts_startport), - 1496| 16.8k| betoh16(ts.ts_endport)); + 1491| 17.1k| log_debug("%s: type %s protoid %u length %d " + 1492| 17.1k| "startport %u endport %u", __func__, + 1493| 17.1k| print_map(ts.ts_type, ikev2_ts_map), + 1494| 17.1k| ts.ts_protoid, betoh16(ts.ts_length), + 1495| 17.1k| betoh16(ts.ts_startport), + 1496| 17.1k| betoh16(ts.ts_endport)); 1497| | - 1498| 16.8k| offset += sizeof(ts); - 1499| 16.8k| left -= sizeof(ts); + 1498| 17.1k| offset += sizeof(ts); + 1499| 17.1k| left -= sizeof(ts); 1500| | - 1501| 16.8k| ts_len = betoh16(ts.ts_length) - sizeof(ts); - 1502| 16.8k| if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type)) + 1501| 17.1k| ts_len = betoh16(ts.ts_length) - sizeof(ts); + 1502| 17.1k| if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type)) ------------------ - | Branch (1502:7): [True: 1.68k, False: 15.1k] + | Branch (1502:7): [True: 1.69k, False: 15.4k] ------------------ - 1503| 1.68k| return (-1); + 1503| 1.69k| return (-1); 1504| | - 1505| 15.1k| offset += ts_len; - 1506| 15.1k| left -= ts_len; - 1507| 15.1k| } + 1505| 15.4k| offset += ts_len; + 1506| 15.4k| left -= ts_len; + 1507| 15.4k| } 1508| | 1509| 1.59k| return (0); - 1510| 15.6k|} + 1510| 15.7k|} ikev2_validate_ts: - 1515| 29.2k|{ - 1516| 29.2k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 1517| 29.2k| size_t ts_length; + 1515| 29.5k|{ + 1516| 29.5k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1517| 29.5k| size_t ts_length; 1518| | - 1519| 29.2k| if (left < sizeof(*ts)) { + 1519| 29.5k| if (left < sizeof(*ts)) { ------------------ - | Branch (1519:6): [True: 11.2k, False: 18.0k] + | Branch (1519:6): [True: 11.2k, False: 18.3k] ------------------ 1520| 11.2k| log_debug("%s: malformed payload: too short for header " 1521| 11.2k| "(%zu < %zu)", __func__, left, sizeof(*ts)); 1522| 11.2k| return (-1); 1523| 11.2k| } - 1524| 18.0k| memcpy(ts, msgbuf + offset, sizeof(*ts)); + 1524| 18.3k| memcpy(ts, msgbuf + offset, sizeof(*ts)); 1525| | - 1526| 18.0k| ts_length = betoh16(ts->ts_length); - 1527| 18.0k| if (ts_length < sizeof(*ts)) { + 1526| 18.3k| ts_length = betoh16(ts->ts_length); + 1527| 18.3k| if (ts_length < sizeof(*ts)) { ------------------ - | Branch (1527:6): [True: 312, False: 17.7k] + | Branch (1527:6): [True: 315, False: 18.0k] ------------------ - 1528| 312| log_debug("%s: malformed payload: shorter than minimum header " - 1529| 312| "size (%zu < %zu)", __func__, ts_length, sizeof(*ts)); - 1530| 312| return (-1); - 1531| 312| } - 1532| 17.7k| if (left < ts_length) { + 1528| 315| log_debug("%s: malformed payload: shorter than minimum header " + 1529| 315| "size (%zu < %zu)", __func__, ts_length, sizeof(*ts)); + 1530| 315| return (-1); + 1531| 315| } + 1532| 18.0k| if (left < ts_length) { ------------------ - | Branch (1532:6): [True: 864, False: 16.8k] + | Branch (1532:6): [True: 873, False: 17.1k] ------------------ - 1533| 864| log_debug("%s: malformed payload: too long for payload size " - 1534| 864| "(%zu < %zu)", __func__, left, ts_length); - 1535| 864| return (-1); - 1536| 864| } + 1533| 873| log_debug("%s: malformed payload: too long for payload size " + 1534| 873| "(%zu < %zu)", __func__, left, ts_length); + 1535| 873| return (-1); + 1536| 873| } 1537| | - 1538| 16.8k| return (0); - 1539| 17.7k|} + 1538| 17.1k| return (0); + 1539| 18.0k|} ikev2_pld_ts: - 1544| 16.8k|{ - 1545| 16.8k| struct sockaddr_in start4, end4; - 1546| 16.8k| struct sockaddr_in6 start6, end6; - 1547| 16.8k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 1548| 16.8k| uint8_t *ptr; + 1544| 17.1k|{ + 1545| 17.1k| struct sockaddr_in start4, end4; + 1546| 17.1k| struct sockaddr_in6 start6, end6; + 1547| 17.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1548| 17.1k| uint8_t *ptr; 1549| | - 1550| 16.8k| ptr = msgbuf + offset; + 1550| 17.1k| ptr = msgbuf + offset; 1551| | - 1552| 16.8k| switch (type) { - 1553| 6.12k| case IKEV2_TS_IPV4_ADDR_RANGE: + 1552| 17.1k| switch (type) { + 1553| 6.22k| case IKEV2_TS_IPV4_ADDR_RANGE: ------------------ - | | 460| 6.12k|#define IKEV2_TS_IPV4_ADDR_RANGE 7 /* RFC7296 */ + | | 460| 6.22k|#define IKEV2_TS_IPV4_ADDR_RANGE 7 /* RFC7296 */ ------------------ - | Branch (1553:2): [True: 6.12k, False: 10.7k] + | Branch (1553:2): [True: 6.22k, False: 10.9k] ------------------ - 1554| 6.12k| if (left < 2 * 4) { + 1554| 6.22k| if (left < 2 * 4) { ------------------ - | Branch (1554:7): [True: 323, False: 5.80k] + | Branch (1554:7): [True: 323, False: 5.90k] ------------------ 1555| 323| log_debug("%s: malformed payload: too short " 1556| 323| "for ipv4 addr range (%zu < %u)", @@ -2427,80 +2427,80 @@ ikev2_pld_ts: 1558| 323| return (-1); 1559| 323| } 1560| | - 1561| 5.80k| bzero(&start4, sizeof(start4)); - 1562| 5.80k| start4.sin_family = AF_INET; + 1561| 5.90k| bzero(&start4, sizeof(start4)); + 1562| 5.90k| start4.sin_family = AF_INET; 1563| |#ifdef HAVE_SOCKADDR_SA_LEN 1564| | start4.sin_len = sizeof(start4); 1565| |#endif - 1566| 5.80k| memcpy(&start4.sin_addr.s_addr, ptr, 4); - 1567| 5.80k| ptr += 4; - 1568| 5.80k| left -= 4; + 1566| 5.90k| memcpy(&start4.sin_addr.s_addr, ptr, 4); + 1567| 5.90k| ptr += 4; + 1568| 5.90k| left -= 4; 1569| | - 1570| 5.80k| bzero(&end4, sizeof(end4)); - 1571| 5.80k| end4.sin_family = AF_INET; + 1570| 5.90k| bzero(&end4, sizeof(end4)); + 1571| 5.90k| end4.sin_family = AF_INET; 1572| |#ifdef HAVE_SOCKADDR_SA_LEN 1573| | end4.sin_len = sizeof(end4); 1574| |#endif - 1575| 5.80k| memcpy(&end4.sin_addr.s_addr, ptr, 4); - 1576| 5.80k| left -= 4; + 1575| 5.90k| memcpy(&end4.sin_addr.s_addr, ptr, 4); + 1576| 5.90k| left -= 4; 1577| | - 1578| 5.80k| log_debug("%s: start %s end %s", __func__, - 1579| 5.80k| print_addr(&start4), print_addr(&end4)); - 1580| 5.80k| break; - 1581| 1.35k| case IKEV2_TS_IPV6_ADDR_RANGE: + 1578| 5.90k| log_debug("%s: start %s end %s", __func__, + 1579| 5.90k| print_addr(&start4), print_addr(&end4)); + 1580| 5.90k| break; + 1581| 1.36k| case IKEV2_TS_IPV6_ADDR_RANGE: ------------------ - | | 461| 1.35k|#define IKEV2_TS_IPV6_ADDR_RANGE 8 /* RFC7296 */ + | | 461| 1.36k|#define IKEV2_TS_IPV6_ADDR_RANGE 8 /* RFC7296 */ ------------------ - | Branch (1581:2): [True: 1.35k, False: 15.5k] + | Branch (1581:2): [True: 1.36k, False: 15.7k] ------------------ - 1582| 1.35k| if (left < 2 * 16) { + 1582| 1.36k| if (left < 2 * 16) { ------------------ - | Branch (1582:7): [True: 252, False: 1.09k] + | Branch (1582:7): [True: 252, False: 1.11k] ------------------ 1583| 252| log_debug("%s: malformed payload: too short " 1584| 252| "for ipv6 addr range (%zu < %u)", 1585| 252| __func__, left, 2 * 16); 1586| 252| return (-1); 1587| 252| } - 1588| 1.09k| bzero(&start6, sizeof(start6)); - 1589| 1.09k| start6.sin6_family = AF_INET6; + 1588| 1.11k| bzero(&start6, sizeof(start6)); + 1589| 1.11k| start6.sin6_family = AF_INET6; 1590| |#ifdef HAVE_SOCKADDR_SA_LEN 1591| | start6.sin6_len = sizeof(start6); 1592| |#endif - 1593| 1.09k| memcpy(&start6.sin6_addr, ptr, 16); - 1594| 1.09k| ptr += 16; - 1595| 1.09k| left -= 16; + 1593| 1.11k| memcpy(&start6.sin6_addr, ptr, 16); + 1594| 1.11k| ptr += 16; + 1595| 1.11k| left -= 16; 1596| | - 1597| 1.09k| bzero(&end6, sizeof(end6)); - 1598| 1.09k| end6.sin6_family = AF_INET6; + 1597| 1.11k| bzero(&end6, sizeof(end6)); + 1598| 1.11k| end6.sin6_family = AF_INET6; 1599| |#ifdef HAVE_SOCKADDR_SA_LEN 1600| | end6.sin6_len = sizeof(end6); 1601| |#endif - 1602| 1.09k| memcpy(&end6.sin6_addr, ptr, 16); - 1603| 1.09k| left -= 16; + 1602| 1.11k| memcpy(&end6.sin6_addr, ptr, 16); + 1603| 1.11k| left -= 16; 1604| | - 1605| 1.09k| log_debug("%s: start %s end %s", __func__, - 1606| 1.09k| print_addr(&start6), print_addr(&end6)); - 1607| 1.09k| break; - 1608| 9.40k| default: + 1605| 1.11k| log_debug("%s: start %s end %s", __func__, + 1606| 1.11k| print_addr(&start6), print_addr(&end6)); + 1607| 1.11k| break; + 1608| 9.54k| default: ------------------ - | Branch (1608:2): [True: 9.40k, False: 7.47k] + | Branch (1608:2): [True: 9.54k, False: 7.59k] ------------------ - 1609| 9.40k| log_debug("%s: ignoring unknown TS type %u", __func__, type); - 1610| 9.40k| return (0); - 1611| 16.8k| } + 1609| 9.54k| log_debug("%s: ignoring unknown TS type %u", __func__, type); + 1610| 9.54k| return (0); + 1611| 17.1k| } 1612| | - 1613| 6.90k| if (left > 0) { + 1613| 7.01k| if (left > 0) { ------------------ - | Branch (1613:6): [True: 1.10k, False: 5.79k] + | Branch (1613:6): [True: 1.12k, False: 5.89k] ------------------ - 1614| 1.10k| log_debug("%s: malformed payload: left (%zu) > 0", - 1615| 1.10k| __func__, left); - 1616| 1.10k| return (-1); - 1617| 1.10k| } + 1614| 1.12k| log_debug("%s: malformed payload: left (%zu) > 0", + 1615| 1.12k| __func__, left); + 1616| 1.12k| return (-1); + 1617| 1.12k| } 1618| | - 1619| 5.79k| return (0); - 1620| 6.90k|} + 1619| 5.89k| return (0); + 1620| 7.01k|} ikev2_validate_cp: 1875| 9.77k|{ 1876| 9.77k| uint8_t *msgbuf = ibuf_data(msg->msg_data); @@ -2566,7 +2566,7 @@ ikev2_pld_cp: 1927| | 1928| 8.98k| if (len < betoh16(cfg->cfg_length)) { ------------------ - | Branch (1928:7): [True: 1.12k, False: 7.85k] + | Branch (1928:7): [True: 1.12k, False: 7.86k] ------------------ 1929| 1.12k| log_debug("%s: malformed payload: too short for " 1930| 1.12k| "cfg_length (%zu < %u)", __func__, len, @@ -2574,10 +2574,10 @@ ikev2_pld_cp: 1932| 1.12k| return (-1); 1933| 1.12k| } 1934| | - 1935| 7.85k| print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length)); + 1935| 7.86k| print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length)); 1936| | - 1937| 7.85k| cfg_type = betoh16(cfg->cfg_type); - 1938| 7.85k| switch (cfg_type) { + 1937| 7.86k| cfg_type = betoh16(cfg->cfg_type); + 1938| 7.86k| switch (cfg_type) { ------------------ | Branch (1938:11): [True: 3.29k, False: 4.56k] ------------------ @@ -2591,7 +2591,7 @@ ikev2_pld_cp: ------------------ | | 530| 1.50k|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ ------------------ - | Branch (1940:3): [True: 660, False: 7.19k] + | Branch (1940:3): [True: 660, False: 7.20k] ------------------ 1941| 1.50k| if (!ikev2_msg_frompeer(msg)) ------------------ @@ -2696,34 +2696,34 @@ ikev2_pld_cp: ------------------ | | 535| 2.25k|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ ------------------ - | Branch (1996:3): [True: 2.25k, False: 5.60k] + | Branch (1996:3): [True: 2.25k, False: 5.61k] ------------------ - 1997| 3.05k| case IKEV2_CFG_INTERNAL_IP6_DNS: + 1997| 3.06k| case IKEV2_CFG_INTERNAL_IP6_DNS: ------------------ - | | 536| 3.05k|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ + | | 536| 3.06k|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ ------------------ - | Branch (1997:3): [True: 809, False: 7.05k] + | Branch (1997:3): [True: 810, False: 7.05k] ------------------ - 1998| 3.05k| if (!ikev2_msg_frompeer(msg)) + 1998| 3.06k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (1998:8): [True: 2.86k, False: 198] + | Branch (1998:8): [True: 2.86k, False: 199] ------------------ 1999| 2.86k| break; - 2000| 198| if (betoh16(cfg->cfg_length) == 0) + 2000| 199| if (betoh16(cfg->cfg_length) == 0) ------------------ - | Branch (2000:8): [True: 67, False: 131] + | Branch (2000:8): [True: 67, False: 132] ------------------ 2001| 67| break; 2002| | /* XXX multiple-valued */ - 2003| 131| if (betoh16(cfg->cfg_length) < 16) { + 2003| 132| if (betoh16(cfg->cfg_length) < 16) { ------------------ - | Branch (2003:8): [True: 4, False: 127] + | Branch (2003:8): [True: 5, False: 127] ------------------ - 2004| 4| log_debug("%s: malformed payload: too short " - 2005| 4| "for ipv6 addr w/prefixlen (%u < %u)", - 2006| 4| __func__, betoh16(cfg->cfg_length), 16); - 2007| 4| return (-1); - 2008| 4| } + 2004| 5| log_debug("%s: malformed payload: too short " + 2005| 5| "for ipv6 addr w/prefixlen (%u < %u)", + 2006| 5| __func__, betoh16(cfg->cfg_length), 16); + 2007| 5| return (-1); + 2008| 5| } 2009| 127| switch(cfg_type) { ------------------ | Branch (2009:11): [True: 0, False: 127] @@ -2801,7 +2801,7 @@ ikev2_pld_cp: 2048| 0| break; 2049| 44| } 2050| 44| break; - 2051| 7.85k| } + 2051| 7.86k| } 2052| | 2053| 7.84k| skip: 2054| 7.84k| ptr += betoh16(cfg->cfg_length); @@ -2819,10 +2819,10 @@ ikev2_pld_cp: 2063| 192| return (0); 2064| 5.15k|} ikev2_validate_eap: - 2069| 17.0k|{ - 2070| 17.0k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 2069| 17.1k|{ + 2070| 17.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 2071| | - 2072| 17.0k| if (left < sizeof(*hdr)) { + 2072| 17.1k| if (left < sizeof(*hdr)) { ------------------ | Branch (2072:6): [True: 7.15k, False: 9.94k] ------------------ @@ -2833,15 +2833,15 @@ ikev2_validate_eap: 2077| 9.94k| memcpy(hdr, msgbuf + offset, sizeof(*hdr)); 2078| | 2079| 9.94k| return (0); - 2080| 17.0k|} + 2080| 17.1k|} ikev2_pld_eap: - 2085| 17.0k|{ - 2086| 17.0k| struct eap_header hdr; - 2087| 17.0k| struct eap_message *eap = NULL; - 2088| 17.0k| const struct iked_sa *sa = msg->msg_sa; - 2089| 17.0k| size_t len; + 2085| 17.1k|{ + 2086| 17.1k| struct eap_header hdr; + 2087| 17.1k| struct eap_message *eap = NULL; + 2088| 17.1k| const struct iked_sa *sa = msg->msg_sa; + 2089| 17.1k| size_t len; 2090| | - 2091| 17.0k| if (ikev2_validate_eap(msg, offset, left, &hdr)) + 2091| 17.1k| if (ikev2_validate_eap(msg, offset, left, &hdr)) ------------------ | Branch (2091:6): [True: 7.15k, False: 9.94k] ------------------ @@ -2890,32 +2890,32 @@ ikev2_pld_eap: 2113| 3.20k| msg->msg_parent->msg_eap.eam_found = 1; 2114| 3.20k| } 2115| | - 2116| 6.65k| return (0); + 2116| 6.66k| return (0); 2117| 9.94k|} ibuf_new: - 41| 20.3k|{ - 42| 20.3k| struct ibuf *buf; + 41| 20.4k|{ + 42| 20.4k| struct ibuf *buf; 43| | - 44| 20.3k| if ((buf = ibuf_dynamic(len, + 44| 20.4k| if ((buf = ibuf_dynamic(len, ------------------ - | Branch (44:6): [True: 0, False: 20.3k] + | Branch (44:6): [True: 0, False: 20.4k] ------------------ - 45| 20.3k| IKED_MSGBUF_MAX)) == NULL) + 45| 20.4k| IKED_MSGBUF_MAX)) == NULL) ------------------ - | | 66| 20.3k|#define IKED_MSGBUF_MAX 8192 + | | 66| 20.4k|#define IKED_MSGBUF_MAX 8192 ------------------ 46| 0| return (NULL); 47| | - 48| 20.3k| if (len == 0) + 48| 20.4k| if (len == 0) ------------------ - | Branch (48:6): [True: 1.41k, False: 18.9k] + | Branch (48:6): [True: 1.41k, False: 19.0k] ------------------ 49| 1.41k| return (buf); 50| | - 51| 18.9k| if (data == NULL) { + 51| 19.0k| if (data == NULL) { ------------------ - | Branch (51:6): [True: 0, False: 18.9k] + | Branch (51:6): [True: 0, False: 19.0k] ------------------ 52| 0| if (ibuf_add_zero(buf, len) != 0) { ------------------ @@ -2924,23 +2924,23 @@ ibuf_new: 53| 0| ibuf_free(buf); 54| 0| return (NULL); 55| 0| } - 56| 18.9k| } else { - 57| 18.9k| if (ibuf_add(buf, data, len) != 0) { + 56| 19.0k| } else { + 57| 19.0k| if (ibuf_add(buf, data, len) != 0) { ------------------ - | Branch (57:7): [True: 0, False: 18.9k] + | Branch (57:7): [True: 0, False: 19.0k] ------------------ 58| 0| ibuf_free(buf); 59| 0| return (NULL); 60| 0| } - 61| 18.9k| } + 61| 19.0k| } 62| | - 63| 18.9k| return (buf); - 64| 18.9k|} + 63| 19.0k| return (buf); + 64| 19.0k|} log_getverbose: - 82| 147k|{ - 83| 147k| return (verbose); - 84| 147k|} + 82| 148k|{ + 83| 148k| return (verbose); + 84| 148k|} vlog: 98| 10.4k|{ 99| 10.4k| char *nfmt; @@ -2976,134 +2976,134 @@ log_info: 163| 10.4k| va_end(ap); 164| 10.4k|} log_debug: - 168| 540k|{ - 169| 540k| va_list ap; + 168| 543k|{ + 169| 543k| va_list ap; 170| | - 171| 540k| if (verbose > 1) { + 171| 543k| if (verbose > 1) { ------------------ - | Branch (171:6): [True: 0, False: 540k] + | Branch (171:6): [True: 0, False: 543k] ------------------ 172| 0| va_start(ap, emsg); 173| 0| vlog(LOG_DEBUG, emsg, ap); 174| 0| va_end(ap); 175| 0| } - 176| 540k|} + 176| 543k|} socket_getport: - 71| 14.0k|{ - 72| 14.0k| switch (sa->sa_family) { - 73| 11.7k| case AF_INET: + 71| 14.2k|{ + 72| 14.2k| switch (sa->sa_family) { + 73| 11.9k| case AF_INET: ------------------ - | Branch (73:2): [True: 11.7k, False: 2.24k] + | Branch (73:2): [True: 11.9k, False: 2.27k] ------------------ - 74| 11.7k| return (ntohs(((struct sockaddr_in *)sa)->sin_port)); - 75| 2.24k| case AF_INET6: + 74| 11.9k| return (ntohs(((struct sockaddr_in *)sa)->sin_port)); + 75| 2.27k| case AF_INET6: ------------------ - | Branch (75:2): [True: 2.24k, False: 11.7k] + | Branch (75:2): [True: 2.27k, False: 11.9k] ------------------ - 76| 2.24k| return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); + 76| 2.27k| return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); 77| 0| default: ------------------ - | Branch (77:2): [True: 0, False: 14.0k] + | Branch (77:2): [True: 0, False: 14.2k] ------------------ 78| 0| return (0); - 79| 14.0k| } + 79| 14.2k| } 80| | 81| | /* NOTREACHED */ 82| 0| return (0); - 83| 14.0k|} + 83| 14.2k|} print_spi: - 499| 35.7k|{ - 500| 35.7k| static char buf[IKED_CYCLE_BUFFERS][32]; - 501| 35.7k| static int i = 0; - 502| 35.7k| char *ptr; + 499| 36.0k|{ + 500| 36.0k| static char buf[IKED_CYCLE_BUFFERS][32]; + 501| 36.0k| static int i = 0; + 502| 36.0k| char *ptr; 503| | - 504| 35.7k| ptr = buf[i]; + 504| 36.0k| ptr = buf[i]; 505| | - 506| 35.7k| switch (size) { + 506| 36.0k| switch (size) { 507| 0| case 2: ------------------ - | Branch (507:2): [True: 0, False: 35.7k] + | Branch (507:2): [True: 0, False: 36.0k] ------------------ 508| 0| snprintf(ptr, 32, "0x%04x", (uint16_t)spi); 509| 0| break; 510| 349| case 4: ------------------ - | Branch (510:2): [True: 349, False: 35.3k] + | Branch (510:2): [True: 349, False: 35.6k] ------------------ 511| 349| snprintf(ptr, 32, "0x%08x", (uint32_t)spi); 512| 349| break; - 513| 26.2k| case 8: + 513| 26.5k| case 8: ------------------ - | Branch (513:2): [True: 26.2k, False: 9.45k] + | Branch (513:2): [True: 26.5k, False: 9.46k] ------------------ - 514| 26.2k| snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi); - 515| 26.2k| break; - 516| 9.10k| default: + 514| 26.5k| snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi); + 515| 26.5k| break; + 516| 9.11k| default: ------------------ - | Branch (516:2): [True: 9.10k, False: 26.6k] + | Branch (516:2): [True: 9.11k, False: 26.9k] ------------------ - 517| 9.10k| snprintf(ptr, 32, "%llu", (long long unsigned)spi); - 518| 9.10k| break; - 519| 35.7k| } + 517| 9.11k| snprintf(ptr, 32, "%llu", (long long unsigned)spi); + 518| 9.11k| break; + 519| 36.0k| } 520| | - 521| 35.7k| if (++i >= IKED_CYCLE_BUFFERS) + 521| 36.0k| if (++i >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 35.7k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 36.0k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (521:6): [True: 4.46k, False: 31.2k] + | Branch (521:6): [True: 4.50k, False: 31.5k] ------------------ - 522| 4.46k| i = 0; + 522| 4.50k| i = 0; 523| | - 524| 35.7k| return (ptr); - 525| 35.7k|} + 524| 36.0k| return (ptr); + 525| 36.0k|} print_map: - 529| 669k|{ - 530| 669k| unsigned int i; - 531| 669k| static char buf[IKED_CYCLE_BUFFERS][32]; - 532| 669k| static int idx = 0; - 533| 669k| const char *name = NULL; + 529| 672k|{ + 530| 672k| unsigned int i; + 531| 672k| static char buf[IKED_CYCLE_BUFFERS][32]; + 532| 672k| static int idx = 0; + 533| 672k| const char *name = NULL; 534| | - 535| 669k| if (idx >= IKED_CYCLE_BUFFERS) + 535| 672k| if (idx >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 669k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 672k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (535:6): [True: 83.6k, False: 585k] + | Branch (535:6): [True: 84.0k, False: 588k] ------------------ - 536| 83.6k| idx = 0; - 537| 669k| bzero(buf[idx], sizeof(buf[idx])); + 536| 84.0k| idx = 0; + 537| 672k| bzero(buf[idx], sizeof(buf[idx])); 538| | - 539| 14.1M| for (i = 0; map[i].cm_name != NULL; i++) { + 539| 14.2M| for (i = 0; map[i].cm_name != NULL; i++) { ------------------ - | Branch (539:14): [True: 13.4M, False: 669k] + | Branch (539:14): [True: 13.5M, False: 672k] ------------------ - 540| 13.4M| if (map[i].cm_type == type) + 540| 13.5M| if (map[i].cm_type == type) ------------------ - | Branch (540:7): [True: 465k, False: 12.9M] + | Branch (540:7): [True: 467k, False: 13.0M] ------------------ - 541| 465k| name = map[i].cm_name; - 542| 13.4M| } + 541| 467k| name = map[i].cm_name; + 542| 13.5M| } 543| | - 544| 669k| if (name == NULL) + 544| 672k| if (name == NULL) ------------------ - | Branch (544:6): [True: 203k, False: 465k] + | Branch (544:6): [True: 205k, False: 467k] ------------------ - 545| 203k| snprintf(buf[idx], sizeof(buf[idx]), "", type); - 546| 465k| else - 547| 465k| strlcpy(buf[idx], name, sizeof(buf[idx])); + 545| 205k| snprintf(buf[idx], sizeof(buf[idx]), "", type); + 546| 467k| else + 547| 467k| strlcpy(buf[idx], name, sizeof(buf[idx])); 548| | - 549| 669k| return (buf[idx++]); - 550| 669k|} + 549| 672k| return (buf[idx++]); + 550| 672k|} print_hex: - 561| 147k|{ - 562| 147k| unsigned int i; + 561| 148k|{ + 562| 148k| unsigned int i; 563| | - 564| 147k| if (log_getverbose() < 3 || !length) + 564| 148k| if (log_getverbose() < 3 || !length) ------------------ - | Branch (564:6): [True: 147k, False: 0] + | Branch (564:6): [True: 148k, False: 0] | Branch (564:30): [True: 0, False: 0] ------------------ - 565| 147k| return; + 565| 148k| return; 566| | 567| 0| for (i = 0; i < length; i++) { ------------------ @@ -3127,95 +3127,95 @@ print_hex: 576| 0| print_debug("\n"); 577| 0|} print_addr: - 737| 14.0k|{ - 738| 14.0k| static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7]; - 739| 14.0k| static int idx; - 740| 14.0k| struct sockaddr *sa = addr; - 741| 14.0k| char *buf; - 742| 14.0k| size_t len; - 743| 14.0k| char pbuf[7]; - 744| 14.0k| in_port_t port; + 737| 14.2k|{ + 738| 14.2k| static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7]; + 739| 14.2k| static int idx; + 740| 14.2k| struct sockaddr *sa = addr; + 741| 14.2k| char *buf; + 742| 14.2k| size_t len; + 743| 14.2k| char pbuf[7]; + 744| 14.2k| in_port_t port; 745| | - 746| 14.0k| buf = sbuf[idx]; - 747| 14.0k| len = sizeof(sbuf[idx]); - 748| 14.0k| if (++idx >= IKED_CYCLE_BUFFERS) + 746| 14.2k| buf = sbuf[idx]; + 747| 14.2k| len = sizeof(sbuf[idx]); + 748| 14.2k| if (++idx >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 14.0k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 14.2k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (748:6): [True: 1.75k, False: 12.2k] + | Branch (748:6): [True: 1.78k, False: 12.4k] ------------------ - 749| 1.75k| idx = 0; + 749| 1.78k| idx = 0; 750| | - 751| 14.0k| if (sa->sa_family == AF_UNSPEC) { + 751| 14.2k| if (sa->sa_family == AF_UNSPEC) { ------------------ - | Branch (751:6): [True: 0, False: 14.0k] + | Branch (751:6): [True: 0, False: 14.2k] ------------------ 752| 0| strlcpy(buf, "any", len); 753| 0| return (buf); 754| 0| } 755| | - 756| 14.0k| if (getnameinfo(sa, SA_LEN(sa), + 756| 14.2k| if (getnameinfo(sa, SA_LEN(sa), ------------------ - | | 113| 14.0k| ((sa->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \ + | | 113| 14.2k| ((sa->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \ | | ------------------ - | | | Branch (113:3): [True: 11.7k, False: 2.24k] + | | | Branch (113:3): [True: 11.9k, False: 2.27k] | | ------------------ - | | 114| 14.0k| (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : \ + | | 114| 14.2k| (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : \ | | ------------------ - | | | Branch (114:2): [True: 2.24k, False: 0] + | | | Branch (114:2): [True: 2.27k, False: 0] | | ------------------ - | | 115| 2.24k| sizeof(struct sockaddr)) + | | 115| 2.27k| sizeof(struct sockaddr)) ------------------ - | Branch (756:6): [True: 0, False: 14.0k] + | Branch (756:6): [True: 0, False: 14.2k] ------------------ - 757| 14.0k| buf, len, NULL, 0, NI_NUMERICHOST) != 0) { + 757| 14.2k| buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 758| 0| strlcpy(buf, "unknown", len); 759| 0| return (buf); 760| 0| } 761| | - 762| 14.0k| if ((port = socket_getport(sa)) != 0) { + 762| 14.2k| if ((port = socket_getport(sa)) != 0) { ------------------ - | Branch (762:6): [True: 0, False: 14.0k] + | Branch (762:6): [True: 0, False: 14.2k] ------------------ 763| 0| snprintf(pbuf, sizeof(pbuf), ":%d", port); 764| 0| (void)strlcat(buf, pbuf, len); 765| 0| } 766| | - 767| 14.0k| return (buf); - 768| 14.0k|} + 767| 14.2k| return (buf); + 768| 14.2k|} eap_parse: 60| 3.20k|{ 61| 3.20k| return (0); 62| 3.20k|} ikev2_msg_frompeer: - 67| 197k|{ - 68| 197k| struct iked_sa *sa = msg->msg_sa; - 69| 197k| struct ike_header *hdr; + 67| 198k|{ + 68| 198k| struct iked_sa *sa = msg->msg_sa; + 69| 198k| struct ike_header *hdr; 70| | - 71| 197k| msg = msg->msg_parent; + 71| 198k| msg = msg->msg_parent; 72| | - 73| 197k| if (sa == NULL || + 73| 198k| if (sa == NULL || ------------------ - | Branch (73:6): [True: 0, False: 197k] + | Branch (73:6): [True: 0, False: 198k] ------------------ - 74| 197k| (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL) + 74| 198k| (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL) ------------------ - | Branch (74:6): [True: 0, False: 197k] + | Branch (74:6): [True: 0, False: 198k] ------------------ 75| 0| return (0); 76| | - 77| 197k| if (!sa->sa_hdr.sh_initiator && + 77| 198k| if (!sa->sa_hdr.sh_initiator && ------------------ - | Branch (77:6): [True: 197k, False: 0] + | Branch (77:6): [True: 198k, False: 0] ------------------ - 78| 197k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR)) + 78| 198k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR)) ------------------ - | | 19| 197k|#define IKEV2_FLAG_INITIATOR 0x08 /* Sent by the initiator */ + | | 19| 198k|#define IKEV2_FLAG_INITIATOR 0x08 /* Sent by the initiator */ ------------------ - | Branch (78:6): [True: 55.2k, False: 142k] + | Branch (78:6): [True: 55.9k, False: 142k] ------------------ - 79| 55.2k| return (1); + 79| 55.9k| return (1); 80| 142k| else if (sa->sa_hdr.sh_initiator && ------------------ | Branch (80:11): [True: 0, False: 142k] @@ -3229,7 +3229,7 @@ ikev2_msg_frompeer: 82| 0| return (1); 83| | 84| 142k| return (0); - 85| 197k|} + 85| 198k|} ikev2_ikesa_info: 101| 7.69k|{ 102| 7.69k| return ""; @@ -3239,9 +3239,9 @@ sa_stateok: 121| 141| return (0); 122| 141|} ikev2_nat_detection: - 164| 22.6k|{ - 165| 22.6k| return (0); - 166| 22.6k|} + 164| 22.9k|{ + 165| 22.9k| return (0); + 166| 22.9k|} ikev2_print_id: 178| 5.38k|{ 179| 5.38k| return (0); @@ -3251,61 +3251,61 @@ config_add_proposal: 192| 69| return (NULL); 193| 69|} ikev2_send_informational: - 208| 722|{ - 209| 722| return (0); - 210| 722|} + 208| 723|{ + 209| 723| return (0); + 210| 723|} ikev2_msg_cleanup: - 250| 13.0k|{ - 251| 13.0k| struct iked_certreq *cr; - 252| 13.0k| struct iked_proposal *prop, *proptmp; - 253| 13.0k| int i; + 250| 13.1k|{ + 251| 13.1k| struct iked_certreq *cr; + 252| 13.1k| struct iked_proposal *prop, *proptmp; + 253| 13.1k| int i; 254| | - 255| 13.0k| if (msg == msg->msg_parent) { - ------------------ - | Branch (255:6): [True: 13.0k, False: 0] - ------------------ - 256| 13.0k| ibuf_free(msg->msg_nonce); - 257| 13.0k| ibuf_free(msg->msg_ke); - 258| 13.0k| ibuf_free(msg->msg_auth.id_buf); - 259| 13.0k| ibuf_free(msg->msg_peerid.id_buf); - 260| 13.0k| ibuf_free(msg->msg_localid.id_buf); - 261| 13.0k| ibuf_free(msg->msg_cert.id_buf); - 262| 52.1k| for (i = 0; i < IKED_SCERT_MAX; i++) - ------------------ - | | 477| 52.1k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ - ------------------ - | Branch (262:15): [True: 39.1k, False: 13.0k] - ------------------ - 263| 39.1k| ibuf_free(msg->msg_scert[i].id_buf); - 264| 13.0k| ibuf_free(msg->msg_cookie); - 265| 13.0k| ibuf_free(msg->msg_cookie2); - 266| 13.0k| ibuf_free(msg->msg_del_buf); - 267| 13.0k| free(msg->msg_eap.eam_user); - 268| 13.0k| free(msg->msg_cp_addr); - 269| 13.0k| free(msg->msg_cp_addr6); - 270| 13.0k| free(msg->msg_cp_dns); + 255| 13.1k| if (msg == msg->msg_parent) { + ------------------ + | Branch (255:6): [True: 13.1k, False: 0] + ------------------ + 256| 13.1k| ibuf_free(msg->msg_nonce); + 257| 13.1k| ibuf_free(msg->msg_ke); + 258| 13.1k| ibuf_free(msg->msg_auth.id_buf); + 259| 13.1k| ibuf_free(msg->msg_peerid.id_buf); + 260| 13.1k| ibuf_free(msg->msg_localid.id_buf); + 261| 13.1k| ibuf_free(msg->msg_cert.id_buf); + 262| 52.7k| for (i = 0; i < IKED_SCERT_MAX; i++) + ------------------ + | | 477| 52.7k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ + ------------------ + | Branch (262:15): [True: 39.5k, False: 13.1k] + ------------------ + 263| 39.5k| ibuf_free(msg->msg_scert[i].id_buf); + 264| 13.1k| ibuf_free(msg->msg_cookie); + 265| 13.1k| ibuf_free(msg->msg_cookie2); + 266| 13.1k| ibuf_free(msg->msg_del_buf); + 267| 13.1k| free(msg->msg_eap.eam_user); + 268| 13.1k| free(msg->msg_cp_addr); + 269| 13.1k| free(msg->msg_cp_addr6); + 270| 13.1k| free(msg->msg_cp_dns); 271| | - 272| 13.0k| TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry, + 272| 13.1k| TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry, ------------------ - | | 445| 13.0k| for ((var) = TAILQ_FIRST(head); \ + | | 445| 13.1k| for ((var) = TAILQ_FIRST(head); \ | | ------------------ - | | | | 428| 13.0k|#define TAILQ_FIRST(head) ((head)->tqh_first) + | | | | 428| 13.1k|#define TAILQ_FIRST(head) ((head)->tqh_first) | | ------------------ - | | 446| 13.0k| (var) != TAILQ_END(head) && \ + | | 446| 13.1k| (var) != TAILQ_END(head) && \ | | ------------------ - | | | | 429| 26.0k|#define TAILQ_END(head) NULL + | | | | 429| 26.3k|#define TAILQ_END(head) NULL | | ------------------ - | | | Branch (446:6): [True: 0, False: 13.0k] + | | | Branch (446:6): [True: 0, False: 13.1k] | | ------------------ - | | 447| 13.0k| ((tvar) = TAILQ_NEXT(var, field), 1); \ + | | 447| 13.1k| ((tvar) = TAILQ_NEXT(var, field), 1); \ | | ------------------ | | | | 430| 0|#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) | | ------------------ | | | Branch (447:6): [True: 0, False: 0] | | ------------------ - | | 448| 13.0k| (var) = (tvar)) + | | 448| 13.1k| (var) = (tvar)) ------------------ - 273| 13.0k| proptmp) { + 273| 13.1k| proptmp) { 274| 0| TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry); ------------------ | | 504| 0|#define TAILQ_REMOVE(head, elm, field) do { \ @@ -3333,32 +3333,32 @@ ikev2_msg_cleanup: 277| 0| free(prop); 278| 0| } 279| | - 280| 13.0k| msg->msg_nonce = NULL; - 281| 13.0k| msg->msg_ke = NULL; - 282| 13.0k| msg->msg_auth.id_buf = NULL; - 283| 13.0k| msg->msg_peerid.id_buf = NULL; - 284| 13.0k| msg->msg_localid.id_buf = NULL; - 285| 13.0k| msg->msg_cert.id_buf = NULL; - 286| 52.1k| for (i = 0; i < IKED_SCERT_MAX; i++) - ------------------ - | | 477| 52.1k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ - ------------------ - | Branch (286:15): [True: 39.1k, False: 13.0k] - ------------------ - 287| 39.1k| msg->msg_scert[i].id_buf = NULL; - 288| 13.0k| msg->msg_cookie = NULL; - 289| 13.0k| msg->msg_cookie2 = NULL; - 290| 13.0k| msg->msg_del_buf = NULL; - 291| 13.0k| msg->msg_eap.eam_user = NULL; - 292| 13.0k| msg->msg_cp_addr = NULL; - 293| 13.0k| msg->msg_cp_addr6 = NULL; - 294| 13.0k| msg->msg_cp_dns = NULL; + 280| 13.1k| msg->msg_nonce = NULL; + 281| 13.1k| msg->msg_ke = NULL; + 282| 13.1k| msg->msg_auth.id_buf = NULL; + 283| 13.1k| msg->msg_peerid.id_buf = NULL; + 284| 13.1k| msg->msg_localid.id_buf = NULL; + 285| 13.1k| msg->msg_cert.id_buf = NULL; + 286| 52.7k| for (i = 0; i < IKED_SCERT_MAX; i++) + ------------------ + | | 477| 52.7k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ + ------------------ + | Branch (286:15): [True: 39.5k, False: 13.1k] + ------------------ + 287| 39.5k| msg->msg_scert[i].id_buf = NULL; + 288| 13.1k| msg->msg_cookie = NULL; + 289| 13.1k| msg->msg_cookie2 = NULL; + 290| 13.1k| msg->msg_del_buf = NULL; + 291| 13.1k| msg->msg_eap.eam_user = NULL; + 292| 13.1k| msg->msg_cp_addr = NULL; + 293| 13.1k| msg->msg_cp_addr6 = NULL; + 294| 13.1k| msg->msg_cp_dns = NULL; 295| | - 296| 13.9k| while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) { + 296| 14.0k| while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) { ------------------ - | | 267| 13.9k|#define SIMPLEQ_FIRST(head) ((head)->sqh_first) + | | 267| 14.0k|#define SIMPLEQ_FIRST(head) ((head)->sqh_first) ------------------ - | Branch (296:10): [True: 897, False: 13.0k] + | Branch (296:10): [True: 897, False: 13.1k] ------------------ 297| 897| ibuf_free(cr->cr_data); 298| 897| SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry); @@ -3376,30 +3376,30 @@ ikev2_msg_cleanup: ------------------ 299| 897| free(cr); 300| 897| } - 301| 13.0k| } + 301| 13.1k| } 302| | - 303| 13.0k| if (msg->msg_data != NULL) { + 303| 13.1k| if (msg->msg_data != NULL) { ------------------ - | Branch (303:6): [True: 13.0k, False: 0] + | Branch (303:6): [True: 13.1k, False: 0] ------------------ - 304| 13.0k| ibuf_free(msg->msg_data); - 305| 13.0k| msg->msg_data = NULL; - 306| 13.0k| } - 307| 13.0k|} + 304| 13.1k| ibuf_free(msg->msg_data); + 305| 13.1k| msg->msg_data = NULL; + 306| 13.1k| } + 307| 13.1k|} LLVMFuzzerTestOneInput: - 107| 13.0k|{ - 108| 13.0k| struct ibuf *fuzzed; - 109| 13.0k| struct ike_header hdr; - 110| 13.0k| struct iked_message msg; + 107| 13.1k|{ + 108| 13.1k| struct ibuf *fuzzed; + 109| 13.1k| struct ike_header hdr; + 110| 13.1k| struct iked_message msg; 111| | - 112| 13.0k| bzero(&hdr, sizeof(hdr)); - 113| 13.0k| bzero(&msg, sizeof(msg)); + 112| 13.1k| bzero(&hdr, sizeof(hdr)); + 113| 13.1k| bzero(&msg, sizeof(msg)); 114| | - 115| 13.0k| fuzzed = ibuf_new(data, size); - 116| 13.0k| if (fuzzed == NULL){ + 115| 13.1k| fuzzed = ibuf_new(data, size); + 116| 13.1k| if (fuzzed == NULL){ ------------------ - | Branch (116:6): [True: 0, False: 13.0k] + | Branch (116:6): [True: 0, False: 13.1k] ------------------ 117| 0| fprintf(stderr, "%s\n", "ERROR: fuzzed == NULL! " 118| 0| "(hint: fuzz-input too long?)"); @@ -3407,108 +3407,108 @@ LLVMFuzzerTestOneInput: 120| 0| } 121| | 122| | /* size too small? */ - 123| 13.0k| if (size < sizeof(cookies) + sizeof(genhdr)){ + 123| 13.1k| if (size < sizeof(cookies) + sizeof(genhdr)){ ------------------ - | Branch (123:6): [True: 1, False: 13.0k] + | Branch (123:6): [True: 1, False: 13.1k] ------------------ 124| 1| ibuf_free(fuzzed); 125| 1| return 0; 126| 1| } 127| | - 128| 13.0k| prepare_header(&hdr, fuzzed); - 129| 13.0k| prepare_message(&msg, fuzzed); + 128| 13.1k| prepare_header(&hdr, fuzzed); + 129| 13.1k| prepare_message(&msg, fuzzed); 130| | - 131| 13.0k| ikev2_pld_parse(NULL, &hdr, &msg, 0); + 131| 13.1k| ikev2_pld_parse(NULL, &hdr, &msg, 0); 132| | - 133| 13.0k| ikev2_msg_cleanup(NULL, &msg); + 133| 13.1k| ikev2_msg_cleanup(NULL, &msg); 134| | - 135| 13.0k| return 0; - 136| 13.0k|} + 135| 13.1k| return 0; + 136| 13.1k|} test_parser_fuzz.c:prepare_header: - 75| 13.0k|{ - 76| 13.0k| bzero(hdr, sizeof(*hdr)); - 77| 13.0k| bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi, - 78| 13.0k| sizeof(hdr->ike_ispi)); - 79| 13.0k| bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi, - 80| 13.0k| sizeof(hdr->ike_rspi)); - 81| 13.0k| hdr->ike_nextpayload = get_nextpayload(ibuf_data(data)); - 82| 13.0k| hdr->ike_version = get_version(ibuf_data(data)); - 83| 13.0k| hdr->ike_exchange = get_exchange(ibuf_data(data)); - 84| 13.0k| hdr->ike_length = get_length(ibuf_data(data)); - 85| 13.0k|} + 75| 13.1k|{ + 76| 13.1k| bzero(hdr, sizeof(*hdr)); + 77| 13.1k| bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi, + 78| 13.1k| sizeof(hdr->ike_ispi)); + 79| 13.1k| bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi, + 80| 13.1k| sizeof(hdr->ike_rspi)); + 81| 13.1k| hdr->ike_nextpayload = get_nextpayload(ibuf_data(data)); + 82| 13.1k| hdr->ike_version = get_version(ibuf_data(data)); + 83| 13.1k| hdr->ike_exchange = get_exchange(ibuf_data(data)); + 84| 13.1k| hdr->ike_length = get_length(ibuf_data(data)); + 85| 13.1k|} test_parser_fuzz.c:get_icookie: - 39| 13.0k|{ - 40| 13.0k| return &data[OFFSET_ICOOKIE]; + 39| 13.1k|{ + 40| 13.1k| return &data[OFFSET_ICOOKIE]; ------------------ - | | 30| 13.0k|#define OFFSET_ICOOKIE 0 + | | 30| 13.1k|#define OFFSET_ICOOKIE 0 ------------------ - 41| 13.0k|} + 41| 13.1k|} test_parser_fuzz.c:get_rcookie: - 45| 13.0k|{ - 46| 13.0k| return &data[OFFSET_RCOOKIE]; + 45| 13.1k|{ + 46| 13.1k| return &data[OFFSET_RCOOKIE]; ------------------ - | | 31| 13.0k|#define OFFSET_RCOOKIE 8 + | | 31| 13.1k|#define OFFSET_RCOOKIE 8 ------------------ - 47| 13.0k|} + 47| 13.1k|} test_parser_fuzz.c:get_nextpayload: - 51| 13.0k|{ - 52| 13.0k| return data[OFFSET_NEXTPAYLOAD]; + 51| 13.1k|{ + 52| 13.1k| return data[OFFSET_NEXTPAYLOAD]; ------------------ - | | 32| 13.0k|#define OFFSET_NEXTPAYLOAD (0 + sizeof(cookies)) + | | 32| 13.1k|#define OFFSET_NEXTPAYLOAD (0 + sizeof(cookies)) ------------------ - 53| 13.0k|} + 53| 13.1k|} test_parser_fuzz.c:get_version: - 57| 13.0k|{ - 58| 13.0k| return data[OFFSET_VERSION]; + 57| 13.1k|{ + 58| 13.1k| return data[OFFSET_VERSION]; ------------------ - | | 33| 13.0k|#define OFFSET_VERSION (1 + sizeof(cookies)) + | | 33| 13.1k|#define OFFSET_VERSION (1 + sizeof(cookies)) ------------------ - 59| 13.0k|} + 59| 13.1k|} test_parser_fuzz.c:get_exchange: - 63| 13.0k|{ - 64| 13.0k| return data[OFFSET_EXCHANGE]; + 63| 13.1k|{ + 64| 13.1k| return data[OFFSET_EXCHANGE]; ------------------ - | | 34| 13.0k|#define OFFSET_EXCHANGE (2 + sizeof(cookies)) + | | 34| 13.1k|#define OFFSET_EXCHANGE (2 + sizeof(cookies)) ------------------ - 65| 13.0k|} + 65| 13.1k|} test_parser_fuzz.c:get_length: - 69| 13.0k|{ - 70| 13.0k| return *(u_int32_t *)&data[OFFSET_LENGTH]; + 69| 13.1k|{ + 70| 13.1k| return *(u_int32_t *)&data[OFFSET_LENGTH]; ------------------ - | | 35| 13.0k|#define OFFSET_LENGTH (8 + sizeof(cookies)) + | | 35| 13.1k|#define OFFSET_LENGTH (8 + sizeof(cookies)) ------------------ - 71| 13.0k|} + 71| 13.1k|} test_parser_fuzz.c:prepare_message: - 89| 13.0k|{ - 90| 13.0k| static struct iked_sa sa; + 89| 13.1k|{ + 90| 13.1k| static struct iked_sa sa; 91| | - 92| 13.0k| bzero(&sa, sizeof(sa)); - 93| 13.0k| bzero(msg, sizeof(*msg)); + 92| 13.1k| bzero(&sa, sizeof(sa)); + 93| 13.1k| bzero(msg, sizeof(*msg)); 94| | - 95| 13.0k| msg->msg_sa = &sa; - 96| 13.0k| msg->msg_data = data; - 97| 13.0k| msg->msg_e = 1; - 98| 13.0k| msg->msg_parent = msg; + 95| 13.1k| msg->msg_sa = &sa; + 96| 13.1k| msg->msg_data = data; + 97| 13.1k| msg->msg_e = 1; + 98| 13.1k| msg->msg_parent = msg; 99| | - 100| 13.0k| TAILQ_INIT(&msg->msg_proposals); + 100| 13.1k| TAILQ_INIT(&msg->msg_proposals); ------------------ - | | 465| 13.0k|#define TAILQ_INIT(head) do { \ - | | 466| 13.0k| (head)->tqh_first = NULL; \ - | | 467| 13.0k| (head)->tqh_last = &(head)->tqh_first; \ - | | 468| 13.0k|} while (0) + | | 465| 13.1k|#define TAILQ_INIT(head) do { \ + | | 466| 13.1k| (head)->tqh_first = NULL; \ + | | 467| 13.1k| (head)->tqh_last = &(head)->tqh_first; \ + | | 468| 13.1k|} while (0) | | ------------------ | | | Branch (468:10): [Folded - Ignored] | | ------------------ ------------------ - 101| 13.0k| SIMPLEQ_INIT(&msg->msg_certreqs); + 101| 13.1k| SIMPLEQ_INIT(&msg->msg_certreqs); ------------------ - | | 285| 13.0k|#define SIMPLEQ_INIT(head) do { \ - | | 286| 13.0k| (head)->sqh_first = NULL; \ - | | 287| 13.0k| (head)->sqh_last = &(head)->sqh_first; \ - | | 288| 13.0k|} while (0) + | | 285| 13.1k|#define SIMPLEQ_INIT(head) do { \ + | | 286| 13.1k| (head)->sqh_first = NULL; \ + | | 287| 13.1k| (head)->sqh_last = &(head)->sqh_first; \ + | | 288| 13.1k|} while (0) | | ------------------ | | | Branch (288:10): [Folded - Ignored] | | ------------------ ------------------ - 102| 13.0k|} + 102| 13.1k|}