From ba63070f9a835832241cda525f8295b0208d8d41 Mon Sep 17 00:00:00 2001 From: CIFuzz Date: Tue, 31 Oct 2023 00:56:38 +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 | 40 +- .../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 | 3814 ++++++++--------- 62 files changed, 1987 insertions(+), 1983 deletions(-) diff --git a/coverage/latest/dumps/merged.profdata b/coverage/latest/dumps/merged.profdata index b59043d9ff20695ab5b05f7dc727dfe0f0d05a64..271b8f8204dd8f879348ef9126f2caed6c7e7bf8 100644 GIT binary patch delta 3390 zcmZ8kYfzMB6n^=3x$L(Hy9)>`vannYL=nU*0xP#&L?Bf1mZ@ZBP2L(CbgE^_w8^m; zk7n5goT;?5($N~rACfwgHvK_nn#r6(2TYyP8h@lSI@9-k=Q%j;{@{7f<$cfPJ?DHc z-R<4&J;CtuZxfXH6TBR2v*=B|O%}QeEf|$YF{%2t^Gfy!zh(^YKex_dX=>0PBD=MU z;D=SWH^vg=pN+GSw=0!>Al9PaDq!U8O7$1=!TBFWTXO!Z)QYcki#~dvP4a05t0Law zCk(QSPK#2i@6;G$6;|rxEav1u@XxE9kx9ACmBDLJGzzDUrL)>J@9ip_=w&Q16Jh)&I4zYT+iY!p6|J?^%`BV3lG8BSo=Zah5C3Zb_Df{)lAkn=oLqkcPNb`KZ=vT zcCk1dLsuMa+8K??^$zpucj_U}njj1N;k+lEuIY1W#O9)avpiRZ%F}6_wjI~G3;*`B z_tOt(w9nb(k*?Z|r1aS6j%s~1tpkE zJ`PIg-{G%@X(cF@{#Yw3MwtTJCo_FzETcFM?OOFO9FX3FK#j-(D0k3-QeWm~!Alcq zz&^HCIz?v1-S1g^2AyyjEhDrPQ`J3IsJy4q%7j|&4C-=t zmzT~Y*7+sIE}p+?Cv3q(Ww+Y7$~9G&TfbOgI_oaQSek{{RvR``A6pGdxTs1Mi7py( zEwCK*S5RWQgSNP*+l;RTop3j_$6`hfp(_iKrW^$P06y-AvHyVA(Y^0L?@jFQiZS!y zxR2W2O)q+un&}v@`{6he6ZHU7zOPOJ2;DwZyuoPuIf3o3(QXO#rU=y>B@Do4{B1@PMqx$Rdg*ym6 zBx_VIv>*hU+F{&IRseUVZj5f=MNI@PNfpGHSEY0;D>b}OCN*~5i`cy-f(}K{xJf1N z3K74CMM=c@^F)D>THTJxiz0L)=?jnUQ5TH(3mv#FrI{4H?T<@CM~-UqlT0ZZ$WNs< ze*uk2cT#a$nP(4XxoBRtne}dcxA&%%>+%Ro7^JBDLTYoT8lpO{bXg%Rufh#Hq0zeZ zI&Dw2+2&@8nopRk=`}Xv)k*o@K-4Z;<89St=5@wVzxQ#Q@iL_3jApkKe>v`F0d33( z$SFT%l$U+JiQNMOjmy zldr=?6#o4AeC#ubbSv_>joIoNj`so2gD<57Qq^N2=u9?mPrI2&H?!vI58IrovjZ9O zpTY#ZG=(-E;PgRuP-`iok?fGC86PCU;ms8ASLCW;Jb+|4h!4xKFh;_A{(y5q635bS z4CG;dyE!SQ=Y+hMmb2Pm0iz$0oiJ?Y)aN{WQm|Om4`KKpk0vd*&dhKyw@pi`r2V+!33KKuVJ9Fv6r delta 3297 zcmZ8jU2IfU5T1MQF74i3+V0Yy?e=%KEd_*Fx3p5Fw7cDIcUw}HQWa>3R*kiZB8@Mu z{A?j;AjZTnK@nfj2ZAA*P|#p}L2F_pVp1P`5HJ)`B7s80goK2|d++(Cg}pD|nK?6a z=I_k8lS7k3AEa^v$2GD)!Sp7Fq_;mWa26%aik5vPO?2$tNA-l?z1VOR^5w6v%i+g0 zC8;a3IhqVDa+U|@6i2BO)qkoS*fg#9N}cFjv&UiVJ*xO_1@yv~rn8a&l(xlc^Ev#< zMkT1EtN^}UY%y{~Sy-r3`*dedk+TZIlhxq2R24g`e?e~+T&MWupbr2q#S~wKNAv~w z?Qz9-@=$Ft&ts$O;SHP5vs&ETk4&A_c$J>)IEqBS1f^rZ2yhG-fLs`KlC{bTp4OiX zdF;5YZw?vVhBz;4oC}uo3ZqkRAs#mpPvx-Vg)NC(&f2C7k!Sh{?O@X zl)*UcZUxp5&w4U?lDO4;)-LdSW;$>SG3-WH{6YM;IiMLF^~M`yX3QW_zI!S&!>5$V zwoc-Yy!`>WGy^y(NPO3utduaorAGr9_jT*P=zP+*!LWuFKk%h=8`+SnC1&Ir2rUIz2}94LL`Mvsah3PTosdy* z9}Sg+{;m~jAvD6K(}-tkn0U0PN6Yf5rV7sZ3!U5fb5WmNwX)(ZHtZ-)nPPv=#orev zLK5a#c$2_!hPt%tO4>bA?hzhss_-Ac!HAknyWf^emkSr&Mfs@nUnRrv@lJ3VXZ>po z>lNTL{^ZaVC`*Qum2W)S5@jc|{l*apH+3sV!31{culUr7VDZa7+ZWdfA8yK{w^`3ph}^ z-mtC}kCygCvv@;g6t*G5V(mX@Ujjy5{9EZ-ZHi~CuCV8Iw5-EU!s}&&L(-8=@CYj8 zM!*-rkP#`K<%v@Zvnsrtwcy}%n4}i1x^reuS{q+>`|a+-OfM6)yi(e z`T^voP)zgjSZISOgX=?$&xJM`*3TQ4R;~9-A8&`Ta-OJ)iIwwJt6@n2|5IK2xXkwyY`lR7TBb%XY{r38zzpz3U;-$B zVMBr=GJo~3i*M8omMAoMR7jVf0#|rJrH_#Z8 ziuYQ)Ah|Kt)jkrAc?X)+&S;qUT6oC5@oOUKkcR0|32&D{KW3dB>5VM>6ezxk?}PY3 xV!a_@=Q!1n(NDPeXhWA>x{D3z`9I5jFxjhdd*fF7;6sgr`UCgrtBtj;{{dAEUl{-Z diff --git a/coverage/latest/dumps/test_libfuzzer.profdata b/coverage/latest/dumps/test_libfuzzer.profdata index 9788d952d9e57454ceb867e733ec8316ce5ec243..ad02e4a81f85c919cde908c3a2276e29b247c8f6 100644 GIT binary patch delta 3386 zcmZ8kYiv|i5I()z((c{T?rvMUyQSN1w`H+V9<41DQ#{K^q1{Q7j}XsHhOofc)T@2*y9q#6)bg5Q;z)H2e?}Fy4FTn-X?^^gHu7XC7x} z?&-$1jcq;A_~P#}l=&0vPqkU}n%))*ogoW`(S$1XZ7N~ygkh8wH6Qpct;rwD?-U*n974>DsC_!IIntyK@(Q47KEsAYaCQt$@& z{SoGm0sRHAY8vycutyrqlMsXDsy1LXFpHABxpX(BPTTM?RSs*2PYSR^uJAbMIf&;I6kl^5 z>qS5>fV1MX#Ltzh)Tc1mg>!BT4Xj|KW|u22x@#eu02FZGV)J2p70OM5f(a#MH4hud z14jdk3CXHzZ7P&&Q1<{oqbj*lQBA6lB-LT6{K3HY_-?;20R@3AsG0^ z$s6Ls=!$)|c1EKLeV%#sTlJWGd6b2x;Jn*Q*Y)W%Xme7;Q4y4(^1O%Bw&ezQ;a>p` zV)8zXb~#$y(p77blpY)1bu{_JSGJ+lW8Qk`<@8!@W{CdF89}Ghr`U|qMi0|t@hCDZ zC;?seb6`UM2A?%dEJ3mM`wCex$|Tr4k?AWV7{z&L*Q_dScxpd0$pHbP55)!t`?n)@0p&8XLoO&#jppE8=wo6E^;(dE=` zAFaroZ*tFMHUuQbZl1wvD{R3-m29R*&e}MYlPOrFIS`KgEU2Pb-t}LeC!zMot9fO%8bPbGbD`tfn8>MD-nCV=a)$xqn z>=xL}X?A^i#Z; z1xC?uuY>w?Cs`fsiMn@S(94E?n_1`9H+!e2LYD_vMjs`WgbXXWhN!_O-4#NSbm9`` zYqZkapzR2o?QOQE`Fy$Rt+N>~PAc(5lD5%uU#l*&t}BgB`JT2JuR_Yso8gkeufP?} zrPX;6IpxQ^it^9bu$zM7^eiN{=jOq1$pxvyi zJAtrcZWf1h%9zJfilV;Di&?F26k`C99W`thH5NU3Z?IU@4`ApYNg*xRU}iWPoULWm m(C%Q^yt-e5v7r}h5o$esI8_xdFdf-mJWK0pJ#w|!pZq_uRFi@L delta 3275 zcmZ8jZ){Ul6uRqic5W~Pwsu|DZv5%SkO?6=G|nXkL;Pap zPX|E*Atq)gDB>6N1HlkY7-%4VL1$tlVlqGYLBKGK5*HXmOh`ybeDB@g*`V*s@1Aqd zIrp4%&pG!^3{4Dun9dKJ)`ayjX13U*c=wB9dr{V;Xx>-SLY#X4X+7q5FVSsONBrY?)Skr7pzfCb!KvcvA753dAd48TN_;P}(M| z-D~qF8kC@tG6VQ_iOI+dk%NU=wJ+`;D6v;Tc=9~>tyQJ=>R-?!jO!J@0`w8!^|<1z z@Pzmh{Emd;+j*!qnOCsU_2h=dr&%pw97d)tYV?dub)H0`Uxm^sU=%n8^g}KJIz?J# zfTrcDklTve{N|C-orv>>M)_a`wdm_)tDtc`xh9Vt4{UMdeAZ57NHED2b z)PIEf3mSDfMq+&%pax)?@ix>JX^Q*8R95MtdycfcDyh>Mw_u;M&)*3nexMZQ8DVTE*Fooi%}B>_&~Fs%Zvu^A1Yb7?zYP0Jfv7X;^ZD{Di_8mE z!4Ndz2P`?E|A4Lm@|j#ps(^&xTJ}JWX^;Z)x^P-)sW5gR#-L7Ti@R3Te60i-r~g!` z|NMgD?}eSccI~vdI^?9JU9OGBIP5e^y5ve54?#`}^0>R*F_b~dytjb+8#uquHge3p zHgtZgvYUYU?Z6sAv+k@+32HN5v@ZCVk@4R}4Es?Pe+c^97|?Wzc@p(JGiHz|??aWD z;d9Dl`#M1%d;0y{Gy^y(DCmJFRmqNmE1q_B+}kaGk#yF(SvQ9kJ@#huKOr(kj-+;* zGQspESbQ|B7L0sQwU1W{xyNS_q!-A3L%K)YLpHdz*bKJ;(|kcIVd!OC!U>&b92Gs> z6FdqYp`cRG-`AoROe1V@9`Q^K3mPry(QWgTw5?j1DR81Nmz!H8NIRz5Wj+x*qRXKi%WZjtLtB2 z^IbB7Y3qT1^5ci9kZ+gvbG*wMg*0cM_oHUjHE}+&z95zhoXB#j3;XGMV3pmO!L)A< zh0YfCm=RzZ8J;%wzgRa@*=ToNO@%&+8Q zgz^q5`ge_zS8664ms_UQzf*0;AkX$RY`lfXnI}dsY$kwHz$|bVFbNd2 zu_B=D;7KbZ4w|bSFc$lhy6WOp{MUN}1

Coverage Report

Created: 2023-10-30 00:56

/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-10-31 00:56

/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 23aaacbdf..ffae26e02 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-10-30 00:56

/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-10-31 00:56

/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 e5f12a2dc..4d83c3ad1 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-10-30 00:56

/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-10-31 00:56

/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 b04e5a1bf..171ba81ad 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-10-30 00:56

/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-10-31 00:56

/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 3f9daf2f9..54011cc1d 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-10-30 00:56

/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
1.51k
{
26
  /* This is legal. */
27
1.51k
  if (ptr == NULL)
28
113
    return;
29
30
1.40k
  explicit_bzero(ptr, sz);
31
1.40k
  free(ptr);
32
1.40k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
16.2k
{
26
  /* This is legal. */
27
16.2k
  if (ptr == NULL)
28
988
    return;
29
30
15.2k
  explicit_bzero(ptr, sz);
31
15.2k
  free(ptr);
32
15.2k
}
\ 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 8a57f8f7e..d074bd422 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-10-30 00:56

/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-10-31 00:56

/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 107ebcf35..ab6bfcfb7 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-10-30 00:56

/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-10-31 00:56

/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 f92ace0fb..9943ec153 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-10-30 00:56

/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
1.51k
{
63
1.51k
  struct ibuf *buf;
64
65
1.51k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
1.51k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
1.51k
  if (len > 0) {
73
1.40k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
1.40k
  }
78
1.51k
  buf->size = len;
79
1.51k
  buf->max = max;
80
1.51k
  buf->fd = -1;
81
82
1.51k
  return (buf);
83
1.51k
}
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
1.40k
{
108
1.40k
  void  *b;
109
110
1.40k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
1.40k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
1.40k
  b = buf->buf + buf->wpos;
120
1.40k
  buf->wpos += len;
121
1.40k
  memset(b, 0, len);
122
1.40k
  return (b);
123
1.40k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
1.40k
{
128
1.40k
  void *b;
129
130
1.40k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
1.40k
  memcpy(b, data, len);
134
1.40k
  return (0);
135
1.40k
}
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
21.3k
{
203
  /* only allowed to seek in already written parts */
204
21.3k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
477
    errno = ERANGE;
206
477
    return (NULL);
207
477
  }
208
209
20.8k
  return (buf->buf + pos);
210
21.3k
}
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
65.8k
{
273
65.8k
  return (buf->buf);
274
65.8k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
717
{
279
717
  return (buf->wpos);
280
717
}
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
10.0k
{
297
10.0k
  if (buf == NULL)
298
8.54k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
1.51k
  freezero(buf->buf, buf->size);
304
1.51k
  free(buf);
305
1.51k
}
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-10-31 00:56

/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
16.2k
{
63
16.2k
  struct ibuf *buf;
64
65
16.2k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
16.2k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
16.2k
  if (len > 0) {
73
15.2k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
15.2k
  }
78
16.2k
  buf->size = len;
79
16.2k
  buf->max = max;
80
16.2k
  buf->fd = -1;
81
82
16.2k
  return (buf);
83
16.2k
}
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
15.2k
{
108
15.2k
  void  *b;
109
110
15.2k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
15.2k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
15.2k
  b = buf->buf + buf->wpos;
120
15.2k
  buf->wpos += len;
121
15.2k
  memset(b, 0, len);
122
15.2k
  return (b);
123
15.2k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
15.2k
{
128
15.2k
  void *b;
129
130
15.2k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
15.2k
  memcpy(b, data, len);
134
15.2k
  return (0);
135
15.2k
}
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
198k
{
203
  /* only allowed to seek in already written parts */
204
198k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
2.86k
    errno = ERANGE;
206
2.86k
    return (NULL);
207
2.86k
  }
208
209
195k
  return (buf->buf + pos);
210
198k
}
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
618k
{
273
618k
  return (buf->buf);
274
618k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
10.0k
{
279
10.0k
  return (buf->wpos);
280
10.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
136k
{
297
136k
  if (buf == NULL)
298
119k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
16.2k
  freezero(buf->buf, buf->size);
304
16.2k
  free(buf);
305
16.2k
}
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 239a6266e..58d4ee008 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-10-30 00:56

/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-10-31 00:56

/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 33a9f919d..0c8e72c0b 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-10-30 00:56

/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-10-31 00:56

/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 98e47b6c4..96ab19429 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-10-30 00:56

/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
562
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
562
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
124
  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-10-31 00:56

/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
10.8k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
10.8k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
1.82k
  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 7fde06138..9e3adc1ce 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-10-30 00:56

/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-10-31 00:56

/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 86e8a7f58..df05adc2f 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-10-30 00:56

/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-10-31 00:56

/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 fa5227978..ba80f51c9 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-10-30 00:56

/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-10-31 00:56

/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 52ebfc5f5..a82d64fe0 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-10-30 00:56

/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
46.3k
{
30
46.3k
  const char *osrc = src;
31
46.3k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
46.3k
  if (nleft != 0) {
35
255k
    while (--nleft != 0) {
36
254k
      if ((*dst++ = *src++) == '\0')
37
46.2k
        break;
38
254k
    }
39
46.3k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
46.3k
  if (nleft == 0) {
43
123
    if (dsize != 0)
44
123
      *dst = '\0';   /* NUL-terminate dst */
45
123
    while (*src++)
46
0
      ;
47
123
  }
48
49
46.3k
  return(src - osrc - 1); /* count does not include NUL */
50
46.3k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
405k
{
30
405k
  const char *osrc = src;
31
405k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
405k
  if (nleft != 0) {
35
2.99M
    while (--nleft != 0) {
36
2.99M
      if ((*dst++ = *src++) == '\0')
37
403k
        break;
38
2.99M
    }
39
405k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
405k
  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
405k
  return(src - osrc - 1); /* count does not include NUL */
50
405k
}
\ 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 ca2e50cc5..9021ea56e 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-10-30 00:56

/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-10-31 00:56

/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 0171c630a..a9481d111 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-10-30 00:56

/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
802
#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
717
#define SIMPLEQ_INIT(head) do {           \
286
717
  (head)->sqh_first = NULL;         \
287
717
  (head)->sqh_last = &(head)->sqh_first;        \
288
717
} 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
85
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
85
  (elm)->field.sqe_next = NULL;         \
298
85
  *(head)->sqh_last = (elm);          \
299
85
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
85
} 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
85
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
85
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
85
    (head)->sqh_last = &(head)->sqh_first;     \
311
85
} 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
717
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
1.43k
#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
717
  for ((var) = TAILQ_FIRST(head);         \
446
717
      (var) != TAILQ_END(head) &&         \
447
717
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
717
      (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
717
#define TAILQ_INIT(head) do {           \
466
717
  (head)->tqh_first = NULL;         \
467
717
  (head)->tqh_last = &(head)->tqh_first;        \
468
717
} 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-10-31 00:56

/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
10.5k
#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
10.0k
#define SIMPLEQ_INIT(head) do {           \
286
10.0k
  (head)->sqh_first = NULL;         \
287
10.0k
  (head)->sqh_last = &(head)->sqh_first;        \
288
10.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
526
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
526
  (elm)->field.sqe_next = NULL;         \
298
526
  *(head)->sqh_last = (elm);          \
299
526
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
526
} 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
526
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
526
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
526
    (head)->sqh_last = &(head)->sqh_first;     \
311
526
} 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
10.0k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
20.1k
#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
10.0k
  for ((var) = TAILQ_FIRST(head);         \
446
10.0k
      (var) != TAILQ_END(head) &&         \
447
10.0k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
10.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
10.0k
#define TAILQ_INIT(head) do {           \
466
10.0k
  (head)->tqh_first = NULL;         \
467
10.0k
  (head)->tqh_last = &(head)->tqh_first;        \
468
10.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 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 bab15b08f..cd7c7f318 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-10-30 00:56

/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-10-31 00:56

/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 e1522bbc0..007238140 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-10-30 00:56

/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-10-31 00:56

/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 b97ebe790..755366626 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-10-30 00:56

/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-10-31 00:56

/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 77ece8a0f..b6ce5df7e 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-10-30 00:56

/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
6.08k
#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
12
#define IKED_MSG_NAT_SRC_IP       0x01
688
36
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
10
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
10
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
10
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
10
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
10
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
18
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
12
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
10
#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
1.70k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
1.70k
#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-10-31 00:56

/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
84.1k
#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
2.47k
#define IKED_MSG_NAT_SRC_IP       0x01
688
13.5k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
133
#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
233
#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
224
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
341
#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.42k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.42k
#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 7ade79301..400858f42 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-10-30 00:56

/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
12
#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
21.7k
#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
4.38k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
644
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
1.00k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
1.77k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
410
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
1.77k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
773
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
57
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
1.12k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
812
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
351
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
1.27k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
21.6k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
1.30k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
3.33k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
21.6k
#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
782
#define IKEV2_XFORM_MORE    3
155
156
334
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
434
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
67
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
68
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
66
#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
3.61k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
1.07k
#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
10
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
11
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
1
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
10
#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
12
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
10
#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
20
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
61
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
50
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
1
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
28
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
17
#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
28
#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
18
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
34
#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
1
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
1
#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
880
#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
335
#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
108
#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
151
#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
242
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
93
#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
196
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
281
#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
216
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
301
#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-10-31 00:56

/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
195k
#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
27.1k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
5.93k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
12.7k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
18.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.21k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
10.2k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
7.98k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
229
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
24.5k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
6.99k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.44k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
16.3k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
194k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
8.50k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
16.1k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
194k
#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
2.73k
#define IKEV2_XFORM_MORE    3
155
156
1.05k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
765
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
247
#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
56.5k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
21.9k
#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
233
#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
341
#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
249
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
18.4k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
15.9k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
301
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
64
#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
263
#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
344
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
201
#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.1k
#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.07k
#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
812
#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.78k
#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
4.72k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.14k
#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.30k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.58k
#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.18k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
2.90k
#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 90d2ff1d5..925ed03cf 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-10-30 00:56

/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
717
{
119
717
  log_debug("%s: header ispi %s rspi %s"
120
717
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
717
      " msgid %d length %u response %d", __func__,
122
717
      print_spi(betoh64(hdr->ike_ispi), 8),
123
717
      print_spi(betoh64(hdr->ike_rspi), 8),
124
717
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
717
      hdr->ike_version,
126
717
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
717
      hdr->ike_flags,
128
717
      betoh32(hdr->ike_msgid),
129
717
      betoh32(hdr->ike_length),
130
717
      msg->msg_response);
131
132
717
  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
713
  offset += sizeof(*hdr);
138
139
713
  return (ikev2_pld_payloads(env, msg, offset,
140
713
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
717
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
21.9k
{
147
21.9k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
21.9k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
21.9k
  if (left < sizeof(*pld)) {
152
66
    log_debug("%s: malformed payload: too short for generic "
153
66
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
66
    return (-1);
155
66
  }
156
21.8k
  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
21.8k
  pld_length = betoh16(pld->pld_length);
164
21.8k
  if (left < pld_length) {
165
90
    log_debug("%s: malformed payload: shorter than specified "
166
90
        "(%zu < %zu)", __func__, left, pld_length);
167
90
    return (-1);
168
90
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
21.7k
  if (pld_length < sizeof(*pld)) {
174
29
    log_debug("%s: malformed payload: shorter than minimum "
175
29
        "header size (%zu < %zu)", __func__, pld_length,
176
29
        sizeof(*pld));
177
29
    return (-1);
178
29
  }
179
180
21.7k
  return (0);
181
21.7k
}
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
713
{
187
713
  struct ikev2_payload   pld;
188
713
  unsigned int     e;
189
713
  int      ret;
190
713
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
713
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
713
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
713
  total = length - offset;
198
199
22.3k
  while (payload != 0 && offset < length) {
200
21.9k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
185
      return (-1);
202
203
21.7k
    log_debug("%s: %spayload %s"
204
21.7k
        " nextpayload %s critical 0x%02x length %d",
205
21.7k
        __func__, e ? "decrypted " : "",
206
21.7k
        print_map(payload, ikev2_payload_map),
207
21.7k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
21.7k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
21.7k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
21.7k
    offset += sizeof(pld);
213
21.7k
    total -= sizeof(pld);
214
21.7k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
21.7k
    ret = 0;
216
217
21.7k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
4.38k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
4.38k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
4.38k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
644
    case IKEV2_PAYLOAD_KE | IKED_E:
224
644
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
644
      break;
226
993
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
1.77k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
1.77k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
1.77k
          payload);
230
1.77k
      break;
231
410
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
410
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
410
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
1.77k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
1.77k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
1.77k
      break;
238
773
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
773
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
773
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
57
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
57
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
57
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
1.12k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
1.12k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
1.12k
      break;
249
812
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
812
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
812
      break;
252
351
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
1.27k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
1.27k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
1.27k
      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
1.30k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
1.30k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
1.30k
      break;
265
3.33k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
3.33k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
3.33k
      break;
268
4.09k
    default:
269
4.09k
      print_hex(msgbuf, offset,
270
4.09k
          betoh16(pld.pld_length) - sizeof(pld));
271
4.09k
      break;
272
21.7k
    }
273
274
21.7k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
70
      (void)ikev2_send_informational(env, msg);
276
70
      return (-1);
277
70
    }
278
279
    /* Encrypted payloads must appear last */
280
21.6k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
21.6k
        (payload == IKEV2_PAYLOAD_SKF))
282
2
      return (0);
283
284
21.6k
    payload = pld.pld_nextpayload;
285
21.6k
    offset += left;
286
21.6k
    total -= left;
287
21.6k
  }
288
289
456
  return (0);
290
713
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
5.47k
{
296
5.47k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
5.47k
  size_t     sap_length;
298
299
5.47k
  if (left < sizeof(*sap)) {
300
1.96k
    log_debug("%s: malformed payload: too short for header "
301
1.96k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
1.96k
    return (-1);
303
1.96k
  }
304
3.51k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
3.51k
  sap_length = betoh16(sap->sap_length);
307
3.51k
  if (sap_length < sizeof(*sap)) {
308
592
    log_debug("%s: malformed payload: shorter than minimum header "
309
592
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
592
    return (-1);
311
592
  }
312
2.92k
  if (left < sap_length) {
313
298
    log_debug("%s: malformed payload: too long for actual payload "
314
298
        "size (%zu < %zu)", __func__, left, sap_length);
315
298
    return (-1);
316
298
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
2.62k
  if (!sap->sap_more && left != sap_length) {
322
10
    log_debug("%s: malformed payload: SA payload length mismatches "
323
10
        "single proposal substructure length (%zu != %zu)",
324
10
        __func__, left, sap_length);
325
10
    return (-1);
326
10
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
2.61k
  if (sap->sap_more && left <= sap_length) {
332
66
    log_debug("%s: malformed payload: SA payload too small for "
333
66
        "further proposals (%zu <= %zu)", __func__,
334
66
        left, sap_length);
335
66
    return (-1);
336
66
  }
337
2.54k
  return (0);
338
2.61k
}
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
4.38k
{
344
4.38k
  struct ikev2_sa_proposal   sap;
345
4.38k
  struct iked_proposal    *prop = NULL;
346
4.38k
  uint32_t       spi32;
347
4.38k
  uint64_t       spi = 0, spi64;
348
4.38k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
4.38k
  int        r;
350
4.38k
  struct iked_proposals   *props;
351
4.38k
  size_t         total;
352
353
5.47k
  do {
354
5.47k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
2.92k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
2.54k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
2.54k
    props = &msg->msg_parent->msg_proposals;
361
362
2.54k
    offset += sizeof(sap);
363
2.54k
    left -= sizeof(sap);
364
365
2.54k
    if (sap.sap_spisize) {
366
381
      if (left < sap.sap_spisize) {
367
69
        log_debug("%s: malformed payload: SPI larger than "
368
69
            "actual payload (%zu < %d)", __func__, left,
369
69
            sap.sap_spisize);
370
69
        return (-1);
371
69
      }
372
312
      if (total < sap.sap_spisize) {
373
66
        log_debug("%s: malformed payload: SPI larger than "
374
66
            "proposal (%zu < %d)", __func__, total,
375
66
            sap.sap_spisize);
376
66
        return (-1);
377
66
      }
378
246
      switch (sap.sap_spisize) {
379
80
      case 4:
380
80
        memcpy(&spi32, msgbuf + offset, 4);
381
80
        spi = betoh32(spi32);
382
80
        break;
383
98
      case 8:
384
98
        memcpy(&spi64, msgbuf + offset, 8);
385
98
        spi = betoh64(spi64);
386
98
        break;
387
68
      default:
388
68
        log_debug("%s: unsupported SPI size %d",
389
68
            __func__, sap.sap_spisize);
390
68
        return (-1);
391
246
      }
392
393
178
      offset += sap.sap_spisize;
394
178
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
178
      total -= sap.sap_spisize;
398
178
    }
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
2.34k
    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
2.34k
    log_debug("%s: more %d reserved %d length %d"
411
2.34k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
2.34k
        __func__, sap.sap_more, sap.sap_reserved,
413
2.34k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
2.34k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
2.34k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
2.34k
    if (ikev2_msg_frompeer(msg)) {
418
3
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
3
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
3
        log_debug("%s: invalid proposal", __func__);
421
3
        return (-1);
422
3
      }
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
2.34k
    if (sap.sap_transforms) {
436
1.37k
      r = ikev2_pld_xform(env, msg, offset, total);
437
1.37k
      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
1.37k
      } else if (r != 0) {
445
1.05k
        log_debug("%s: invalid proposal transforms",
446
1.05k
            __func__);
447
1.05k
        return (-1);
448
1.05k
      }
449
1.37k
    }
450
451
1.28k
    offset += total;
452
1.28k
    left -= total;
453
1.28k
  } while (sap.sap_more);
454
455
190
  return (0);
456
4.38k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
1.76k
{
462
1.76k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
1.76k
  size_t     xfrm_length;
464
465
1.76k
  if (total < sizeof(*xfrm)) {
466
168
    log_debug("%s: malformed payload: too short for header "
467
168
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
168
    return (-1);
469
168
  }
470
1.59k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
1.59k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
1.59k
  if (xfrm_length < sizeof(*xfrm)) {
474
129
    log_debug("%s: malformed payload: shorter than minimum header "
475
129
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
129
    return (-1);
477
129
  }
478
1.46k
  if (total < xfrm_length) {
479
113
    log_debug("%s: malformed payload: too long for payload size "
480
113
        "(%zu < %zu)", __func__, total, xfrm_length);
481
113
    return (-1);
482
113
  }
483
484
1.35k
  return (0);
485
1.46k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
1.76k
{
491
1.76k
  struct ikev2_transform     xfrm;
492
1.76k
  char         id[BUFSIZ];
493
1.76k
  int        ret = 0;
494
1.76k
  int        r;
495
1.76k
  size_t         xfrm_length;
496
497
1.76k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
410
    return (-1);
499
500
1.35k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
1.35k
  switch (xfrm.xfrm_type) {
503
334
  case IKEV2_XFORMTYPE_ENCR:
504
334
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
334
        ikev2_xformencr_map), sizeof(id));
506
334
    break;
507
434
  case IKEV2_XFORMTYPE_PRF:
508
434
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
434
        ikev2_xformprf_map), sizeof(id));
510
434
    break;
511
67
  case IKEV2_XFORMTYPE_INTEGR:
512
67
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
67
        ikev2_xformauth_map), sizeof(id));
514
67
    break;
515
68
  case IKEV2_XFORMTYPE_DH:
516
68
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
68
        ikev2_xformdh_map), sizeof(id));
518
68
    break;
519
66
  case IKEV2_XFORMTYPE_ESN:
520
66
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
66
        ikev2_xformesn_map), sizeof(id));
522
66
    break;
523
381
  default:
524
381
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
381
    break;
526
1.35k
  }
527
528
1.35k
  log_debug("%s: more %d reserved %d length %zu"
529
1.35k
      " type %s id %s",
530
1.35k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
1.35k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
1.35k
  msg->msg_attrlength = 0;
537
1.35k
  if (xfrm_length > sizeof(xfrm)) {
538
839
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
839
        xfrm_length - sizeof(xfrm)) != 0) {
540
568
      return (-1);
541
568
    }
542
839
  }
543
544
782
  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
782
  offset += xfrm_length;
561
782
  total -= xfrm_length;
562
782
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
389
    ret = ikev2_pld_xform(env, msg, offset, total);
564
393
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
79
    log_debug("%s: less data than specified, %zu bytes left",
567
79
        __func__, total);
568
79
    ret = -1;
569
79
  }
570
571
782
  return (ret);
572
782
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
1.91k
{
578
1.91k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
1.91k
  if (total < sizeof(*attr)) {
581
104
    log_debug("%s: malformed payload: too short for header "
582
104
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
104
    return (-1);
584
104
  }
585
1.80k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
1.80k
  return (0);
588
1.91k
}
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
1.91k
{
594
1.91k
  struct ikev2_attribute     attr;
595
1.91k
  unsigned int       type;
596
1.91k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
1.91k
  int        ret = 0;
598
1.91k
  size_t         attr_length;
599
600
1.91k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
104
    return (-1);
602
603
1.80k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
1.80k
  log_debug("%s: attribute type %s length %d total %zu",
606
1.80k
      __func__, print_map(type, ikev2_attrtype_map),
607
1.80k
      betoh16(attr.attr_length), total);
608
609
1.80k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
1.07k
    offset += sizeof(attr);
612
1.07k
    total -= sizeof(attr);
613
614
1.07k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
34
      msg->msg_attrlength = betoh16(attr.attr_length);
616
1.07k
  } else {
617
    /* Type-Length-Value attribute */
618
732
    attr_length = betoh16(attr.attr_length);
619
732
    if (attr_length < sizeof(attr)) {
620
244
      log_debug("%s: malformed payload: shorter than "
621
244
          "minimum header size (%zu < %zu)", __func__,
622
244
          attr_length, sizeof(attr));
623
244
      return (-1);
624
244
    }
625
488
    if (total < attr_length) {
626
220
      log_debug("%s: malformed payload: attribute larger "
627
220
          "than actual payload (%zu < %zu)", __func__,
628
220
          total, attr_length);
629
220
      return (-1);
630
220
    }
631
268
    print_hex(msgbuf, offset + sizeof(attr),
632
268
        attr_length - sizeof(attr));
633
268
    offset += attr_length;
634
268
    total -= attr_length;
635
268
  }
636
637
1.34k
  if (total > 0) {
638
    /* Next attribute */
639
1.07k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
1.07k
  }
641
642
1.34k
  return (ret);
643
1.80k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
644
{
649
644
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
644
  if (left < sizeof(*kex)) {
652
440
    log_debug("%s: malformed payload: too short for header "
653
440
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
440
    return (-1);
655
440
  }
656
204
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
204
  return (0);
659
644
}
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
644
{
665
644
  struct ikev2_keyexchange   kex;
666
644
  uint8_t       *buf;
667
644
  size_t         len;
668
644
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
644
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
440
    return (-1);
672
673
204
  log_debug("%s: dh group %s reserved %d", __func__,
674
204
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
204
      betoh16(kex.kex_reserved));
676
677
204
  buf = msgbuf + offset + sizeof(kex);
678
204
  len = left - sizeof(kex);
679
680
204
  if (len == 0) {
681
68
    log_debug("%s: malformed payload: no KE data given", __func__);
682
68
    return (-1);
683
68
  }
684
685
136
  print_hex(buf, 0, len);
686
687
136
  if (ikev2_msg_frompeer(msg)) {
688
3
    if (msg->msg_parent->msg_ke != NULL) {
689
1
      log_info("%s: duplicate KE payload", __func__);
690
1
      return (-1);
691
1
    }
692
2
    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
2
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
2
  }
698
699
135
  return (0);
700
136
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
1.77k
{
706
1.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
1.77k
  if (left < sizeof(*id)) {
709
893
    log_debug("%s: malformed payload: too short for header "
710
893
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
893
    return (-1);
712
893
  }
713
880
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
880
  if (id->id_type == IKEV2_ID_NONE) {
716
222
    log_debug("%s: malformed payload: invalid ID type.",
717
222
        __func__);
718
222
    return (-1);
719
222
  }
720
721
658
  return (0);
722
880
}
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
1.77k
{
728
1.77k
  uint8_t       *ptr;
729
1.77k
  struct ikev2_id      id;
730
1.77k
  size_t         len;
731
1.77k
  struct iked_id      *idp, idb;
732
1.77k
  const struct iked_sa    *sa = msg->msg_sa;
733
1.77k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
1.77k
  char         idstr[IKED_ID_SIZE];
735
736
1.77k
  if (ikev2_validate_id(msg, offset, left, &id))
737
1.11k
    return (-1);
738
739
658
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
658
  ptr = msgbuf + offset;
743
658
  len = left;
744
745
658
  idb.id_type = id.id_type;
746
658
  idb.id_offset = sizeof(id);
747
658
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
658
  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
658
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
658
  if (!ikev2_msg_frompeer(msg)) {
759
648
    ibuf_free(idb.id_buf);
760
648
    return (0);
761
648
  }
762
763
10
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
10
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
6
    idp = &msg->msg_parent->msg_peerid;
766
4
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
4
    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
10
  if (idp->id_type) {
775
2
    ibuf_free(idb.id_buf);
776
2
    log_debug("%s: duplicate id payload", __func__);
777
2
    return (-1);
778
2
  }
779
780
8
  idp->id_buf = idb.id_buf;
781
8
  idp->id_offset = idb.id_offset;
782
8
  idp->id_type = idb.id_type;
783
784
8
  return (0);
785
10
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
410
{
791
410
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
410
  if (left < sizeof(*cert)) {
794
75
    log_debug("%s: malformed payload: too short for header "
795
75
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
75
    return (-1);
797
75
  }
798
335
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
335
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
24
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
24
    return (-1);
802
24
  }
803
804
311
  return (0);
805
335
}
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
410
{
811
410
  struct ikev2_cert    cert;
812
410
  uint8_t       *buf;
813
410
  size_t         len;
814
410
  struct iked_id      *certid;
815
410
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
410
  const struct iked_sa    *sa = msg->msg_sa;
817
410
  int        i;
818
819
410
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
99
    return (-1);
821
311
  offset += sizeof(cert);
822
823
311
  buf = msgbuf + offset;
824
311
  len = left - sizeof(cert);
825
826
311
  log_debug("%s: type %s length %zu",
827
311
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
311
  print_hex(buf, 0, len);
830
831
311
  if (!ikev2_msg_frompeer(msg))
832
160
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
151
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
34
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
34
       SPI_SA(sa, __func__));
838
34
    return (0);
839
34
  }
840
841
117
  certid = &msg->msg_parent->msg_cert;
842
117
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
344
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
274
      certid = &msg->msg_parent->msg_scert[i];
846
274
      if (!certid->id_type)
847
33
        break;
848
274
    }
849
103
    if (certid->id_type) {
850
70
      log_debug("%s: too many cert payloads, ignoring",
851
70
         SPI_SA(sa, __func__));
852
70
      return (0);
853
70
    }
854
103
  }
855
856
47
  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
47
  certid->id_type = cert.cert_type;
861
47
  certid->id_offset = 0;
862
863
47
  return (0);
864
47
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
1.77k
{
870
1.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
1.77k
  if (left < sizeof(*cert)) {
873
406
    log_debug("%s: malformed payload: too short for header "
874
406
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
406
    return (-1);
876
406
  }
877
1.36k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
1.36k
  return (0);
880
1.77k
}
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
1.77k
{
886
1.77k
  struct ikev2_cert    cert;
887
1.77k
  struct iked_certreq   *cr;
888
1.77k
  uint8_t       *buf;
889
1.77k
  ssize_t        len;
890
1.77k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
1.77k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
406
    return (-1);
894
1.36k
  offset += sizeof(cert);
895
896
1.36k
  buf = msgbuf + offset;
897
1.36k
  len = left - sizeof(cert);
898
899
1.36k
  log_debug("%s: type %s length %zd",
900
1.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
1.36k
  print_hex(buf, 0, len);
903
904
1.36k
  if (!ikev2_msg_frompeer(msg))
905
1.26k
    return (0);
906
907
108
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
33
    if (len == 0) {
909
22
      log_info("%s: invalid length 0", __func__);
910
22
      return (0);
911
22
    }
912
11
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
1
      log_info("%s: invalid certificate request",
914
1
          __func__);
915
1
      return (-1);
916
1
    }
917
11
  }
918
919
85
  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
85
  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
85
  cr->cr_type = cert.cert_type;
929
85
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
85
  return (0);
932
85
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
773
{
938
773
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
773
  if (left < sizeof(*auth)) {
941
130
    log_debug("%s: malformed payload: too short for header "
942
130
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
130
    return (-1);
944
130
  }
945
643
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
643
  if (auth->auth_method == 0) {
948
325
    log_info("%s: malformed payload: invalid auth method",
949
325
        __func__);
950
325
    return (-1);
951
325
  }
952
953
318
  return (0);
954
643
}
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
773
{
960
773
  struct ikev2_auth    auth;
961
773
  struct iked_id      *idp;
962
773
  uint8_t       *buf;
963
773
  size_t         len;
964
773
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
773
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
455
    return (-1);
968
318
  offset += sizeof(auth);
969
970
318
  buf = msgbuf + offset;
971
318
  len = left - sizeof(auth);
972
973
318
  log_debug("%s: method %s length %zu",
974
318
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
318
  print_hex(buf, 0, len);
977
978
318
  if (!ikev2_msg_frompeer(msg))
979
315
    return (0);
980
981
3
  idp = &msg->msg_parent->msg_auth;
982
3
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
2
  ibuf_free(idp->id_buf);
988
2
  idp->id_type = auth.auth_method;
989
2
  idp->id_offset = 0;
990
2
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
2
  return (0);
994
2
}
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
57
{
1000
57
  size_t     len;
1001
57
  uint8_t   *buf;
1002
57
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
57
  buf = msgbuf + offset;
1005
57
  len = left;
1006
1007
57
  if (len == 0) {
1008
18
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
18
    return (-1);
1010
18
  }
1011
1012
39
  print_hex(buf, 0, len);
1013
1014
39
  if (ikev2_msg_frompeer(msg)) {
1015
2
    if (msg->msg_parent->msg_nonce != NULL) {
1016
1
      log_info("%s: duplicate NONCE payload", __func__);
1017
1
      return (-1);
1018
1
    }
1019
1
    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
1
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
1
  }
1025
1026
38
  return (0);
1027
39
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
1.12k
{
1033
1.12k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
1.12k
  if (left < sizeof(*n)) {
1036
549
    log_debug("%s: malformed payload: too short for header "
1037
549
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
549
    return (-1);
1039
549
  }
1040
580
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
580
  return (0);
1043
1.12k
}
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
1.12k
{
1049
1.12k
  struct ikev2_notify  n;
1050
1.12k
  const struct iked_sa  *sa = msg->msg_sa;
1051
1.12k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
1.12k
  uint32_t     spi32;
1053
1.12k
  uint64_t     spi64;
1054
1.12k
  struct iked_spi   *rekey;
1055
1.12k
  uint16_t     type;
1056
1.12k
  uint16_t     signature_hash;
1057
1058
1.12k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
549
    return (-1);
1060
580
  type = betoh16(n.n_type);
1061
1062
580
  log_debug("%s: protoid %s spisize %d type %s",
1063
580
      __func__,
1064
580
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
580
      print_map(type, ikev2_n_map));
1066
1067
580
  left -= sizeof(n);
1068
580
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
580
  print_hex(buf, 0, left);
1072
1073
580
  if (!ikev2_msg_frompeer(msg))
1074
261
    return (0);
1075
1076
319
  switch (type) {
1077
13
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
50
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
50
    if (left != sizeof(md)) {
1080
2
      log_debug("%s: malformed payload: hash size mismatch"
1081
2
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
2
      return (-1);
1083
2
    }
1084
48
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
48
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
48
    if (memcmp(buf, md, left) != 0) {
1088
48
      log_debug("%s: %s detected NAT", __func__,
1089
48
          print_map(type, ikev2_n_map));
1090
48
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
12
        msg->msg_parent->msg_nat_detected
1092
12
            |= IKED_MSG_NAT_SRC_IP;
1093
36
      else
1094
36
        msg->msg_parent->msg_nat_detected
1095
36
            |= IKED_MSG_NAT_DST_IP;
1096
48
    }
1097
48
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
48
    msg->msg_parent->msg_natt_rcvd = 1;
1100
48
    break;
1101
1
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
1
    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
1
    if (!sa->sa_hdr.sh_initiator) {
1113
1
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
1
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
1
            " from unauthenticated initiator",
1116
1
            __func__);
1117
1
        return (-1);
1118
1
      }
1119
1
    } 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
11
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
11
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
11
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
11
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
1
      log_debug("%s: malformed payload: group size mismatch"
1139
1
          " (%zu != %zu)", __func__, left,
1140
1
          sizeof(msg->msg_parent->msg_group));
1141
1
      return (-1);
1142
1
    }
1143
10
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
10
    break;
1146
10
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
10
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
10
    break;
1154
17
  case IKEV2_N_REKEY_SA:
1155
17
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
17
    if (left != n.n_spisize) {
1160
1
      log_debug("%s: malformed notification", __func__);
1161
1
      return (-1);
1162
1
    }
1163
16
    rekey = &msg->msg_parent->msg_rekey;
1164
16
    if (rekey->spi != 0) {
1165
1
      log_debug("%s: rekeying of multiple SAs not supported",
1166
1
          __func__);
1167
1
      return (-1);
1168
1
    }
1169
15
    switch (n.n_spisize) {
1170
13
    case 4:
1171
13
      memcpy(&spi32, buf, left);
1172
13
      rekey->spi = betoh32(spi32);
1173
13
      break;
1174
1
    case 8:
1175
1
      memcpy(&spi64, buf, left);
1176
1
      rekey->spi = betoh64(spi64);
1177
1
      break;
1178
1
    default:
1179
1
      log_debug("%s: invalid spi size %d", __func__,
1180
1
          n.n_spisize);
1181
1
      return (-1);
1182
15
    }
1183
14
    rekey->spi_size = n.n_spisize;
1184
14
    rekey->spi_protoid = n.n_protoid;
1185
1186
14
    log_debug("%s: rekey %s spi %s", __func__,
1187
14
        print_map(n.n_protoid, ikev2_saproto_map),
1188
14
        print_spi(rekey->spi, n.n_spisize));
1189
14
    break;
1190
12
  case IKEV2_N_TEMPORARY_FAILURE:
1191
12
    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
12
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
12
    break;
1198
20
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
20
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
20
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
20
        sizeof(msg->msg_parent->msg_transform)) {
1206
10
      log_debug("%s: ignoring malformed ipcomp notification",
1207
10
          __func__);
1208
10
      return (0);
1209
10
    }
1210
10
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
10
        sizeof(msg->msg_parent->msg_cpi));
1212
10
    memcpy(&msg->msg_parent->msg_transform,
1213
10
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
10
        sizeof(msg->msg_parent->msg_transform));
1215
1216
10
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
10
        msg->msg_parent->msg_response ? "res" : "req",
1218
10
        betoh16(msg->msg_parent->msg_cpi),
1219
10
        print_map(msg->msg_parent->msg_transform,
1220
10
        ikev2_ipcomp_map), left);
1221
1222
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
10
    break;
1224
10
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
10
    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
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
10
    break;
1232
10
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
10
    break;
1235
28
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
28
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
28
    if (left != 0) {
1242
18
      log_debug("%s: ignoring malformed mobike"
1243
18
          " notification: %zu", __func__, left);
1244
18
      return (0);
1245
18
    }
1246
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
10
    break;
1248
28
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
28
    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
28
    if (left != 0) {
1255
10
      log_debug("%s: ignoring malformed transport mode"
1256
10
          " notification: %zu", __func__, left);
1257
10
      return (0);
1258
10
    }
1259
18
    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
18
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
18
    break;
1268
18
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
18
    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
18
    if (!sa->sa_mobike) {
1275
18
      log_debug("%s: ignoring update sa addresses"
1276
18
          " notification w/o mobike: %zu", __func__, left);
1277
18
      return (0);
1278
18
    }
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
34
  case IKEV2_N_COOKIE2:
1287
34
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
34
    if (!sa->sa_mobike) {
1293
34
      log_debug("%s: ignoring cookie2 notification"
1294
34
          " w/o mobike: %zu", __func__, left);
1295
34
      return (0);
1296
34
    }
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
1
  case IKEV2_N_COOKIE:
1310
1
    if (msg->msg_e) {
1311
1
      log_debug("%s: N_COOKIE encrypted",
1312
1
          __func__);
1313
1
      return (-1);
1314
1
    }
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
1
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
1
    if (msg->msg_e) {
1332
1
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
1
          __func__);
1334
1
      return (-1);
1335
1
    }
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
1
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
1
    if (msg->msg_e) {
1345
1
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
1
          __func__);
1347
1
      return (-1);
1348
1
    }
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
319
  }
1379
1380
219
  return (0);
1381
319
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
812
{
1387
812
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
812
  if (left < sizeof(*del)) {
1390
110
    log_debug("%s: malformed payload: too short for header "
1391
110
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
110
    return (-1);
1393
110
  }
1394
702
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
702
  if (del->del_protoid == 0) {
1397
22
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
22
    return (-1);
1399
22
  }
1400
1401
680
  return (0);
1402
702
}
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
812
{
1408
812
  struct ikev2_delete  del;
1409
812
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
812
  size_t       cnt, sz, len;
1411
1412
812
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
132
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
680
  if (ikev2_msg_frompeer(msg) &&
1417
680
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
680
  cnt = betoh16(del.del_nspi);
1421
680
  sz = del.del_spisize;
1422
1423
680
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
680
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
680
      sz, cnt);
1426
1427
680
  if (msg->msg_parent->msg_del_protoid) {
1428
638
    log_debug("%s: duplicate delete payload", __func__);
1429
638
    return (0);
1430
638
  }
1431
1432
42
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
42
  msg->msg_parent->msg_del_cnt = cnt;
1434
42
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
42
  buf = msgbuf + offset + sizeof(del);
1437
42
  len = left - sizeof(del);
1438
42
  if (len == 0 || sz == 0 || cnt == 0)
1439
34
    return (0);
1440
1441
8
  if ((len / sz) != cnt) {
1442
7
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
7
        __func__, len, sz, cnt);
1444
7
    return (-1);
1445
7
  }
1446
1447
1
  print_hex(buf, 0, len);
1448
1449
1
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
1
  return (0);
1452
8
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
1.27k
{
1458
1.27k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
1.27k
  if (left < sizeof(*tsp)) {
1461
146
    log_debug("%s: malformed payload: too short for header "
1462
146
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
146
    return (-1);
1464
146
  }
1465
1.12k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
1.12k
  return (0);
1468
1.27k
}
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
1.27k
{
1474
1.27k
  struct ikev2_tsp     tsp;
1475
1.27k
  struct ikev2_ts      ts;
1476
1.27k
  size_t         ts_len, i;
1477
1478
1.27k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
146
    return (-1);
1480
1481
1.12k
  offset += sizeof(tsp);
1482
1.12k
  left -= sizeof(tsp);
1483
1484
1.12k
  log_debug("%s: count %d length %zu", __func__,
1485
1.12k
      tsp.tsp_count, left);
1486
1487
1.88k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
1.79k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
898
      return (-1);
1490
1491
895
    log_debug("%s: type %s protoid %u length %d "
1492
895
        "startport %u endport %u", __func__,
1493
895
        print_map(ts.ts_type, ikev2_ts_map),
1494
895
        ts.ts_protoid, betoh16(ts.ts_length),
1495
895
        betoh16(ts.ts_startport),
1496
895
        betoh16(ts.ts_endport));
1497
1498
895
    offset += sizeof(ts);
1499
895
    left -= sizeof(ts);
1500
1501
895
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
895
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
137
      return (-1);
1504
1505
758
    offset += ts_len;
1506
758
    left -= ts_len;
1507
758
  }
1508
1509
90
  return (0);
1510
1.12k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
1.79k
{
1516
1.79k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
1.79k
  size_t     ts_length;
1518
1519
1.79k
  if (left < sizeof(*ts)) {
1520
793
    log_debug("%s: malformed payload: too short for header "
1521
793
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
793
    return (-1);
1523
793
  }
1524
1.00k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
1.00k
  ts_length = betoh16(ts->ts_length);
1527
1.00k
  if (ts_length < sizeof(*ts)) {
1528
40
    log_debug("%s: malformed payload: shorter than minimum header "
1529
40
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
40
    return (-1);
1531
40
  }
1532
960
  if (left < ts_length) {
1533
65
    log_debug("%s: malformed payload: too long for payload size "
1534
65
        "(%zu < %zu)", __func__, left, ts_length);
1535
65
    return (-1);
1536
65
  }
1537
1538
895
  return (0);
1539
960
}
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
895
{
1545
895
  struct sockaddr_in     start4, end4;
1546
895
  struct sockaddr_in6    start6, end6;
1547
895
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
895
  uint8_t       *ptr;
1549
1550
895
  ptr = msgbuf + offset;
1551
1552
895
  switch (type) {
1553
242
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
242
    if (left < 2 * 4) {
1555
34
      log_debug("%s: malformed payload: too short "
1556
34
          "for ipv4 addr range (%zu < %u)",
1557
34
          __func__, left, 2 * 4);
1558
34
      return (-1);
1559
34
    }
1560
1561
208
    bzero(&start4, sizeof(start4));
1562
208
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
208
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
208
    ptr += 4;
1568
208
    left -= 4;
1569
1570
208
    bzero(&end4, sizeof(end4));
1571
208
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
208
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
208
    left -= 4;
1577
1578
208
    log_debug("%s: start %s end %s", __func__,
1579
208
        print_addr(&start4), print_addr(&end4));
1580
208
    break;
1581
93
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
93
    if (left < 2 * 16) {
1583
34
      log_debug("%s: malformed payload: too short "
1584
34
          "for ipv6 addr range (%zu < %u)",
1585
34
          __func__, left, 2 * 16);
1586
34
      return (-1);
1587
34
    }
1588
59
    bzero(&start6, sizeof(start6));
1589
59
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
59
    memcpy(&start6.sin6_addr, ptr, 16);
1594
59
    ptr += 16;
1595
59
    left -= 16;
1596
1597
59
    bzero(&end6, sizeof(end6));
1598
59
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
59
    memcpy(&end6.sin6_addr, ptr, 16);
1603
59
    left -= 16;
1604
1605
59
    log_debug("%s: start %s end %s", __func__,
1606
59
        print_addr(&start6), print_addr(&end6));
1607
59
    break;
1608
560
  default:
1609
560
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
560
    return (0);
1611
895
  }
1612
1613
267
  if (left > 0) {
1614
69
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
69
        __func__, left);
1616
69
    return (-1);
1617
69
  }
1618
1619
198
  return (0);
1620
267
}
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
1.30k
{
1876
1.30k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
1.30k
  if (left < sizeof(*cp)) {
1879
236
    log_debug("%s: malformed payload: too short for header "
1880
236
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
236
    return (-1);
1882
236
  }
1883
1.06k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
1.06k
  return (0);
1886
1.30k
}
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
1.30k
{
1892
1.30k
  struct ikev2_cp    cp;
1893
1.30k
  struct ikev2_cfg  *cfg;
1894
1.30k
  struct iked_addr  *addr;
1895
1.30k
  struct sockaddr_in  *in4;
1896
1.30k
  struct sockaddr_in6 *in6;
1897
1.30k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
1.30k
  uint8_t     *ptr;
1899
1.30k
  size_t       len;
1900
1.30k
  int      cfg_type;
1901
1902
1.30k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
236
    return (-1);
1904
1905
1.06k
  ptr = msgbuf + offset + sizeof(cp);
1906
1.06k
  len = left - sizeof(cp);
1907
1908
1.06k
  log_debug("%s: type %s length %zu",
1909
1.06k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
1.06k
  print_hex(ptr, 0, len);
1911
1912
2.18k
  while (len > 0) {
1913
1.34k
    if (len < sizeof(*cfg)) {
1914
102
      log_debug("%s: malformed payload: too short for cfg "
1915
102
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
102
      return (-1);
1917
102
    }
1918
1.23k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
1.23k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
1.23k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
1.23k
        betoh16(cfg->cfg_type),
1923
1.23k
        betoh16(cfg->cfg_length));
1924
1925
1.23k
    ptr += sizeof(*cfg);
1926
1.23k
    len -= sizeof(*cfg);
1927
1928
1.23k
    if (len < betoh16(cfg->cfg_length)) {
1929
121
      log_debug("%s: malformed payload: too short for "
1930
121
          "cfg_length (%zu < %u)", __func__, len,
1931
121
          betoh16(cfg->cfg_length));
1932
121
      return (-1);
1933
121
    }
1934
1935
1.11k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
1.11k
    cfg_type = betoh16(cfg->cfg_type);
1938
1.11k
    switch (cfg_type) {
1939
149
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
253
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
253
      if (!ikev2_msg_frompeer(msg))
1942
121
        break;
1943
132
      if (betoh16(cfg->cfg_length) == 0)
1944
78
        break;
1945
      /* XXX multiple-valued */
1946
54
      if (betoh16(cfg->cfg_length) < 4) {
1947
1
        log_debug("%s: malformed payload: too short "
1948
1
            "for ipv4 addr (%u < %u)",
1949
1
            __func__, betoh16(cfg->cfg_length), 4);
1950
1
        return (-1);
1951
1
      }
1952
53
      switch(cfg_type) {
1953
34
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
34
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
21
          log_debug("%s: address already set", __func__);
1956
21
          goto skip;
1957
21
        }
1958
13
        break;
1959
19
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
19
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
10
          log_debug("%s: dns already set", __func__);
1962
10
          goto skip;
1963
10
        }
1964
9
        break;
1965
9
      default:
1966
0
        break;
1967
53
      }
1968
22
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
22
      addr->addr_af = AF_INET;
1973
22
      in4 = (struct sockaddr_in *)&addr->addr;
1974
22
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
22
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
22
      switch(cfg_type) {
1980
13
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
13
        msg->msg_parent->msg_cp_addr = addr;
1982
13
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
13
            print_addr(&addr->addr));
1984
13
        break;
1985
9
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
9
        msg->msg_parent->msg_cp_dns = addr;
1987
9
        log_debug("%s: IP4_DNS %s", __func__,
1988
9
            print_addr(&addr->addr));
1989
9
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
22
      }
1995
22
      break;
1996
196
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
289
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
289
      if (!ikev2_msg_frompeer(msg))
1999
233
        break;
2000
56
      if (betoh16(cfg->cfg_length) == 0)
2001
29
        break;
2002
      /* XXX multiple-valued */
2003
27
      if (betoh16(cfg->cfg_length) < 16) {
2004
1
        log_debug("%s: malformed payload: too short "
2005
1
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
1
            __func__, betoh16(cfg->cfg_length), 16);
2007
1
        return (-1);
2008
1
      }
2009
26
      switch(cfg_type) {
2010
15
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
15
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
10
          log_debug("%s: address6 already set", __func__);
2013
10
          goto skip;
2014
10
        }
2015
5
        break;
2016
11
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
11
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
10
          log_debug("%s: dns already set", __func__);
2019
10
          goto skip;
2020
10
        }
2021
1
        break;
2022
26
      }
2023
6
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
6
      addr->addr_af = AF_INET6;
2028
6
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
6
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
6
      memcpy(&in6->sin6_addr, ptr, 16);
2034
6
      switch(cfg_type) {
2035
5
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
5
        msg->msg_parent->msg_cp_addr6 = addr;
2037
5
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
5
            print_addr(&addr->addr));
2039
5
        break;
2040
1
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
1
        msg->msg_parent->msg_cp_dns = addr;
2042
1
        log_debug("%s: IP6_DNS %s", __func__,
2043
1
            print_addr(&addr->addr));
2044
1
        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
6
      }
2050
6
      break;
2051
1.11k
    }
2052
2053
1.11k
 skip:
2054
1.11k
    ptr += betoh16(cfg->cfg_length);
2055
1.11k
    len -= betoh16(cfg->cfg_length);
2056
1.11k
  }
2057
2058
842
  if (!ikev2_msg_frompeer(msg))
2059
792
    return (0);
2060
2061
50
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
50
  return (0);
2064
842
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
3.33k
{
2070
3.33k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
3.33k
  if (left < sizeof(*hdr)) {
2073
1.26k
    log_debug("%s: malformed payload: too short for header "
2074
1.26k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
1.26k
    return (-1);
2076
1.26k
  }
2077
2.07k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
2.07k
  return (0);
2080
3.33k
}
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
3.33k
{
2086
3.33k
  struct eap_header    hdr;
2087
3.33k
  struct eap_message    *eap = NULL;
2088
3.33k
  const struct iked_sa    *sa = msg->msg_sa;
2089
3.33k
  size_t         len;
2090
2091
3.33k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
1.26k
    return (-1);
2093
2.07k
  len = betoh16(hdr.eap_length);
2094
2095
2.07k
  if (len < sizeof(*eap)) {
2096
861
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
861
        print_map(hdr.eap_code, eap_code_map),
2098
861
        hdr.eap_id, betoh16(hdr.eap_length));
2099
1.21k
  } else {
2100
    /* Now try to get the indicated length */
2101
1.21k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
477
      log_debug("%s: invalid EAP length", __func__);
2103
477
      return (-1);
2104
477
    }
2105
2106
737
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
737
        print_map(eap->eap_code, eap_code_map),
2108
737
        eap->eap_id, betoh16(eap->eap_length),
2109
737
        print_map(eap->eap_type, eap_type_map));
2110
2111
737
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
737
    msg->msg_parent->msg_eap.eam_found = 1;
2114
737
  }
2115
2116
1.59k
  return (0);
2117
2.07k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
10.0k
{
119
10.0k
  log_debug("%s: header ispi %s rspi %s"
120
10.0k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
10.0k
      " msgid %d length %u response %d", __func__,
122
10.0k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
10.0k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
10.0k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
10.0k
      hdr->ike_version,
126
10.0k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
10.0k
      hdr->ike_flags,
128
10.0k
      betoh32(hdr->ike_msgid),
129
10.0k
      betoh32(hdr->ike_length),
130
10.0k
      msg->msg_response);
131
132
10.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
10.0k
  offset += sizeof(*hdr);
138
139
10.0k
  return (ikev2_pld_payloads(env, msg, offset,
140
10.0k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
10.0k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
202k
{
147
202k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
202k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
202k
  if (left < sizeof(*pld)) {
152
1.45k
    log_debug("%s: malformed payload: too short for generic "
153
1.45k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.45k
    return (-1);
155
1.45k
  }
156
201k
  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
201k
  pld_length = betoh16(pld->pld_length);
164
201k
  if (left < pld_length) {
165
4.27k
    log_debug("%s: malformed payload: shorter than specified "
166
4.27k
        "(%zu < %zu)", __func__, left, pld_length);
167
4.27k
    return (-1);
168
4.27k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
197k
  if (pld_length < sizeof(*pld)) {
174
1.66k
    log_debug("%s: malformed payload: shorter than minimum "
175
1.66k
        "header size (%zu < %zu)", __func__, pld_length,
176
1.66k
        sizeof(*pld));
177
1.66k
    return (-1);
178
1.66k
  }
179
180
195k
  return (0);
181
197k
}
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
10.0k
{
187
10.0k
  struct ikev2_payload   pld;
188
10.0k
  unsigned int     e;
189
10.0k
  int      ret;
190
10.0k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
10.0k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
10.0k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
10.0k
  total = length - offset;
198
199
204k
  while (payload != 0 && offset < length) {
200
202k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
7.39k
      return (-1);
202
203
195k
    log_debug("%s: %spayload %s"
204
195k
        " nextpayload %s critical 0x%02x length %d",
205
195k
        __func__, e ? "decrypted " : "",
206
195k
        print_map(payload, ikev2_payload_map),
207
195k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
195k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
195k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
195k
    offset += sizeof(pld);
213
195k
    total -= sizeof(pld);
214
195k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
195k
    ret = 0;
216
217
195k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
27.1k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
27.1k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
27.1k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
5.93k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
5.93k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
5.93k
      break;
226
12.6k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
18.5k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
18.5k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
18.5k
          payload);
230
18.5k
      break;
231
5.21k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.21k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.21k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
10.2k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
10.2k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
10.2k
      break;
238
7.98k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
7.98k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
7.98k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
229
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
229
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
229
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
24.5k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
24.5k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
24.5k
      break;
249
6.99k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
6.99k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
6.99k
      break;
252
4.44k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
16.3k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
16.3k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
16.3k
      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
8.50k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
8.50k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
8.50k
      break;
265
16.1k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
16.1k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
16.1k
      break;
268
47.8k
    default:
269
47.8k
      print_hex(msgbuf, offset,
270
47.8k
          betoh16(pld.pld_length) - sizeof(pld));
271
47.8k
      break;
272
195k
    }
273
274
195k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
706
      (void)ikev2_send_informational(env, msg);
276
706
      return (-1);
277
706
    }
278
279
    /* Encrypted payloads must appear last */
280
194k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
194k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
194k
    payload = pld.pld_nextpayload;
285
194k
    offset += left;
286
194k
    total -= left;
287
194k
  }
288
289
1.95k
  return (0);
290
10.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
31.4k
{
296
31.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
31.4k
  size_t     sap_length;
298
299
31.4k
  if (left < sizeof(*sap)) {
300
13.3k
    log_debug("%s: malformed payload: too short for header "
301
13.3k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.3k
    return (-1);
303
13.3k
  }
304
18.0k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.0k
  sap_length = betoh16(sap->sap_length);
307
18.0k
  if (sap_length < sizeof(*sap)) {
308
4.88k
    log_debug("%s: malformed payload: shorter than minimum header "
309
4.88k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
4.88k
    return (-1);
311
4.88k
  }
312
13.1k
  if (left < sap_length) {
313
2.19k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.19k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.19k
    return (-1);
316
2.19k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
10.9k
  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
10.9k
  if (sap->sap_more && left <= sap_length) {
332
828
    log_debug("%s: malformed payload: SA payload too small for "
333
828
        "further proposals (%zu <= %zu)", __func__,
334
828
        left, sap_length);
335
828
    return (-1);
336
828
  }
337
10.0k
  return (0);
338
10.9k
}
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
27.1k
{
344
27.1k
  struct ikev2_sa_proposal   sap;
345
27.1k
  struct iked_proposal    *prop = NULL;
346
27.1k
  uint32_t       spi32;
347
27.1k
  uint64_t       spi = 0, spi64;
348
27.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
27.1k
  int        r;
350
27.1k
  struct iked_proposals   *props;
351
27.1k
  size_t         total;
352
353
31.4k
  do {
354
31.4k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
21.3k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.0k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.0k
    props = &msg->msg_parent->msg_proposals;
361
362
10.0k
    offset += sizeof(sap);
363
10.0k
    left -= sizeof(sap);
364
365
10.0k
    if (sap.sap_spisize) {
366
1.38k
      if (left < sap.sap_spisize) {
367
634
        log_debug("%s: malformed payload: SPI larger than "
368
634
            "actual payload (%zu < %d)", __func__, left,
369
634
            sap.sap_spisize);
370
634
        return (-1);
371
634
      }
372
748
      if (total < sap.sap_spisize) {
373
132
        log_debug("%s: malformed payload: SPI larger than "
374
132
            "proposal (%zu < %d)", __func__, total,
375
132
            sap.sap_spisize);
376
132
        return (-1);
377
132
      }
378
616
      switch (sap.sap_spisize) {
379
286
      case 4:
380
286
        memcpy(&spi32, msgbuf + offset, 4);
381
286
        spi = betoh32(spi32);
382
286
        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
616
      }
392
393
486
      offset += sap.sap_spisize;
394
486
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
486
      total -= sap.sap_spisize;
398
486
    }
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.18k
    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.18k
    log_debug("%s: more %d reserved %d length %d"
411
9.18k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.18k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.18k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.18k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.18k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.18k
    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.11k
    if (sap.sap_transforms) {
436
5.13k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.13k
      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.13k
      } else if (r != 0) {
445
4.07k
        log_debug("%s: invalid proposal transforms",
446
4.07k
            __func__);
447
4.07k
        return (-1);
448
4.07k
      }
449
5.13k
    }
450
451
5.03k
    offset += total;
452
5.03k
    left -= total;
453
5.03k
  } while (sap.sap_more);
454
455
733
  return (0);
456
27.1k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
6.66k
{
462
6.66k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
6.66k
  size_t     xfrm_length;
464
465
6.66k
  if (total < sizeof(*xfrm)) {
466
551
    log_debug("%s: malformed payload: too short for header "
467
551
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
551
    return (-1);
469
551
  }
470
6.11k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.11k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.11k
  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
4.99k
  if (total < xfrm_length) {
479
599
    log_debug("%s: malformed payload: too long for payload size "
480
599
        "(%zu < %zu)", __func__, total, xfrm_length);
481
599
    return (-1);
482
599
  }
483
484
4.39k
  return (0);
485
4.99k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
6.66k
{
491
6.66k
  struct ikev2_transform     xfrm;
492
6.66k
  char         id[BUFSIZ];
493
6.66k
  int        ret = 0;
494
6.66k
  int        r;
495
6.66k
  size_t         xfrm_length;
496
497
6.66k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.27k
    return (-1);
499
500
4.39k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.39k
  switch (xfrm.xfrm_type) {
503
1.05k
  case IKEV2_XFORMTYPE_ENCR:
504
1.05k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.05k
        ikev2_xformencr_map), sizeof(id));
506
1.05k
    break;
507
765
  case IKEV2_XFORMTYPE_PRF:
508
765
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
765
        ikev2_xformprf_map), sizeof(id));
510
765
    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
247
  case IKEV2_XFORMTYPE_DH:
516
247
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
247
        ikev2_xformdh_map), sizeof(id));
518
247
    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.16k
  default:
524
1.16k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.16k
    break;
526
4.39k
  }
527
528
4.39k
  log_debug("%s: more %d reserved %d length %zu"
529
4.39k
      " type %s id %s",
530
4.39k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.39k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.39k
  msg->msg_attrlength = 0;
537
4.39k
  if (xfrm_length > sizeof(xfrm)) {
538
2.18k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.18k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.65k
      return (-1);
541
1.65k
    }
542
2.18k
  }
543
544
2.73k
  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
2.73k
  offset += xfrm_length;
561
2.73k
  total -= xfrm_length;
562
2.73k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.53k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.20k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
146
    log_debug("%s: less data than specified, %zu bytes left",
567
146
        __func__, total);
568
146
    ret = -1;
569
146
  }
570
571
2.73k
  return (ret);
572
2.73k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
28.9k
{
578
28.9k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
28.9k
  if (total < sizeof(*attr)) {
581
708
    log_debug("%s: malformed payload: too short for header "
582
708
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
708
    return (-1);
584
708
  }
585
28.2k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.2k
  return (0);
588
28.9k
}
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
28.9k
{
594
28.9k
  struct ikev2_attribute     attr;
595
28.9k
  unsigned int       type;
596
28.9k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
28.9k
  int        ret = 0;
598
28.9k
  size_t         attr_length;
599
600
28.9k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
708
    return (-1);
602
603
28.2k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.2k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.2k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.2k
      betoh16(attr.attr_length), total);
608
609
28.2k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
21.9k
    offset += sizeof(attr);
612
21.9k
    total -= sizeof(attr);
613
614
21.9k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
45
      msg->msg_attrlength = betoh16(attr.attr_length);
616
21.9k
  } else {
617
    /* Type-Length-Value attribute */
618
6.31k
    attr_length = betoh16(attr.attr_length);
619
6.31k
    if (attr_length < sizeof(attr)) {
620
526
      log_debug("%s: malformed payload: shorter than "
621
526
          "minimum header size (%zu < %zu)", __func__,
622
526
          attr_length, sizeof(attr));
623
526
      return (-1);
624
526
    }
625
5.78k
    if (total < attr_length) {
626
422
      log_debug("%s: malformed payload: attribute larger "
627
422
          "than actual payload (%zu < %zu)", __func__,
628
422
          total, attr_length);
629
422
      return (-1);
630
422
    }
631
5.36k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.36k
        attr_length - sizeof(attr));
633
5.36k
    offset += attr_length;
634
5.36k
    total -= attr_length;
635
5.36k
  }
636
637
27.3k
  if (total > 0) {
638
    /* Next attribute */
639
26.7k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
26.7k
  }
641
642
27.3k
  return (ret);
643
28.2k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
5.93k
{
649
5.93k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
5.93k
  if (left < sizeof(*kex)) {
652
3.70k
    log_debug("%s: malformed payload: too short for header "
653
3.70k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
3.70k
    return (-1);
655
3.70k
  }
656
2.22k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
2.22k
  return (0);
659
5.93k
}
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
5.93k
{
665
5.93k
  struct ikev2_keyexchange   kex;
666
5.93k
  uint8_t       *buf;
667
5.93k
  size_t         len;
668
5.93k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
5.93k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
3.70k
    return (-1);
672
673
2.22k
  log_debug("%s: dh group %s reserved %d", __func__,
674
2.22k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
2.22k
      betoh16(kex.kex_reserved));
676
677
2.22k
  buf = msgbuf + offset + sizeof(kex);
678
2.22k
  len = left - sizeof(kex);
679
680
2.22k
  if (len == 0) {
681
651
    log_debug("%s: malformed payload: no KE data given", __func__);
682
651
    return (-1);
683
651
  }
684
685
1.57k
  print_hex(buf, 0, len);
686
687
1.57k
  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.57k
  return (0);
700
1.57k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
18.5k
{
706
18.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
18.5k
  if (left < sizeof(*id)) {
709
7.36k
    log_debug("%s: malformed payload: too short for header "
710
7.36k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.36k
    return (-1);
712
7.36k
  }
713
11.1k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.1k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.41k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.41k
        __func__);
718
6.41k
    return (-1);
719
6.41k
  }
720
721
4.75k
  return (0);
722
11.1k
}
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
18.5k
{
728
18.5k
  uint8_t       *ptr;
729
18.5k
  struct ikev2_id      id;
730
18.5k
  size_t         len;
731
18.5k
  struct iked_id      *idp, idb;
732
18.5k
  const struct iked_sa    *sa = msg->msg_sa;
733
18.5k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
18.5k
  char         idstr[IKED_ID_SIZE];
735
736
18.5k
  if (ikev2_validate_id(msg, offset, left, &id))
737
13.7k
    return (-1);
738
739
4.75k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
4.75k
  ptr = msgbuf + offset;
743
4.75k
  len = left;
744
745
4.75k
  idb.id_type = id.id_type;
746
4.75k
  idb.id_offset = sizeof(id);
747
4.75k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
4.75k
  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
4.75k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
4.75k
  if (!ikev2_msg_frompeer(msg)) {
759
4.65k
    ibuf_free(idb.id_buf);
760
4.65k
    return (0);
761
4.65k
  }
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.21k
{
791
5.21k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.21k
  if (left < sizeof(*cert)) {
794
1.14k
    log_debug("%s: malformed payload: too short for header "
795
1.14k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.14k
    return (-1);
797
1.14k
  }
798
4.07k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.07k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
912
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
912
    return (-1);
802
912
  }
803
804
3.15k
  return (0);
805
4.07k
}
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.21k
{
811
5.21k
  struct ikev2_cert    cert;
812
5.21k
  uint8_t       *buf;
813
5.21k
  size_t         len;
814
5.21k
  struct iked_id      *certid;
815
5.21k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.21k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.21k
  int        i;
818
819
5.21k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.05k
    return (-1);
821
3.15k
  offset += sizeof(cert);
822
823
3.15k
  buf = msgbuf + offset;
824
3.15k
  len = left - sizeof(cert);
825
826
3.15k
  log_debug("%s: type %s length %zu",
827
3.15k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.15k
  print_hex(buf, 0, len);
830
831
3.15k
  if (!ikev2_msg_frompeer(msg))
832
1.37k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.78k
  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.49k
  certid = &msg->msg_parent->msg_cert;
842
1.49k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
3.63k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
2.97k
      certid = &msg->msg_parent->msg_scert[i];
846
2.97k
      if (!certid->id_type)
847
542
        break;
848
2.97k
    }
849
1.20k
    if (certid->id_type) {
850
663
      log_debug("%s: too many cert payloads, ignoring",
851
663
         SPI_SA(sa, __func__));
852
663
      return (0);
853
663
    }
854
1.20k
  }
855
856
827
  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
827
  certid->id_type = cert.cert_type;
861
827
  certid->id_offset = 0;
862
863
827
  return (0);
864
827
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
10.2k
{
870
10.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
10.2k
  if (left < sizeof(*cert)) {
873
2.14k
    log_debug("%s: malformed payload: too short for header "
874
2.14k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.14k
    return (-1);
876
2.14k
  }
877
8.07k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
8.07k
  return (0);
880
10.2k
}
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
10.2k
{
886
10.2k
  struct ikev2_cert    cert;
887
10.2k
  struct iked_certreq   *cr;
888
10.2k
  uint8_t       *buf;
889
10.2k
  ssize_t        len;
890
10.2k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
10.2k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.14k
    return (-1);
894
8.07k
  offset += sizeof(cert);
895
896
8.07k
  buf = msgbuf + offset;
897
8.07k
  len = left - sizeof(cert);
898
899
8.07k
  log_debug("%s: type %s length %zd",
900
8.07k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
8.07k
  print_hex(buf, 0, len);
903
904
8.07k
  if (!ikev2_msg_frompeer(msg))
905
7.26k
    return (0);
906
907
812
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
319
    if (len == 0) {
909
277
      log_info("%s: invalid length 0", __func__);
910
277
      return (0);
911
277
    }
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
526
  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
526
  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
526
  cr->cr_type = cert.cert_type;
929
526
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
526
  return (0);
932
526
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
7.98k
{
938
7.98k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
7.98k
  if (left < sizeof(*auth)) {
941
1.82k
    log_debug("%s: malformed payload: too short for header "
942
1.82k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.82k
    return (-1);
944
1.82k
  }
945
6.16k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.16k
  if (auth->auth_method == 0) {
948
3.34k
    log_info("%s: malformed payload: invalid auth method",
949
3.34k
        __func__);
950
3.34k
    return (-1);
951
3.34k
  }
952
953
2.82k
  return (0);
954
6.16k
}
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
7.98k
{
960
7.98k
  struct ikev2_auth    auth;
961
7.98k
  struct iked_id      *idp;
962
7.98k
  uint8_t       *buf;
963
7.98k
  size_t         len;
964
7.98k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
7.98k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.16k
    return (-1);
968
2.82k
  offset += sizeof(auth);
969
970
2.82k
  buf = msgbuf + offset;
971
2.82k
  len = left - sizeof(auth);
972
973
2.82k
  log_debug("%s: method %s length %zu",
974
2.82k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.82k
  print_hex(buf, 0, len);
977
978
2.82k
  if (!ikev2_msg_frompeer(msg))
979
2.77k
    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
229
{
1000
229
  size_t     len;
1001
229
  uint8_t   *buf;
1002
229
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
229
  buf = msgbuf + offset;
1005
229
  len = left;
1006
1007
229
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
147
  print_hex(buf, 0, len);
1013
1014
147
  if (ikev2_msg_frompeer(msg)) {
1015
58
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
39
    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
39
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
39
  }
1025
1026
128
  return (0);
1027
147
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
24.5k
{
1033
24.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
24.5k
  if (left < sizeof(*n)) {
1036
3.14k
    log_debug("%s: malformed payload: too short for header "
1037
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.14k
    return (-1);
1039
3.14k
  }
1040
21.4k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
21.4k
  return (0);
1043
24.5k
}
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
24.5k
{
1049
24.5k
  struct ikev2_notify  n;
1050
24.5k
  const struct iked_sa  *sa = msg->msg_sa;
1051
24.5k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
24.5k
  uint32_t     spi32;
1053
24.5k
  uint64_t     spi64;
1054
24.5k
  struct iked_spi   *rekey;
1055
24.5k
  uint16_t     type;
1056
24.5k
  uint16_t     signature_hash;
1057
1058
24.5k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.14k
    return (-1);
1060
21.4k
  type = betoh16(n.n_type);
1061
1062
21.4k
  log_debug("%s: protoid %s spisize %d type %s",
1063
21.4k
      __func__,
1064
21.4k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
21.4k
      print_map(type, ikev2_n_map));
1066
1067
21.4k
  left -= sizeof(n);
1068
21.4k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
21.4k
  print_hex(buf, 0, left);
1072
1073
21.4k
  if (!ikev2_msg_frompeer(msg))
1074
1.36k
    return (0);
1075
1076
20.0k
  switch (type) {
1077
2.47k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
15.9k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
15.9k
    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
15.9k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
15.9k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
15.9k
    if (memcmp(buf, md, left) != 0) {
1088
15.9k
      log_debug("%s: %s detected NAT", __func__,
1089
15.9k
          print_map(type, ikev2_n_map));
1090
15.9k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
2.47k
        msg->msg_parent->msg_nat_detected
1092
2.47k
            |= IKED_MSG_NAT_SRC_IP;
1093
13.5k
      else
1094
13.5k
        msg->msg_parent->msg_nat_detected
1095
13.5k
            |= IKED_MSG_NAT_DST_IP;
1096
15.9k
    }
1097
15.9k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
15.9k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
15.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
233
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
233
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
233
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
233
    break;
1154
64
  case IKEV2_N_REKEY_SA:
1155
64
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
64
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
59
    rekey = &msg->msg_parent->msg_rekey;
1164
59
    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
54
    switch (n.n_spisize) {
1170
48
    case 4:
1171
48
      memcpy(&spi32, buf, left);
1172
48
      rekey->spi = betoh32(spi32);
1173
48
      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
54
    }
1183
51
    rekey->spi_size = n.n_spisize;
1184
51
    rekey->spi_protoid = n.n_protoid;
1185
1186
51
    log_debug("%s: rekey %s spi %s", __func__,
1187
51
        print_map(n.n_protoid, ikev2_saproto_map),
1188
51
        print_spi(rekey->spi, n.n_spisize));
1189
51
    break;
1190
341
  case IKEV2_N_TEMPORARY_FAILURE:
1191
341
    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
341
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
341
    break;
1198
249
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
249
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
249
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
249
        sizeof(msg->msg_parent->msg_transform)) {
1206
121
      log_debug("%s: ignoring malformed ipcomp notification",
1207
121
          __func__);
1208
121
      return (0);
1209
121
    }
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
263
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
263
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
263
    if (left != 0) {
1242
130
      log_debug("%s: ignoring malformed mobike"
1243
130
          " notification: %zu", __func__, left);
1244
130
      return (0);
1245
130
    }
1246
133
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
133
    break;
1248
301
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
301
    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
301
    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
224
    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
224
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
224
    break;
1268
344
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
344
    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
344
    if (!sa->sa_mobike) {
1275
344
      log_debug("%s: ignoring update sa addresses"
1276
344
          " notification w/o mobike: %zu", __func__, left);
1277
344
      return (0);
1278
344
    }
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
201
  case IKEV2_N_COOKIE2:
1287
201
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
201
    if (!sa->sa_mobike) {
1293
201
      log_debug("%s: ignoring cookie2 notification"
1294
201
          " w/o mobike: %zu", __func__, left);
1295
201
      return (0);
1296
201
    }
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
20.0k
  }
1379
1380
19.1k
  return (0);
1381
20.0k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
6.99k
{
1387
6.99k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
6.99k
  if (left < sizeof(*del)) {
1390
1.33k
    log_debug("%s: malformed payload: too short for header "
1391
1.33k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.33k
    return (-1);
1393
1.33k
  }
1394
5.66k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.66k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.58k
  return (0);
1402
5.66k
}
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
6.99k
{
1408
6.99k
  struct ikev2_delete  del;
1409
6.99k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
6.99k
  size_t       cnt, sz, len;
1411
1412
6.99k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.41k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.58k
  if (ikev2_msg_frompeer(msg) &&
1417
5.58k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.58k
  cnt = betoh16(del.del_nspi);
1421
5.58k
  sz = del.del_spisize;
1422
1423
5.58k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.58k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.58k
      sz, cnt);
1426
1427
5.58k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.28k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.28k
    return (0);
1430
5.28k
  }
1431
1432
303
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
303
  msg->msg_parent->msg_del_cnt = cnt;
1434
303
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
303
  buf = msgbuf + offset + sizeof(del);
1437
303
  len = left - sizeof(del);
1438
303
  if (len == 0 || sz == 0 || cnt == 0)
1439
280
    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
16.3k
{
1458
16.3k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
16.3k
  if (left < sizeof(*tsp)) {
1461
2.36k
    log_debug("%s: malformed payload: too short for header "
1462
2.36k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.36k
    return (-1);
1464
2.36k
  }
1465
13.9k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
13.9k
  return (0);
1468
16.3k
}
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
16.3k
{
1474
16.3k
  struct ikev2_tsp     tsp;
1475
16.3k
  struct ikev2_ts      ts;
1476
16.3k
  size_t         ts_len, i;
1477
1478
16.3k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.36k
    return (-1);
1480
1481
13.9k
  offset += sizeof(tsp);
1482
13.9k
  left -= sizeof(tsp);
1483
1484
13.9k
  log_debug("%s: count %d length %zu", __func__,
1485
13.9k
      tsp.tsp_count, left);
1486
1487
25.8k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
24.2k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
10.9k
      return (-1);
1490
1491
13.3k
    log_debug("%s: type %s protoid %u length %d "
1492
13.3k
        "startport %u endport %u", __func__,
1493
13.3k
        print_map(ts.ts_type, ikev2_ts_map),
1494
13.3k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
13.3k
        betoh16(ts.ts_startport),
1496
13.3k
        betoh16(ts.ts_endport));
1497
1498
13.3k
    offset += sizeof(ts);
1499
13.3k
    left -= sizeof(ts);
1500
1501
13.3k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
13.3k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.45k
      return (-1);
1504
1505
11.9k
    offset += ts_len;
1506
11.9k
    left -= ts_len;
1507
11.9k
  }
1508
1509
1.59k
  return (0);
1510
13.9k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
24.2k
{
1516
24.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
24.2k
  size_t     ts_length;
1518
1519
24.2k
  if (left < sizeof(*ts)) {
1520
9.93k
    log_debug("%s: malformed payload: too short for header "
1521
9.93k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
9.93k
    return (-1);
1523
9.93k
  }
1524
14.3k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
14.3k
  ts_length = betoh16(ts->ts_length);
1527
14.3k
  if (ts_length < sizeof(*ts)) {
1528
289
    log_debug("%s: malformed payload: shorter than minimum header "
1529
289
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
289
    return (-1);
1531
289
  }
1532
14.0k
  if (left < ts_length) {
1533
692
    log_debug("%s: malformed payload: too long for payload size "
1534
692
        "(%zu < %zu)", __func__, left, ts_length);
1535
692
    return (-1);
1536
692
  }
1537
1538
13.3k
  return (0);
1539
14.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
13.3k
{
1545
13.3k
  struct sockaddr_in     start4, end4;
1546
13.3k
  struct sockaddr_in6    start6, end6;
1547
13.3k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
13.3k
  uint8_t       *ptr;
1549
1550
13.3k
  ptr = msgbuf + offset;
1551
1552
13.3k
  switch (type) {
1553
4.72k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
4.72k
    if (left < 2 * 4) {
1555
307
      log_debug("%s: malformed payload: too short "
1556
307
          "for ipv4 addr range (%zu < %u)",
1557
307
          __func__, left, 2 * 4);
1558
307
      return (-1);
1559
307
    }
1560
1561
4.42k
    bzero(&start4, sizeof(start4));
1562
4.42k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
4.42k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
4.42k
    ptr += 4;
1568
4.42k
    left -= 4;
1569
1570
4.42k
    bzero(&end4, sizeof(end4));
1571
4.42k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
4.42k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
4.42k
    left -= 4;
1577
1578
4.42k
    log_debug("%s: start %s end %s", __func__,
1579
4.42k
        print_addr(&start4), print_addr(&end4));
1580
4.42k
    break;
1581
1.14k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.14k
    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
890
    bzero(&start6, sizeof(start6));
1589
890
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
890
    memcpy(&start6.sin6_addr, ptr, 16);
1594
890
    ptr += 16;
1595
890
    left -= 16;
1596
1597
890
    bzero(&end6, sizeof(end6));
1598
890
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
890
    memcpy(&end6.sin6_addr, ptr, 16);
1603
890
    left -= 16;
1604
1605
890
    log_debug("%s: start %s end %s", __func__,
1606
890
        print_addr(&start6), print_addr(&end6));
1607
890
    break;
1608
7.49k
  default:
1609
7.49k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
7.49k
    return (0);
1611
13.3k
  }
1612
1613
5.31k
  if (left > 0) {
1614
900
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
900
        __func__, left);
1616
900
    return (-1);
1617
900
  }
1618
1619
4.41k
  return (0);
1620
5.31k
}
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
8.50k
{
1876
8.50k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
8.50k
  if (left < sizeof(*cp)) {
1879
2.70k
    log_debug("%s: malformed payload: too short for header "
1880
2.70k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
2.70k
    return (-1);
1882
2.70k
  }
1883
5.79k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
5.79k
  return (0);
1886
8.50k
}
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
8.50k
{
1892
8.50k
  struct ikev2_cp    cp;
1893
8.50k
  struct ikev2_cfg  *cfg;
1894
8.50k
  struct iked_addr  *addr;
1895
8.50k
  struct sockaddr_in  *in4;
1896
8.50k
  struct sockaddr_in6 *in6;
1897
8.50k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
8.50k
  uint8_t     *ptr;
1899
8.50k
  size_t       len;
1900
8.50k
  int      cfg_type;
1901
1902
8.50k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
2.70k
    return (-1);
1904
1905
5.79k
  ptr = msgbuf + offset + sizeof(cp);
1906
5.79k
  len = left - sizeof(cp);
1907
1908
5.79k
  log_debug("%s: type %s length %zu",
1909
5.79k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
5.79k
  print_hex(ptr, 0, len);
1911
1912
13.1k
  while (len > 0) {
1913
8.63k
    if (len < sizeof(*cfg)) {
1914
339
      log_debug("%s: malformed payload: too short for cfg "
1915
339
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
339
      return (-1);
1917
339
    }
1918
8.29k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.29k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.29k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.29k
        betoh16(cfg->cfg_type),
1923
8.29k
        betoh16(cfg->cfg_length));
1924
1925
8.29k
    ptr += sizeof(*cfg);
1926
8.29k
    len -= sizeof(*cfg);
1927
1928
8.29k
    if (len < betoh16(cfg->cfg_length)) {
1929
932
      log_debug("%s: malformed payload: too short for "
1930
932
          "cfg_length (%zu < %u)", __func__, len,
1931
932
          betoh16(cfg->cfg_length));
1932
932
      return (-1);
1933
932
    }
1934
1935
7.36k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.36k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.36k
    switch (cfg_type) {
1939
833
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.43k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.43k
      if (!ikev2_msg_frompeer(msg))
1942
668
        break;
1943
767
      if (betoh16(cfg->cfg_length) == 0)
1944
307
        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.05k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
2.85k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
2.85k
      if (!ikev2_msg_frompeer(msg))
1999
2.67k
        break;
2000
185
      if (betoh16(cfg->cfg_length) == 0)
2001
58
        break;
2002
      /* XXX multiple-valued */
2003
127
      if (betoh16(cfg->cfg_length) < 16) {
2004
1
        log_debug("%s: malformed payload: too short "
2005
1
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
1
            __func__, betoh16(cfg->cfg_length), 16);
2007
1
        return (-1);
2008
1
      }
2009
126
      switch(cfg_type) {
2010
86
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
86
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
39
        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
126
      }
2023
43
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
43
      addr->addr_af = AF_INET6;
2028
43
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
43
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
43
      memcpy(&in6->sin6_addr, ptr, 16);
2034
43
      switch(cfg_type) {
2035
39
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
39
        msg->msg_parent->msg_cp_addr6 = addr;
2037
39
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
39
            print_addr(&addr->addr));
2039
39
        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
43
      }
2050
43
      break;
2051
7.36k
    }
2052
2053
7.35k
 skip:
2054
7.35k
    ptr += betoh16(cfg->cfg_length);
2055
7.35k
    len -= betoh16(cfg->cfg_length);
2056
7.35k
  }
2057
2058
4.52k
  if (!ikev2_msg_frompeer(msg))
2059
4.33k
    return (0);
2060
2061
189
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
189
  return (0);
2064
4.52k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
16.1k
{
2070
16.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
16.1k
  if (left < sizeof(*hdr)) {
2073
6.77k
    log_debug("%s: malformed payload: too short for header "
2074
6.77k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
6.77k
    return (-1);
2076
6.77k
  }
2077
9.33k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.33k
  return (0);
2080
16.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
16.1k
{
2086
16.1k
  struct eap_header    hdr;
2087
16.1k
  struct eap_message    *eap = NULL;
2088
16.1k
  const struct iked_sa    *sa = msg->msg_sa;
2089
16.1k
  size_t         len;
2090
2091
16.1k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
6.77k
    return (-1);
2093
9.33k
  len = betoh16(hdr.eap_length);
2094
2095
9.33k
  if (len < sizeof(*eap)) {
2096
3.37k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.37k
        print_map(hdr.eap_code, eap_code_map),
2098
3.37k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
5.96k
  } else {
2100
    /* Now try to get the indicated length */
2101
5.96k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
2.86k
      log_debug("%s: invalid EAP length", __func__);
2103
2.86k
      return (-1);
2104
2.86k
    }
2105
2106
3.10k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.10k
        print_map(eap->eap_code, eap_code_map),
2108
3.10k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.10k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.10k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.10k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.10k
  }
2115
2116
6.47k
  return (0);
2117
9.33k
}
\ 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 1042be240..dc5bf3425 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-10-30 00:56

/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
1.51k
{
42
1.51k
  struct ibuf *buf;
43
44
1.51k
  if ((buf = ibuf_dynamic(len,
45
1.51k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
1.51k
  if (len == 0)
49
113
    return (buf);
50
51
1.40k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
1.40k
  } else {
57
1.40k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
1.40k
  }
62
63
1.40k
  return (buf);
64
1.40k
}
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-10-31 00:56

/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
16.2k
{
42
16.2k
  struct ibuf *buf;
43
44
16.2k
  if ((buf = ibuf_dynamic(len,
45
16.2k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
16.2k
  if (len == 0)
49
988
    return (buf);
50
51
15.2k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
15.2k
  } else {
57
15.2k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
15.2k
  }
62
63
15.2k
  return (buf);
64
15.2k
}
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 c9f552a1e..e06b05a24 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-10-30 00:56

/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
9.34k
{
83
9.34k
  return (verbose);
84
9.34k
}
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
1.97k
{
99
1.97k
  char  *nfmt;
100
1.97k
  int  saved_errno = errno;
101
102
1.97k
  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
1.97k
    vsyslog(pri, fmt, ap);
114
115
1.97k
  errno = saved_errno;
116
1.97k
}
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
1.97k
{
159
1.97k
  va_list  ap;
160
161
1.97k
  va_start(ap, emsg);
162
1.97k
  vlog(LOG_INFO, emsg, ap);
163
1.97k
  va_end(ap);
164
1.97k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
50.0k
{
169
50.0k
  va_list  ap;
170
171
50.0k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
50.0k
}
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-10-31 00:56

/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
119k
{
83
119k
  return (verbose);
84
119k
}
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.2k
{
99
10.2k
  char  *nfmt;
100
10.2k
  int  saved_errno = errno;
101
102
10.2k
  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.2k
    vsyslog(pri, fmt, ap);
114
115
10.2k
  errno = saved_errno;
116
10.2k
}
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.2k
{
159
10.2k
  va_list  ap;
160
161
10.2k
  va_start(ap, emsg);
162
10.2k
  vlog(LOG_INFO, emsg, ap);
163
10.2k
  va_end(ap);
164
10.2k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
468k
{
169
468k
  va_list  ap;
170
171
468k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
468k
}
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 d9e78e09b..eafdf99da 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-10-30 00:56

/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
1.51k
#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
65.4k
#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
19.7k
#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-10-31 00:56

/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
16.2k
#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
614k
#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
174k
#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 05015dda8..314bd899e 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-10-30 00:56

/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
562
{
72
562
  switch (sa->sa_family) {
73
438
  case AF_INET:
74
438
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
124
  case AF_INET6:
76
124
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
562
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
562
}
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
3.79k
{
500
3.79k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
3.79k
  static int     i = 0;
502
3.79k
  char      *ptr;
503
504
3.79k
  ptr = buf[i];
505
506
3.79k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
93
  case 4:
511
93
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
93
    break;
513
1.53k
  case 8:
514
1.53k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
1.53k
    break;
516
2.16k
  default:
517
2.16k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
2.16k
    break;
519
3.79k
  }
520
521
3.79k
  if (++i >= IKED_CYCLE_BUFFERS)
522
474
    i = 0;
523
524
3.79k
  return (ptr);
525
3.79k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
61.0k
{
530
61.0k
  unsigned int     i;
531
61.0k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
61.0k
  static int     idx = 0;
533
61.0k
  const char    *name = NULL;
534
535
61.0k
  if (idx >= IKED_CYCLE_BUFFERS)
536
7.63k
    idx = 0;
537
61.0k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
1.10M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
1.04M
    if (map[i].cm_type == type)
541
45.3k
      name = map[i].cm_name;
542
1.04M
  }
543
544
61.0k
  if (name == NULL)
545
15.6k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
45.3k
  else
547
45.3k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
61.0k
  return (buf[idx++]);
550
61.0k
}
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
9.34k
{
562
9.34k
  unsigned int   i;
563
564
9.34k
  if (log_getverbose() < 3 || !length)
565
9.34k
    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
562
{
738
562
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
562
  static int   idx;
740
562
  struct sockaddr *sa = addr;
741
562
  char    *buf;
742
562
  size_t     len;
743
562
  char     pbuf[7];
744
562
  in_port_t  port;
745
746
562
  buf = sbuf[idx];
747
562
  len = sizeof(sbuf[idx]);
748
562
  if (++idx >= IKED_CYCLE_BUFFERS)
749
70
    idx = 0;
750
751
562
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
562
  if (getnameinfo(sa, SA_LEN(sa),
757
562
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
562
  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
562
  return (buf);
768
562
}
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-10-31 00:56

/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
10.8k
{
72
10.8k
  switch (sa->sa_family) {
73
9.00k
  case AF_INET:
74
9.00k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
1.82k
  case AF_INET6:
76
1.82k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
10.8k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
10.8k
}
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
29.3k
{
500
29.3k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
29.3k
  static int     i = 0;
502
29.3k
  char      *ptr;
503
504
29.3k
  ptr = buf[i];
505
506
29.3k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
334
  case 4:
511
334
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
334
    break;
513
20.3k
  case 8:
514
20.3k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
20.3k
    break;
516
8.69k
  default:
517
8.69k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
8.69k
    break;
519
29.3k
  }
520
521
29.3k
  if (++i >= IKED_CYCLE_BUFFERS)
522
3.66k
    i = 0;
523
524
29.3k
  return (ptr);
525
29.3k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
574k
{
530
574k
  unsigned int     i;
531
574k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
574k
  static int     idx = 0;
533
574k
  const char    *name = NULL;
534
535
574k
  if (idx >= IKED_CYCLE_BUFFERS)
536
71.7k
    idx = 0;
537
574k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
11.7M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
11.2M
    if (map[i].cm_type == type)
541
401k
      name = map[i].cm_name;
542
11.2M
  }
543
544
574k
  if (name == NULL)
545
172k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
401k
  else
547
401k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
574k
  return (buf[idx++]);
550
574k
}
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
119k
{
562
119k
  unsigned int   i;
563
564
119k
  if (log_getverbose() < 3 || !length)
565
119k
    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
10.8k
{
738
10.8k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
10.8k
  static int   idx;
740
10.8k
  struct sockaddr *sa = addr;
741
10.8k
  char    *buf;
742
10.8k
  size_t     len;
743
10.8k
  char     pbuf[7];
744
10.8k
  in_port_t  port;
745
746
10.8k
  buf = sbuf[idx];
747
10.8k
  len = sizeof(sbuf[idx]);
748
10.8k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.35k
    idx = 0;
750
751
10.8k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
10.8k
  if (getnameinfo(sa, SA_LEN(sa),
757
10.8k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
10.8k
  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
10.8k
  return (buf);
768
10.8k
}
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 77be77340..28e2e45fd 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-10-30 00:56

/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
19.5k
#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
737
{
61
737
  return (0);
62
737
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
19.5k
{
68
19.5k
  struct iked_sa    *sa = msg->msg_sa;
69
19.5k
  struct ike_header *hdr;
70
71
19.5k
  msg = msg->msg_parent;
72
73
19.5k
  if (sa == NULL ||
74
19.5k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
19.5k
  if (!sa->sa_hdr.sh_initiator &&
78
19.5k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
999
    return (1);
80
18.5k
  else if (sa->sa_hdr.sh_initiator &&
81
18.5k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
18.5k
  return (0);
85
19.5k
}
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
1.70k
{
102
1.70k
  return "";
103
1.70k
}
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
12
{
121
12
  return (0);
122
12
}
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
48
{
165
48
  return (0);
166
48
}
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
658
{
179
658
  return (0);
180
658
}
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
3
{
192
3
  return (NULL);
193
3
}
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
70
{
209
70
  return (0);
210
70
}
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
717
{
251
717
  struct iked_certreq *cr;
252
717
  struct iked_proposal *prop, *proptmp;
253
717
  int      i;
254
255
717
  if (msg == msg->msg_parent) {
256
717
    ibuf_free(msg->msg_nonce);
257
717
    ibuf_free(msg->msg_ke);
258
717
    ibuf_free(msg->msg_auth.id_buf);
259
717
    ibuf_free(msg->msg_peerid.id_buf);
260
717
    ibuf_free(msg->msg_localid.id_buf);
261
717
    ibuf_free(msg->msg_cert.id_buf);
262
2.86k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
2.15k
      ibuf_free(msg->msg_scert[i].id_buf);
264
717
    ibuf_free(msg->msg_cookie);
265
717
    ibuf_free(msg->msg_cookie2);
266
717
    ibuf_free(msg->msg_del_buf);
267
717
    free(msg->msg_eap.eam_user);
268
717
    free(msg->msg_cp_addr);
269
717
    free(msg->msg_cp_addr6);
270
717
    free(msg->msg_cp_dns);
271
272
717
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
717
        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
717
    msg->msg_nonce = NULL;
281
717
    msg->msg_ke = NULL;
282
717
    msg->msg_auth.id_buf = NULL;
283
717
    msg->msg_peerid.id_buf = NULL;
284
717
    msg->msg_localid.id_buf = NULL;
285
717
    msg->msg_cert.id_buf = NULL;
286
2.86k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
2.15k
      msg->msg_scert[i].id_buf = NULL;
288
717
    msg->msg_cookie = NULL;
289
717
    msg->msg_cookie2 = NULL;
290
717
    msg->msg_del_buf = NULL;
291
717
    msg->msg_eap.eam_user = NULL;
292
717
    msg->msg_cp_addr = NULL;
293
717
    msg->msg_cp_addr6 = NULL;
294
717
    msg->msg_cp_dns = NULL;
295
296
802
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
85
      ibuf_free(cr->cr_data);
298
85
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
85
      free(cr);
300
85
    }
301
717
  }
302
303
717
  if (msg->msg_data != NULL) {
304
717
    ibuf_free(msg->msg_data);
305
717
    msg->msg_data = NULL;
306
717
  }
307
717
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
171k
#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.10k
{
61
3.10k
  return (0);
62
3.10k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
171k
{
68
171k
  struct iked_sa    *sa = msg->msg_sa;
69
171k
  struct ike_header *hdr;
70
71
171k
  msg = msg->msg_parent;
72
73
171k
  if (sa == NULL ||
74
171k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
171k
  if (!sa->sa_hdr.sh_initiator &&
78
171k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
40.9k
    return (1);
80
130k
  else if (sa->sa_hdr.sh_initiator &&
81
130k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
130k
  return (0);
85
171k
}
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.42k
{
102
7.42k
  return "";
103
7.42k
}
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
15.9k
{
165
15.9k
  return (0);
166
15.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
4.75k
{
179
4.75k
  return (0);
180
4.75k
}
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
706
{
209
706
  return (0);
210
706
}
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
10.0k
{
251
10.0k
  struct iked_certreq *cr;
252
10.0k
  struct iked_proposal *prop, *proptmp;
253
10.0k
  int      i;
254
255
10.0k
  if (msg == msg->msg_parent) {
256
10.0k
    ibuf_free(msg->msg_nonce);
257
10.0k
    ibuf_free(msg->msg_ke);
258
10.0k
    ibuf_free(msg->msg_auth.id_buf);
259
10.0k
    ibuf_free(msg->msg_peerid.id_buf);
260
10.0k
    ibuf_free(msg->msg_localid.id_buf);
261
10.0k
    ibuf_free(msg->msg_cert.id_buf);
262
40.2k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
30.1k
      ibuf_free(msg->msg_scert[i].id_buf);
264
10.0k
    ibuf_free(msg->msg_cookie);
265
10.0k
    ibuf_free(msg->msg_cookie2);
266
10.0k
    ibuf_free(msg->msg_del_buf);
267
10.0k
    free(msg->msg_eap.eam_user);
268
10.0k
    free(msg->msg_cp_addr);
269
10.0k
    free(msg->msg_cp_addr6);
270
10.0k
    free(msg->msg_cp_dns);
271
272
10.0k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
10.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
10.0k
    msg->msg_nonce = NULL;
281
10.0k
    msg->msg_ke = NULL;
282
10.0k
    msg->msg_auth.id_buf = NULL;
283
10.0k
    msg->msg_peerid.id_buf = NULL;
284
10.0k
    msg->msg_localid.id_buf = NULL;
285
10.0k
    msg->msg_cert.id_buf = NULL;
286
40.2k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
30.1k
      msg->msg_scert[i].id_buf = NULL;
288
10.0k
    msg->msg_cookie = NULL;
289
10.0k
    msg->msg_cookie2 = NULL;
290
10.0k
    msg->msg_del_buf = NULL;
291
10.0k
    msg->msg_eap.eam_user = NULL;
292
10.0k
    msg->msg_cp_addr = NULL;
293
10.0k
    msg->msg_cp_addr6 = NULL;
294
10.0k
    msg->msg_cp_dns = NULL;
295
296
10.5k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
526
      ibuf_free(cr->cr_data);
298
526
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
526
      free(cr);
300
526
    }
301
10.0k
  }
302
303
10.0k
  if (msg->msg_data != NULL) {
304
10.0k
    ibuf_free(msg->msg_data);
305
10.0k
    msg->msg_data = NULL;
306
10.0k
  }
307
10.0k
}
\ 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 2de4ffb01..cc12552ea 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-10-30 00:56

/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
717
#define OFFSET_ICOOKIE    0
31
717
#define OFFSET_RCOOKIE    8
32
717
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
717
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
717
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
717
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
717
{
40
717
  return &data[OFFSET_ICOOKIE];
41
717
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
717
{
46
717
  return &data[OFFSET_RCOOKIE];
47
717
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
717
{
52
717
  return data[OFFSET_NEXTPAYLOAD];
53
717
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
717
{
58
717
  return data[OFFSET_VERSION];
59
717
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
717
{
64
717
  return data[OFFSET_EXCHANGE];
65
717
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
717
{
70
717
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
717
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
717
{
76
717
  bzero(hdr, sizeof(*hdr));
77
717
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
717
      sizeof(hdr->ike_ispi));
79
717
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
717
      sizeof(hdr->ike_rspi));
81
717
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
717
  hdr->ike_version = get_version(ibuf_data(data));
83
717
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
717
  hdr->ike_length = get_length(ibuf_data(data));
85
717
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
717
{
90
717
  static struct iked_sa sa;
91
92
717
  bzero(&sa, sizeof(sa));
93
717
  bzero(msg, sizeof(*msg));
94
95
717
  msg->msg_sa = &sa;
96
717
  msg->msg_data = data;
97
717
  msg->msg_e = 1;
98
717
  msg->msg_parent = msg;
99
100
717
  TAILQ_INIT(&msg->msg_proposals);
101
717
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
717
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
718
{
108
718
  struct ibuf   *fuzzed;
109
718
  struct ike_header  hdr;
110
718
  struct iked_message  msg;
111
112
718
  bzero(&hdr, sizeof(hdr));
113
718
  bzero(&msg, sizeof(msg));
114
115
718
  fuzzed = ibuf_new(data, size);
116
718
  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
718
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
717
  prepare_header(&hdr, fuzzed);
129
717
  prepare_message(&msg, fuzzed);
130
131
717
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
717
  ikev2_msg_cleanup(NULL, &msg);
134
135
717
  return 0;
136
718
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
10.0k
#define OFFSET_ICOOKIE    0
31
10.0k
#define OFFSET_RCOOKIE    8
32
10.0k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
10.0k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
10.0k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
10.0k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
10.0k
{
40
10.0k
  return &data[OFFSET_ICOOKIE];
41
10.0k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
10.0k
{
46
10.0k
  return &data[OFFSET_RCOOKIE];
47
10.0k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
10.0k
{
52
10.0k
  return data[OFFSET_NEXTPAYLOAD];
53
10.0k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
10.0k
{
58
10.0k
  return data[OFFSET_VERSION];
59
10.0k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
10.0k
{
64
10.0k
  return data[OFFSET_EXCHANGE];
65
10.0k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
10.0k
{
70
10.0k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
10.0k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
10.0k
{
76
10.0k
  bzero(hdr, sizeof(*hdr));
77
10.0k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
10.0k
      sizeof(hdr->ike_ispi));
79
10.0k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
10.0k
      sizeof(hdr->ike_rspi));
81
10.0k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
10.0k
  hdr->ike_version = get_version(ibuf_data(data));
83
10.0k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
10.0k
  hdr->ike_length = get_length(ibuf_data(data));
85
10.0k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
10.0k
{
90
10.0k
  static struct iked_sa sa;
91
92
10.0k
  bzero(&sa, sizeof(sa));
93
10.0k
  bzero(msg, sizeof(*msg));
94
95
10.0k
  msg->msg_sa = &sa;
96
10.0k
  msg->msg_data = data;
97
10.0k
  msg->msg_e = 1;
98
10.0k
  msg->msg_parent = msg;
99
100
10.0k
  TAILQ_INIT(&msg->msg_proposals);
101
10.0k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
10.0k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
10.0k
{
108
10.0k
  struct ibuf   *fuzzed;
109
10.0k
  struct ike_header  hdr;
110
10.0k
  struct iked_message  msg;
111
112
10.0k
  bzero(&hdr, sizeof(hdr));
113
10.0k
  bzero(&msg, sizeof(msg));
114
115
10.0k
  fuzzed = ibuf_new(data, size);
116
10.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
10.0k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
10.0k
  prepare_header(&hdr, fuzzed);
129
10.0k
  prepare_message(&msg, fuzzed);
130
131
10.0k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
10.0k
  ikev2_msg_cleanup(NULL, &msg);
134
135
10.0k
  return 0;
136
10.0k
}
\ 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 232fe5a91..f1e5b17a8 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-10-30 00:56

/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-10-31 00:56

/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 23aaacbdf..ffae26e02 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-10-30 00:56

/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-10-31 00:56

/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 e5f12a2dc..4d83c3ad1 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-10-30 00:56

/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-10-31 00:56

/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 b04e5a1bf..171ba81ad 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-10-30 00:56

/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-10-31 00:56

/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 3f9daf2f9..54011cc1d 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-10-30 00:56

/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
1.51k
{
26
  /* This is legal. */
27
1.51k
  if (ptr == NULL)
28
113
    return;
29
30
1.40k
  explicit_bzero(ptr, sz);
31
1.40k
  free(ptr);
32
1.40k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
16.2k
{
26
  /* This is legal. */
27
16.2k
  if (ptr == NULL)
28
988
    return;
29
30
15.2k
  explicit_bzero(ptr, sz);
31
15.2k
  free(ptr);
32
15.2k
}
\ 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 8a57f8f7e..d074bd422 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-10-30 00:56

/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-10-31 00:56

/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 107ebcf35..ab6bfcfb7 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-10-30 00:56

/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-10-31 00:56

/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 f92ace0fb..9943ec153 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-10-30 00:56

/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
1.51k
{
63
1.51k
  struct ibuf *buf;
64
65
1.51k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
1.51k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
1.51k
  if (len > 0) {
73
1.40k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
1.40k
  }
78
1.51k
  buf->size = len;
79
1.51k
  buf->max = max;
80
1.51k
  buf->fd = -1;
81
82
1.51k
  return (buf);
83
1.51k
}
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
1.40k
{
108
1.40k
  void  *b;
109
110
1.40k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
1.40k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
1.40k
  b = buf->buf + buf->wpos;
120
1.40k
  buf->wpos += len;
121
1.40k
  memset(b, 0, len);
122
1.40k
  return (b);
123
1.40k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
1.40k
{
128
1.40k
  void *b;
129
130
1.40k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
1.40k
  memcpy(b, data, len);
134
1.40k
  return (0);
135
1.40k
}
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
21.3k
{
203
  /* only allowed to seek in already written parts */
204
21.3k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
477
    errno = ERANGE;
206
477
    return (NULL);
207
477
  }
208
209
20.8k
  return (buf->buf + pos);
210
21.3k
}
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
65.8k
{
273
65.8k
  return (buf->buf);
274
65.8k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
717
{
279
717
  return (buf->wpos);
280
717
}
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
10.0k
{
297
10.0k
  if (buf == NULL)
298
8.54k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
1.51k
  freezero(buf->buf, buf->size);
304
1.51k
  free(buf);
305
1.51k
}
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-10-31 00:56

/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
16.2k
{
63
16.2k
  struct ibuf *buf;
64
65
16.2k
  if (max < len) {
66
0
    errno = EINVAL;
67
0
    return (NULL);
68
0
  }
69
70
16.2k
  if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
71
0
    return (NULL);
72
16.2k
  if (len > 0) {
73
15.2k
    if ((buf->buf = calloc(len, 1)) == NULL) {
74
0
      free(buf);
75
0
      return (NULL);
76
0
    }
77
15.2k
  }
78
16.2k
  buf->size = len;
79
16.2k
  buf->max = max;
80
16.2k
  buf->fd = -1;
81
82
16.2k
  return (buf);
83
16.2k
}
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
15.2k
{
108
15.2k
  void  *b;
109
110
15.2k
  if (len > SIZE_MAX - buf->wpos) {
111
0
    errno = ERANGE;
112
0
    return (NULL);
113
0
  }
114
115
15.2k
  if (buf->wpos + len > buf->size)
116
0
    if (ibuf_realloc(buf, len) == -1)
117
0
      return (NULL);
118
119
15.2k
  b = buf->buf + buf->wpos;
120
15.2k
  buf->wpos += len;
121
15.2k
  memset(b, 0, len);
122
15.2k
  return (b);
123
15.2k
}
124
125
int
126
ibuf_add(struct ibuf *buf, const void *data, size_t len)
127
15.2k
{
128
15.2k
  void *b;
129
130
15.2k
  if ((b = ibuf_reserve(buf, len)) == NULL)
131
0
    return (-1);
132
133
15.2k
  memcpy(b, data, len);
134
15.2k
  return (0);
135
15.2k
}
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
198k
{
203
  /* only allowed to seek in already written parts */
204
198k
  if (len > SIZE_MAX - pos || pos + len > buf->wpos) {
205
2.86k
    errno = ERANGE;
206
2.86k
    return (NULL);
207
2.86k
  }
208
209
195k
  return (buf->buf + pos);
210
198k
}
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
618k
{
273
618k
  return (buf->buf);
274
618k
}
275
276
size_t
277
ibuf_size(struct ibuf *buf)
278
10.0k
{
279
10.0k
  return (buf->wpos);
280
10.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
136k
{
297
136k
  if (buf == NULL)
298
119k
    return;
299
#ifdef NOTYET
300
  if (buf->fd != -1)
301
    close(buf->fd);
302
#endif
303
16.2k
  freezero(buf->buf, buf->size);
304
16.2k
  free(buf);
305
16.2k
}
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 239a6266e..58d4ee008 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-10-30 00:56

/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-10-31 00:56

/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 33a9f919d..0c8e72c0b 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-10-30 00:56

/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-10-31 00:56

/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 98e47b6c4..96ab19429 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-10-30 00:56

/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
562
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
562
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
124
  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-10-31 00:56

/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
10.8k
  ((sa->sa_family == AF_INET)  ? sizeof(struct sockaddr_in) :  \
114
10.8k
  (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) :  \
115
1.82k
  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 7fde06138..9e3adc1ce 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-10-30 00:56

/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-10-31 00:56

/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 86e8a7f58..df05adc2f 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-10-30 00:56

/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-10-31 00:56

/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 fa5227978..ba80f51c9 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-10-30 00:56

/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-10-31 00:56

/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 52ebfc5f5..a82d64fe0 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-10-30 00:56

/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
46.3k
{
30
46.3k
  const char *osrc = src;
31
46.3k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
46.3k
  if (nleft != 0) {
35
255k
    while (--nleft != 0) {
36
254k
      if ((*dst++ = *src++) == '\0')
37
46.2k
        break;
38
254k
    }
39
46.3k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
46.3k
  if (nleft == 0) {
43
123
    if (dsize != 0)
44
123
      *dst = '\0';   /* NUL-terminate dst */
45
123
    while (*src++)
46
0
      ;
47
123
  }
48
49
46.3k
  return(src - osrc - 1); /* count does not include NUL */
50
46.3k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
405k
{
30
405k
  const char *osrc = src;
31
405k
  size_t nleft = dsize;
32
33
  /* Copy as many bytes as will fit. */
34
405k
  if (nleft != 0) {
35
2.99M
    while (--nleft != 0) {
36
2.99M
      if ((*dst++ = *src++) == '\0')
37
403k
        break;
38
2.99M
    }
39
405k
  }
40
41
  /* Not enough room in dst, add NUL and traverse rest of src. */
42
405k
  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
405k
  return(src - osrc - 1); /* count does not include NUL */
50
405k
}
\ 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 ca2e50cc5..9021ea56e 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-10-30 00:56

/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-10-31 00:56

/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 0171c630a..a9481d111 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-10-30 00:56

/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
802
#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
717
#define SIMPLEQ_INIT(head) do {           \
286
717
  (head)->sqh_first = NULL;         \
287
717
  (head)->sqh_last = &(head)->sqh_first;        \
288
717
} 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
85
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
85
  (elm)->field.sqe_next = NULL;         \
298
85
  *(head)->sqh_last = (elm);          \
299
85
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
85
} 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
85
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
85
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
85
    (head)->sqh_last = &(head)->sqh_first;     \
311
85
} 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
717
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
1.43k
#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
717
  for ((var) = TAILQ_FIRST(head);         \
446
717
      (var) != TAILQ_END(head) &&         \
447
717
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
717
      (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
717
#define TAILQ_INIT(head) do {           \
466
717
  (head)->tqh_first = NULL;         \
467
717
  (head)->tqh_last = &(head)->tqh_first;        \
468
717
} 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-10-31 00:56

/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
10.5k
#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
10.0k
#define SIMPLEQ_INIT(head) do {           \
286
10.0k
  (head)->sqh_first = NULL;         \
287
10.0k
  (head)->sqh_last = &(head)->sqh_first;        \
288
10.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
526
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
526
  (elm)->field.sqe_next = NULL;         \
298
526
  *(head)->sqh_last = (elm);          \
299
526
  (head)->sqh_last = &(elm)->field.sqe_next;      \
300
526
} 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
526
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
526
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
526
    (head)->sqh_last = &(head)->sqh_first;     \
311
526
} 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
10.0k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
429
20.1k
#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
10.0k
  for ((var) = TAILQ_FIRST(head);         \
446
10.0k
      (var) != TAILQ_END(head) &&         \
447
10.0k
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
448
10.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
10.0k
#define TAILQ_INIT(head) do {           \
466
10.0k
  (head)->tqh_first = NULL;         \
467
10.0k
  (head)->tqh_last = &(head)->tqh_first;        \
468
10.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 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 bab15b08f..cd7c7f318 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-10-30 00:56

/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-10-31 00:56

/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 e1522bbc0..007238140 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-10-30 00:56

/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-10-31 00:56

/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 b97ebe790..755366626 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-10-30 00:56

/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-10-31 00:56

/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 77ece8a0f..b6ce5df7e 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-10-30 00:56

/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
6.08k
#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
12
#define IKED_MSG_NAT_SRC_IP       0x01
688
36
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
10
#define IKED_MSG_FLAGS_MOBIKE       0x0002
692
0
#define IKED_MSG_FLAGS_SIGSHA2        0x0004
693
10
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND   0x0008
694
10
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS    0x0010
695
0
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED    0x0020
696
10
#define IKED_MSG_FLAGS_INVALID_KE     0x0040
697
10
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED     0x0080
698
18
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
12
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE    0x0200
700
10
#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
1.70k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
1.70k
#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-10-31 00:56

/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
84.1k
#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
2.47k
#define IKED_MSG_NAT_SRC_IP       0x01
688
13.5k
#define IKED_MSG_NAT_DST_IP       0x02
689
690
0
#define IKED_MSG_FLAGS_FRAGMENTATION      0x0001
691
133
#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
233
#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
224
#define IKED_MSG_FLAGS_USE_TRANSPORT      0x0100
699
341
#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.42k
#define SPI_SH(sh, f)    ikev2_ikesa_info((sh)->sh_ispi, (f))
1105
7.42k
#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 7ade79301..400858f42 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-10-30 00:56

/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
12
#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
21.7k
#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
4.38k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
644
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
1.00k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
1.77k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
410
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
1.77k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
773
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
57
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
1.12k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
812
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
351
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
1.27k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
21.6k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
1.30k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
3.33k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
21.6k
#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
782
#define IKEV2_XFORM_MORE    3
155
156
334
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
434
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
67
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
68
#define IKEV2_XFORMTYPE_DH    4  /* Diffie-Hellman Group */
160
66
#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
3.61k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
1.07k
#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
10
#define IKEV2_N_NO_PROPOSAL_CHOSEN    14  /* RFC7296 */
313
11
#define IKEV2_N_INVALID_KE_PAYLOAD    17  /* RFC7296 */
314
1
#define IKEV2_N_AUTHENTICATION_FAILED   24  /* RFC7296 */
315
#define IKEV2_N_SINGLE_PAIR_REQUIRED    34  /* RFC7296 */
316
10
#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
12
#define IKEV2_N_TEMPORARY_FAILURE   43  /* RFC7296 */
325
10
#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
20
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
61
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
50
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
1
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
28
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
17
#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
28
#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
18
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
34
#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
1
#define IKEV2_N_FRAGMENTATION_SUPPORTED   16430  /* RFC7383 */
372
1
#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
880
#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
335
#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
108
#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
151
#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
242
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
93
#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
196
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
281
#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
216
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
301
#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-10-31 00:56

/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
195k
#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
27.1k
#define IKEV2_PAYLOAD_SA  33  /* Security Association */
94
5.93k
#define IKEV2_PAYLOAD_KE  34  /* Key Exchange */
95
12.7k
#define IKEV2_PAYLOAD_IDi 35  /* Identification - Initiator */
96
18.5k
#define IKEV2_PAYLOAD_IDr 36  /* Identification - Responder */
97
5.21k
#define IKEV2_PAYLOAD_CERT  37  /* Certificate */
98
10.2k
#define IKEV2_PAYLOAD_CERTREQ 38  /* Certificate Request */
99
7.98k
#define IKEV2_PAYLOAD_AUTH  39  /* Authentication */
100
229
#define IKEV2_PAYLOAD_NONCE 40  /* Nonce */
101
24.5k
#define IKEV2_PAYLOAD_NOTIFY  41  /* Notify */
102
6.99k
#define IKEV2_PAYLOAD_DELETE  42  /* Delete */
103
#define IKEV2_PAYLOAD_VENDOR  43  /* Vendor ID */
104
4.44k
#define IKEV2_PAYLOAD_TSi 44  /* Traffic Selector - Initiator */
105
16.3k
#define IKEV2_PAYLOAD_TSr 45  /* Traffic Selector - Responder */
106
194k
#define IKEV2_PAYLOAD_SK  46  /* Encrypted */
107
8.50k
#define IKEV2_PAYLOAD_CP  47  /* Configuration Payload */
108
16.1k
#define IKEV2_PAYLOAD_EAP 48  /* Extensible Authentication */
109
#define IKEV2_PAYLOAD_GSPM  49  /* RFC6467 Generic Secure Password */
110
194k
#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
2.73k
#define IKEV2_XFORM_MORE    3
155
156
1.05k
#define IKEV2_XFORMTYPE_ENCR    1  /* Encryption */
157
765
#define IKEV2_XFORMTYPE_PRF   2  /* Pseudo-Random Function */
158
154
#define IKEV2_XFORMTYPE_INTEGR    3  /* Integrity Algorithm */
159
247
#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
56.5k
#define IKEV2_ATTRAF_TV     0x8000  /* Type-Value format */
280
281
21.9k
#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
233
#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
341
#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
249
#define IKEV2_N_IPCOMP_SUPPORTED    16387  /* RFC7296 */
330
18.4k
#define IKEV2_N_NAT_DETECTION_SOURCE_IP   16388  /* RFC7296 */
331
15.9k
#define IKEV2_N_NAT_DETECTION_DESTINATION_IP  16389  /* RFC7296 */
332
2
#define IKEV2_N_COOKIE        16390  /* RFC7296 */
333
301
#define IKEV2_N_USE_TRANSPORT_MODE    16391  /* RFC7296 */
334
#define IKEV2_N_HTTP_CERT_LOOKUP_SUPPORTED  16392 /* RFC7296 */
335
64
#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
263
#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
344
#define IKEV2_N_UPDATE_SA_ADDRESSES   16400  /* RFC4555 */
343
201
#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.1k
#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.07k
#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
812
#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.78k
#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
4.72k
#define IKEV2_TS_IPV4_ADDR_RANGE  7  /* RFC7296 */
461
1.14k
#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.30k
#define IKEV2_CFG_INTERNAL_IP4_ADDRESS    1  /* RFC7296 */
529
#define IKEV2_CFG_INTERNAL_IP4_NETMASK    2 /* RFC7296 */
530
1.58k
#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.18k
#define IKEV2_CFG_INTERNAL_IP6_ADDRESS    8  /* RFC7296 */
536
2.90k
#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 90d2ff1d5..925ed03cf 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-10-30 00:56

/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
717
{
119
717
  log_debug("%s: header ispi %s rspi %s"
120
717
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
717
      " msgid %d length %u response %d", __func__,
122
717
      print_spi(betoh64(hdr->ike_ispi), 8),
123
717
      print_spi(betoh64(hdr->ike_rspi), 8),
124
717
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
717
      hdr->ike_version,
126
717
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
717
      hdr->ike_flags,
128
717
      betoh32(hdr->ike_msgid),
129
717
      betoh32(hdr->ike_length),
130
717
      msg->msg_response);
131
132
717
  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
713
  offset += sizeof(*hdr);
138
139
713
  return (ikev2_pld_payloads(env, msg, offset,
140
713
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
717
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
21.9k
{
147
21.9k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
21.9k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
21.9k
  if (left < sizeof(*pld)) {
152
66
    log_debug("%s: malformed payload: too short for generic "
153
66
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
66
    return (-1);
155
66
  }
156
21.8k
  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
21.8k
  pld_length = betoh16(pld->pld_length);
164
21.8k
  if (left < pld_length) {
165
90
    log_debug("%s: malformed payload: shorter than specified "
166
90
        "(%zu < %zu)", __func__, left, pld_length);
167
90
    return (-1);
168
90
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
21.7k
  if (pld_length < sizeof(*pld)) {
174
29
    log_debug("%s: malformed payload: shorter than minimum "
175
29
        "header size (%zu < %zu)", __func__, pld_length,
176
29
        sizeof(*pld));
177
29
    return (-1);
178
29
  }
179
180
21.7k
  return (0);
181
21.7k
}
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
713
{
187
713
  struct ikev2_payload   pld;
188
713
  unsigned int     e;
189
713
  int      ret;
190
713
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
713
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
713
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
713
  total = length - offset;
198
199
22.3k
  while (payload != 0 && offset < length) {
200
21.9k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
185
      return (-1);
202
203
21.7k
    log_debug("%s: %spayload %s"
204
21.7k
        " nextpayload %s critical 0x%02x length %d",
205
21.7k
        __func__, e ? "decrypted " : "",
206
21.7k
        print_map(payload, ikev2_payload_map),
207
21.7k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
21.7k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
21.7k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
21.7k
    offset += sizeof(pld);
213
21.7k
    total -= sizeof(pld);
214
21.7k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
21.7k
    ret = 0;
216
217
21.7k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
4.38k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
4.38k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
4.38k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
644
    case IKEV2_PAYLOAD_KE | IKED_E:
224
644
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
644
      break;
226
993
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
1.77k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
1.77k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
1.77k
          payload);
230
1.77k
      break;
231
410
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
410
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
410
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
1.77k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
1.77k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
1.77k
      break;
238
773
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
773
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
773
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
57
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
57
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
57
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
1.12k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
1.12k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
1.12k
      break;
249
812
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
812
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
812
      break;
252
351
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
1.27k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
1.27k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
1.27k
      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
1.30k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
1.30k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
1.30k
      break;
265
3.33k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
3.33k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
3.33k
      break;
268
4.09k
    default:
269
4.09k
      print_hex(msgbuf, offset,
270
4.09k
          betoh16(pld.pld_length) - sizeof(pld));
271
4.09k
      break;
272
21.7k
    }
273
274
21.7k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
70
      (void)ikev2_send_informational(env, msg);
276
70
      return (-1);
277
70
    }
278
279
    /* Encrypted payloads must appear last */
280
21.6k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
21.6k
        (payload == IKEV2_PAYLOAD_SKF))
282
2
      return (0);
283
284
21.6k
    payload = pld.pld_nextpayload;
285
21.6k
    offset += left;
286
21.6k
    total -= left;
287
21.6k
  }
288
289
456
  return (0);
290
713
}
291
292
int
293
ikev2_validate_sa(struct iked_message *msg, size_t offset, size_t left,
294
    struct ikev2_sa_proposal *sap)
295
5.47k
{
296
5.47k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
5.47k
  size_t     sap_length;
298
299
5.47k
  if (left < sizeof(*sap)) {
300
1.96k
    log_debug("%s: malformed payload: too short for header "
301
1.96k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
1.96k
    return (-1);
303
1.96k
  }
304
3.51k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
3.51k
  sap_length = betoh16(sap->sap_length);
307
3.51k
  if (sap_length < sizeof(*sap)) {
308
592
    log_debug("%s: malformed payload: shorter than minimum header "
309
592
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
592
    return (-1);
311
592
  }
312
2.92k
  if (left < sap_length) {
313
298
    log_debug("%s: malformed payload: too long for actual payload "
314
298
        "size (%zu < %zu)", __func__, left, sap_length);
315
298
    return (-1);
316
298
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
2.62k
  if (!sap->sap_more && left != sap_length) {
322
10
    log_debug("%s: malformed payload: SA payload length mismatches "
323
10
        "single proposal substructure length (%zu != %zu)",
324
10
        __func__, left, sap_length);
325
10
    return (-1);
326
10
  }
327
  /*
328
   * If there are more than one proposal, there must be bytes
329
   * left in the payload.
330
   */
331
2.61k
  if (sap->sap_more && left <= sap_length) {
332
66
    log_debug("%s: malformed payload: SA payload too small for "
333
66
        "further proposals (%zu <= %zu)", __func__,
334
66
        left, sap_length);
335
66
    return (-1);
336
66
  }
337
2.54k
  return (0);
338
2.61k
}
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
4.38k
{
344
4.38k
  struct ikev2_sa_proposal   sap;
345
4.38k
  struct iked_proposal    *prop = NULL;
346
4.38k
  uint32_t       spi32;
347
4.38k
  uint64_t       spi = 0, spi64;
348
4.38k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
4.38k
  int        r;
350
4.38k
  struct iked_proposals   *props;
351
4.38k
  size_t         total;
352
353
5.47k
  do {
354
5.47k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
2.92k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
2.54k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
2.54k
    props = &msg->msg_parent->msg_proposals;
361
362
2.54k
    offset += sizeof(sap);
363
2.54k
    left -= sizeof(sap);
364
365
2.54k
    if (sap.sap_spisize) {
366
381
      if (left < sap.sap_spisize) {
367
69
        log_debug("%s: malformed payload: SPI larger than "
368
69
            "actual payload (%zu < %d)", __func__, left,
369
69
            sap.sap_spisize);
370
69
        return (-1);
371
69
      }
372
312
      if (total < sap.sap_spisize) {
373
66
        log_debug("%s: malformed payload: SPI larger than "
374
66
            "proposal (%zu < %d)", __func__, total,
375
66
            sap.sap_spisize);
376
66
        return (-1);
377
66
      }
378
246
      switch (sap.sap_spisize) {
379
80
      case 4:
380
80
        memcpy(&spi32, msgbuf + offset, 4);
381
80
        spi = betoh32(spi32);
382
80
        break;
383
98
      case 8:
384
98
        memcpy(&spi64, msgbuf + offset, 8);
385
98
        spi = betoh64(spi64);
386
98
        break;
387
68
      default:
388
68
        log_debug("%s: unsupported SPI size %d",
389
68
            __func__, sap.sap_spisize);
390
68
        return (-1);
391
246
      }
392
393
178
      offset += sap.sap_spisize;
394
178
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
178
      total -= sap.sap_spisize;
398
178
    }
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
2.34k
    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
2.34k
    log_debug("%s: more %d reserved %d length %d"
411
2.34k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
2.34k
        __func__, sap.sap_more, sap.sap_reserved,
413
2.34k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
2.34k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
2.34k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
2.34k
    if (ikev2_msg_frompeer(msg)) {
418
3
      if ((msg->msg_parent->msg_prop = config_add_proposal(props,
419
3
          sap.sap_proposalnr, sap.sap_protoid)) == NULL) {
420
3
        log_debug("%s: invalid proposal", __func__);
421
3
        return (-1);
422
3
      }
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
2.34k
    if (sap.sap_transforms) {
436
1.37k
      r = ikev2_pld_xform(env, msg, offset, total);
437
1.37k
      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
1.37k
      } else if (r != 0) {
445
1.05k
        log_debug("%s: invalid proposal transforms",
446
1.05k
            __func__);
447
1.05k
        return (-1);
448
1.05k
      }
449
1.37k
    }
450
451
1.28k
    offset += total;
452
1.28k
    left -= total;
453
1.28k
  } while (sap.sap_more);
454
455
190
  return (0);
456
4.38k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
1.76k
{
462
1.76k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
1.76k
  size_t     xfrm_length;
464
465
1.76k
  if (total < sizeof(*xfrm)) {
466
168
    log_debug("%s: malformed payload: too short for header "
467
168
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
168
    return (-1);
469
168
  }
470
1.59k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
1.59k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
1.59k
  if (xfrm_length < sizeof(*xfrm)) {
474
129
    log_debug("%s: malformed payload: shorter than minimum header "
475
129
        "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm));
476
129
    return (-1);
477
129
  }
478
1.46k
  if (total < xfrm_length) {
479
113
    log_debug("%s: malformed payload: too long for payload size "
480
113
        "(%zu < %zu)", __func__, total, xfrm_length);
481
113
    return (-1);
482
113
  }
483
484
1.35k
  return (0);
485
1.46k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
1.76k
{
491
1.76k
  struct ikev2_transform     xfrm;
492
1.76k
  char         id[BUFSIZ];
493
1.76k
  int        ret = 0;
494
1.76k
  int        r;
495
1.76k
  size_t         xfrm_length;
496
497
1.76k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
410
    return (-1);
499
500
1.35k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
1.35k
  switch (xfrm.xfrm_type) {
503
334
  case IKEV2_XFORMTYPE_ENCR:
504
334
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
334
        ikev2_xformencr_map), sizeof(id));
506
334
    break;
507
434
  case IKEV2_XFORMTYPE_PRF:
508
434
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
434
        ikev2_xformprf_map), sizeof(id));
510
434
    break;
511
67
  case IKEV2_XFORMTYPE_INTEGR:
512
67
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
513
67
        ikev2_xformauth_map), sizeof(id));
514
67
    break;
515
68
  case IKEV2_XFORMTYPE_DH:
516
68
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
68
        ikev2_xformdh_map), sizeof(id));
518
68
    break;
519
66
  case IKEV2_XFORMTYPE_ESN:
520
66
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
521
66
        ikev2_xformesn_map), sizeof(id));
522
66
    break;
523
381
  default:
524
381
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
381
    break;
526
1.35k
  }
527
528
1.35k
  log_debug("%s: more %d reserved %d length %zu"
529
1.35k
      " type %s id %s",
530
1.35k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
1.35k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
1.35k
  msg->msg_attrlength = 0;
537
1.35k
  if (xfrm_length > sizeof(xfrm)) {
538
839
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
839
        xfrm_length - sizeof(xfrm)) != 0) {
540
568
      return (-1);
541
568
    }
542
839
  }
543
544
782
  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
782
  offset += xfrm_length;
561
782
  total -= xfrm_length;
562
782
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
389
    ret = ikev2_pld_xform(env, msg, offset, total);
564
393
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
79
    log_debug("%s: less data than specified, %zu bytes left",
567
79
        __func__, total);
568
79
    ret = -1;
569
79
  }
570
571
782
  return (ret);
572
782
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
1.91k
{
578
1.91k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
1.91k
  if (total < sizeof(*attr)) {
581
104
    log_debug("%s: malformed payload: too short for header "
582
104
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
104
    return (-1);
584
104
  }
585
1.80k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
1.80k
  return (0);
588
1.91k
}
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
1.91k
{
594
1.91k
  struct ikev2_attribute     attr;
595
1.91k
  unsigned int       type;
596
1.91k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
1.91k
  int        ret = 0;
598
1.91k
  size_t         attr_length;
599
600
1.91k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
104
    return (-1);
602
603
1.80k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
1.80k
  log_debug("%s: attribute type %s length %d total %zu",
606
1.80k
      __func__, print_map(type, ikev2_attrtype_map),
607
1.80k
      betoh16(attr.attr_length), total);
608
609
1.80k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
1.07k
    offset += sizeof(attr);
612
1.07k
    total -= sizeof(attr);
613
614
1.07k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
34
      msg->msg_attrlength = betoh16(attr.attr_length);
616
1.07k
  } else {
617
    /* Type-Length-Value attribute */
618
732
    attr_length = betoh16(attr.attr_length);
619
732
    if (attr_length < sizeof(attr)) {
620
244
      log_debug("%s: malformed payload: shorter than "
621
244
          "minimum header size (%zu < %zu)", __func__,
622
244
          attr_length, sizeof(attr));
623
244
      return (-1);
624
244
    }
625
488
    if (total < attr_length) {
626
220
      log_debug("%s: malformed payload: attribute larger "
627
220
          "than actual payload (%zu < %zu)", __func__,
628
220
          total, attr_length);
629
220
      return (-1);
630
220
    }
631
268
    print_hex(msgbuf, offset + sizeof(attr),
632
268
        attr_length - sizeof(attr));
633
268
    offset += attr_length;
634
268
    total -= attr_length;
635
268
  }
636
637
1.34k
  if (total > 0) {
638
    /* Next attribute */
639
1.07k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
1.07k
  }
641
642
1.34k
  return (ret);
643
1.80k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
644
{
649
644
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
644
  if (left < sizeof(*kex)) {
652
440
    log_debug("%s: malformed payload: too short for header "
653
440
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
440
    return (-1);
655
440
  }
656
204
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
204
  return (0);
659
644
}
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
644
{
665
644
  struct ikev2_keyexchange   kex;
666
644
  uint8_t       *buf;
667
644
  size_t         len;
668
644
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
644
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
440
    return (-1);
672
673
204
  log_debug("%s: dh group %s reserved %d", __func__,
674
204
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
204
      betoh16(kex.kex_reserved));
676
677
204
  buf = msgbuf + offset + sizeof(kex);
678
204
  len = left - sizeof(kex);
679
680
204
  if (len == 0) {
681
68
    log_debug("%s: malformed payload: no KE data given", __func__);
682
68
    return (-1);
683
68
  }
684
685
136
  print_hex(buf, 0, len);
686
687
136
  if (ikev2_msg_frompeer(msg)) {
688
3
    if (msg->msg_parent->msg_ke != NULL) {
689
1
      log_info("%s: duplicate KE payload", __func__);
690
1
      return (-1);
691
1
    }
692
2
    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
2
    msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup);
697
2
  }
698
699
135
  return (0);
700
136
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
1.77k
{
706
1.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
1.77k
  if (left < sizeof(*id)) {
709
893
    log_debug("%s: malformed payload: too short for header "
710
893
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
893
    return (-1);
712
893
  }
713
880
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
880
  if (id->id_type == IKEV2_ID_NONE) {
716
222
    log_debug("%s: malformed payload: invalid ID type.",
717
222
        __func__);
718
222
    return (-1);
719
222
  }
720
721
658
  return (0);
722
880
}
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
1.77k
{
728
1.77k
  uint8_t       *ptr;
729
1.77k
  struct ikev2_id      id;
730
1.77k
  size_t         len;
731
1.77k
  struct iked_id      *idp, idb;
732
1.77k
  const struct iked_sa    *sa = msg->msg_sa;
733
1.77k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
1.77k
  char         idstr[IKED_ID_SIZE];
735
736
1.77k
  if (ikev2_validate_id(msg, offset, left, &id))
737
1.11k
    return (-1);
738
739
658
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
658
  ptr = msgbuf + offset;
743
658
  len = left;
744
745
658
  idb.id_type = id.id_type;
746
658
  idb.id_offset = sizeof(id);
747
658
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
658
  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
658
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
658
  if (!ikev2_msg_frompeer(msg)) {
759
648
    ibuf_free(idb.id_buf);
760
648
    return (0);
761
648
  }
762
763
10
  if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ||
764
10
      (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi)))
765
6
    idp = &msg->msg_parent->msg_peerid;
766
4
  else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr)
767
4
    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
10
  if (idp->id_type) {
775
2
    ibuf_free(idb.id_buf);
776
2
    log_debug("%s: duplicate id payload", __func__);
777
2
    return (-1);
778
2
  }
779
780
8
  idp->id_buf = idb.id_buf;
781
8
  idp->id_offset = idb.id_offset;
782
8
  idp->id_type = idb.id_type;
783
784
8
  return (0);
785
10
}
786
787
int
788
ikev2_validate_cert(struct iked_message *msg, size_t offset, size_t left,
789
    struct ikev2_cert *cert)
790
410
{
791
410
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
410
  if (left < sizeof(*cert)) {
794
75
    log_debug("%s: malformed payload: too short for header "
795
75
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
75
    return (-1);
797
75
  }
798
335
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
335
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
24
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
24
    return (-1);
802
24
  }
803
804
311
  return (0);
805
335
}
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
410
{
811
410
  struct ikev2_cert    cert;
812
410
  uint8_t       *buf;
813
410
  size_t         len;
814
410
  struct iked_id      *certid;
815
410
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
410
  const struct iked_sa    *sa = msg->msg_sa;
817
410
  int        i;
818
819
410
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
99
    return (-1);
821
311
  offset += sizeof(cert);
822
823
311
  buf = msgbuf + offset;
824
311
  len = left - sizeof(cert);
825
826
311
  log_debug("%s: type %s length %zu",
827
311
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
311
  print_hex(buf, 0, len);
830
831
311
  if (!ikev2_msg_frompeer(msg))
832
160
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
151
  if (cert.cert_type == IKEV2_CERT_BUNDLE) {
836
34
    log_debug("%s: ignoring IKEV2_CERT_BUNDLE",
837
34
       SPI_SA(sa, __func__));
838
34
    return (0);
839
34
  }
840
841
117
  certid = &msg->msg_parent->msg_cert;
842
117
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
344
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
274
      certid = &msg->msg_parent->msg_scert[i];
846
274
      if (!certid->id_type)
847
33
        break;
848
274
    }
849
103
    if (certid->id_type) {
850
70
      log_debug("%s: too many cert payloads, ignoring",
851
70
         SPI_SA(sa, __func__));
852
70
      return (0);
853
70
    }
854
103
  }
855
856
47
  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
47
  certid->id_type = cert.cert_type;
861
47
  certid->id_offset = 0;
862
863
47
  return (0);
864
47
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
1.77k
{
870
1.77k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
1.77k
  if (left < sizeof(*cert)) {
873
406
    log_debug("%s: malformed payload: too short for header "
874
406
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
406
    return (-1);
876
406
  }
877
1.36k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
1.36k
  return (0);
880
1.77k
}
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
1.77k
{
886
1.77k
  struct ikev2_cert    cert;
887
1.77k
  struct iked_certreq   *cr;
888
1.77k
  uint8_t       *buf;
889
1.77k
  ssize_t        len;
890
1.77k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
1.77k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
406
    return (-1);
894
1.36k
  offset += sizeof(cert);
895
896
1.36k
  buf = msgbuf + offset;
897
1.36k
  len = left - sizeof(cert);
898
899
1.36k
  log_debug("%s: type %s length %zd",
900
1.36k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
1.36k
  print_hex(buf, 0, len);
903
904
1.36k
  if (!ikev2_msg_frompeer(msg))
905
1.26k
    return (0);
906
907
108
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
33
    if (len == 0) {
909
22
      log_info("%s: invalid length 0", __func__);
910
22
      return (0);
911
22
    }
912
11
    if ((len % SHA_DIGEST_LENGTH) != 0) {
913
1
      log_info("%s: invalid certificate request",
914
1
          __func__);
915
1
      return (-1);
916
1
    }
917
11
  }
918
919
85
  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
85
  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
85
  cr->cr_type = cert.cert_type;
929
85
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
85
  return (0);
932
85
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
773
{
938
773
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
773
  if (left < sizeof(*auth)) {
941
130
    log_debug("%s: malformed payload: too short for header "
942
130
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
130
    return (-1);
944
130
  }
945
643
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
643
  if (auth->auth_method == 0) {
948
325
    log_info("%s: malformed payload: invalid auth method",
949
325
        __func__);
950
325
    return (-1);
951
325
  }
952
953
318
  return (0);
954
643
}
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
773
{
960
773
  struct ikev2_auth    auth;
961
773
  struct iked_id      *idp;
962
773
  uint8_t       *buf;
963
773
  size_t         len;
964
773
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
773
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
455
    return (-1);
968
318
  offset += sizeof(auth);
969
970
318
  buf = msgbuf + offset;
971
318
  len = left - sizeof(auth);
972
973
318
  log_debug("%s: method %s length %zu",
974
318
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
318
  print_hex(buf, 0, len);
977
978
318
  if (!ikev2_msg_frompeer(msg))
979
315
    return (0);
980
981
3
  idp = &msg->msg_parent->msg_auth;
982
3
  if (idp->id_type) {
983
1
    log_debug("%s: duplicate auth payload", __func__);
984
1
    return (-1);
985
1
  }
986
987
2
  ibuf_free(idp->id_buf);
988
2
  idp->id_type = auth.auth_method;
989
2
  idp->id_offset = 0;
990
2
  if ((idp->id_buf = ibuf_new(buf, len)) == NULL)
991
0
    return (-1);
992
993
2
  return (0);
994
2
}
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
57
{
1000
57
  size_t     len;
1001
57
  uint8_t   *buf;
1002
57
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
57
  buf = msgbuf + offset;
1005
57
  len = left;
1006
1007
57
  if (len == 0) {
1008
18
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
18
    return (-1);
1010
18
  }
1011
1012
39
  print_hex(buf, 0, len);
1013
1014
39
  if (ikev2_msg_frompeer(msg)) {
1015
2
    if (msg->msg_parent->msg_nonce != NULL) {
1016
1
      log_info("%s: duplicate NONCE payload", __func__);
1017
1
      return (-1);
1018
1
    }
1019
1
    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
1
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
1
  }
1025
1026
38
  return (0);
1027
39
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
1.12k
{
1033
1.12k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
1.12k
  if (left < sizeof(*n)) {
1036
549
    log_debug("%s: malformed payload: too short for header "
1037
549
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
549
    return (-1);
1039
549
  }
1040
580
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
580
  return (0);
1043
1.12k
}
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
1.12k
{
1049
1.12k
  struct ikev2_notify  n;
1050
1.12k
  const struct iked_sa  *sa = msg->msg_sa;
1051
1.12k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
1.12k
  uint32_t     spi32;
1053
1.12k
  uint64_t     spi64;
1054
1.12k
  struct iked_spi   *rekey;
1055
1.12k
  uint16_t     type;
1056
1.12k
  uint16_t     signature_hash;
1057
1058
1.12k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
549
    return (-1);
1060
580
  type = betoh16(n.n_type);
1061
1062
580
  log_debug("%s: protoid %s spisize %d type %s",
1063
580
      __func__,
1064
580
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
580
      print_map(type, ikev2_n_map));
1066
1067
580
  left -= sizeof(n);
1068
580
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
580
  print_hex(buf, 0, left);
1072
1073
580
  if (!ikev2_msg_frompeer(msg))
1074
261
    return (0);
1075
1076
319
  switch (type) {
1077
13
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
50
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
50
    if (left != sizeof(md)) {
1080
2
      log_debug("%s: malformed payload: hash size mismatch"
1081
2
          " (%zu != %zu)", __func__, left, sizeof(md));
1082
2
      return (-1);
1083
2
    }
1084
48
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
48
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
48
    if (memcmp(buf, md, left) != 0) {
1088
48
      log_debug("%s: %s detected NAT", __func__,
1089
48
          print_map(type, ikev2_n_map));
1090
48
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
12
        msg->msg_parent->msg_nat_detected
1092
12
            |= IKED_MSG_NAT_SRC_IP;
1093
36
      else
1094
36
        msg->msg_parent->msg_nat_detected
1095
36
            |= IKED_MSG_NAT_DST_IP;
1096
48
    }
1097
48
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
48
    msg->msg_parent->msg_natt_rcvd = 1;
1100
48
    break;
1101
1
  case IKEV2_N_AUTHENTICATION_FAILED:
1102
1
    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
1
    if (!sa->sa_hdr.sh_initiator) {
1113
1
      if (!sa_stateok(sa, IKEV2_STATE_VALID)) {
1114
1
        log_debug("%s: ignoring AUTHENTICATION_FAILED"
1115
1
            " from unauthenticated initiator",
1116
1
            __func__);
1117
1
        return (-1);
1118
1
      }
1119
1
    } 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
11
  case IKEV2_N_INVALID_KE_PAYLOAD:
1131
11
    if (sa_stateok(sa, IKEV2_STATE_VALID) &&
1132
11
        !msg->msg_e) {
1133
0
      log_debug("%s: INVALID_KE_PAYLOAD not encrypted",
1134
0
          __func__);
1135
0
      return (-1);
1136
0
    }
1137
11
    if (left != sizeof(msg->msg_parent->msg_group)) {
1138
1
      log_debug("%s: malformed payload: group size mismatch"
1139
1
          " (%zu != %zu)", __func__, left,
1140
1
          sizeof(msg->msg_parent->msg_group));
1141
1
      return (-1);
1142
1
    }
1143
10
    memcpy(&msg->msg_parent->msg_group, buf, left);
1144
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE;
1145
10
    break;
1146
10
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
10
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
10
    break;
1154
17
  case IKEV2_N_REKEY_SA:
1155
17
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
17
    if (left != n.n_spisize) {
1160
1
      log_debug("%s: malformed notification", __func__);
1161
1
      return (-1);
1162
1
    }
1163
16
    rekey = &msg->msg_parent->msg_rekey;
1164
16
    if (rekey->spi != 0) {
1165
1
      log_debug("%s: rekeying of multiple SAs not supported",
1166
1
          __func__);
1167
1
      return (-1);
1168
1
    }
1169
15
    switch (n.n_spisize) {
1170
13
    case 4:
1171
13
      memcpy(&spi32, buf, left);
1172
13
      rekey->spi = betoh32(spi32);
1173
13
      break;
1174
1
    case 8:
1175
1
      memcpy(&spi64, buf, left);
1176
1
      rekey->spi = betoh64(spi64);
1177
1
      break;
1178
1
    default:
1179
1
      log_debug("%s: invalid spi size %d", __func__,
1180
1
          n.n_spisize);
1181
1
      return (-1);
1182
15
    }
1183
14
    rekey->spi_size = n.n_spisize;
1184
14
    rekey->spi_protoid = n.n_protoid;
1185
1186
14
    log_debug("%s: rekey %s spi %s", __func__,
1187
14
        print_map(n.n_protoid, ikev2_saproto_map),
1188
14
        print_spi(rekey->spi, n.n_spisize));
1189
14
    break;
1190
12
  case IKEV2_N_TEMPORARY_FAILURE:
1191
12
    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
12
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
12
    break;
1198
20
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
20
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
20
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
20
        sizeof(msg->msg_parent->msg_transform)) {
1206
10
      log_debug("%s: ignoring malformed ipcomp notification",
1207
10
          __func__);
1208
10
      return (0);
1209
10
    }
1210
10
    memcpy(&msg->msg_parent->msg_cpi, buf,
1211
10
        sizeof(msg->msg_parent->msg_cpi));
1212
10
    memcpy(&msg->msg_parent->msg_transform,
1213
10
        buf + sizeof(msg->msg_parent->msg_cpi),
1214
10
        sizeof(msg->msg_parent->msg_transform));
1215
1216
10
    log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__,
1217
10
        msg->msg_parent->msg_response ? "res" : "req",
1218
10
        betoh16(msg->msg_parent->msg_cpi),
1219
10
        print_map(msg->msg_parent->msg_transform,
1220
10
        ikev2_ipcomp_map), left);
1221
1222
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED;
1223
10
    break;
1224
10
  case IKEV2_N_CHILD_SA_NOT_FOUND:
1225
10
    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
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND;
1231
10
    break;
1232
10
  case IKEV2_N_NO_PROPOSAL_CHOSEN:
1233
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN;
1234
10
    break;
1235
28
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
28
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
28
    if (left != 0) {
1242
18
      log_debug("%s: ignoring malformed mobike"
1243
18
          " notification: %zu", __func__, left);
1244
18
      return (0);
1245
18
    }
1246
10
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
10
    break;
1248
28
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
28
    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
28
    if (left != 0) {
1255
10
      log_debug("%s: ignoring malformed transport mode"
1256
10
          " notification: %zu", __func__, left);
1257
10
      return (0);
1258
10
    }
1259
18
    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
18
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
18
    break;
1268
18
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
18
    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
18
    if (!sa->sa_mobike) {
1275
18
      log_debug("%s: ignoring update sa addresses"
1276
18
          " notification w/o mobike: %zu", __func__, left);
1277
18
      return (0);
1278
18
    }
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
34
  case IKEV2_N_COOKIE2:
1287
34
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
34
    if (!sa->sa_mobike) {
1293
34
      log_debug("%s: ignoring cookie2 notification"
1294
34
          " w/o mobike: %zu", __func__, left);
1295
34
      return (0);
1296
34
    }
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
1
  case IKEV2_N_COOKIE:
1310
1
    if (msg->msg_e) {
1311
1
      log_debug("%s: N_COOKIE encrypted",
1312
1
          __func__);
1313
1
      return (-1);
1314
1
    }
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
1
  case IKEV2_N_FRAGMENTATION_SUPPORTED:
1331
1
    if (msg->msg_e) {
1332
1
      log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted",
1333
1
          __func__);
1334
1
      return (-1);
1335
1
    }
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
1
  case IKEV2_N_SIGNATURE_HASH_ALGORITHMS:
1344
1
    if (msg->msg_e) {
1345
1
      log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted",
1346
1
          __func__);
1347
1
      return (-1);
1348
1
    }
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
319
  }
1379
1380
219
  return (0);
1381
319
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
812
{
1387
812
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
812
  if (left < sizeof(*del)) {
1390
110
    log_debug("%s: malformed payload: too short for header "
1391
110
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
110
    return (-1);
1393
110
  }
1394
702
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
702
  if (del->del_protoid == 0) {
1397
22
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
22
    return (-1);
1399
22
  }
1400
1401
680
  return (0);
1402
702
}
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
812
{
1408
812
  struct ikev2_delete  del;
1409
812
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
812
  size_t       cnt, sz, len;
1411
1412
812
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
132
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
680
  if (ikev2_msg_frompeer(msg) &&
1417
680
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
680
  cnt = betoh16(del.del_nspi);
1421
680
  sz = del.del_spisize;
1422
1423
680
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
680
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
680
      sz, cnt);
1426
1427
680
  if (msg->msg_parent->msg_del_protoid) {
1428
638
    log_debug("%s: duplicate delete payload", __func__);
1429
638
    return (0);
1430
638
  }
1431
1432
42
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
42
  msg->msg_parent->msg_del_cnt = cnt;
1434
42
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
42
  buf = msgbuf + offset + sizeof(del);
1437
42
  len = left - sizeof(del);
1438
42
  if (len == 0 || sz == 0 || cnt == 0)
1439
34
    return (0);
1440
1441
8
  if ((len / sz) != cnt) {
1442
7
    log_debug("%s: invalid payload length %zu/%zu != %zu",
1443
7
        __func__, len, sz, cnt);
1444
7
    return (-1);
1445
7
  }
1446
1447
1
  print_hex(buf, 0, len);
1448
1449
1
  msg->msg_parent->msg_del_buf = ibuf_new(buf, len);
1450
1451
1
  return (0);
1452
8
}
1453
1454
int
1455
ikev2_validate_tss(struct iked_message *msg, size_t offset, size_t left,
1456
    struct ikev2_tsp *tsp)
1457
1.27k
{
1458
1.27k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
1.27k
  if (left < sizeof(*tsp)) {
1461
146
    log_debug("%s: malformed payload: too short for header "
1462
146
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
146
    return (-1);
1464
146
  }
1465
1.12k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
1.12k
  return (0);
1468
1.27k
}
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
1.27k
{
1474
1.27k
  struct ikev2_tsp     tsp;
1475
1.27k
  struct ikev2_ts      ts;
1476
1.27k
  size_t         ts_len, i;
1477
1478
1.27k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
146
    return (-1);
1480
1481
1.12k
  offset += sizeof(tsp);
1482
1.12k
  left -= sizeof(tsp);
1483
1484
1.12k
  log_debug("%s: count %d length %zu", __func__,
1485
1.12k
      tsp.tsp_count, left);
1486
1487
1.88k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
1.79k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
898
      return (-1);
1490
1491
895
    log_debug("%s: type %s protoid %u length %d "
1492
895
        "startport %u endport %u", __func__,
1493
895
        print_map(ts.ts_type, ikev2_ts_map),
1494
895
        ts.ts_protoid, betoh16(ts.ts_length),
1495
895
        betoh16(ts.ts_startport),
1496
895
        betoh16(ts.ts_endport));
1497
1498
895
    offset += sizeof(ts);
1499
895
    left -= sizeof(ts);
1500
1501
895
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
895
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
137
      return (-1);
1504
1505
758
    offset += ts_len;
1506
758
    left -= ts_len;
1507
758
  }
1508
1509
90
  return (0);
1510
1.12k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
1.79k
{
1516
1.79k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
1.79k
  size_t     ts_length;
1518
1519
1.79k
  if (left < sizeof(*ts)) {
1520
793
    log_debug("%s: malformed payload: too short for header "
1521
793
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
793
    return (-1);
1523
793
  }
1524
1.00k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
1.00k
  ts_length = betoh16(ts->ts_length);
1527
1.00k
  if (ts_length < sizeof(*ts)) {
1528
40
    log_debug("%s: malformed payload: shorter than minimum header "
1529
40
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
40
    return (-1);
1531
40
  }
1532
960
  if (left < ts_length) {
1533
65
    log_debug("%s: malformed payload: too long for payload size "
1534
65
        "(%zu < %zu)", __func__, left, ts_length);
1535
65
    return (-1);
1536
65
  }
1537
1538
895
  return (0);
1539
960
}
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
895
{
1545
895
  struct sockaddr_in     start4, end4;
1546
895
  struct sockaddr_in6    start6, end6;
1547
895
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
895
  uint8_t       *ptr;
1549
1550
895
  ptr = msgbuf + offset;
1551
1552
895
  switch (type) {
1553
242
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
242
    if (left < 2 * 4) {
1555
34
      log_debug("%s: malformed payload: too short "
1556
34
          "for ipv4 addr range (%zu < %u)",
1557
34
          __func__, left, 2 * 4);
1558
34
      return (-1);
1559
34
    }
1560
1561
208
    bzero(&start4, sizeof(start4));
1562
208
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
208
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
208
    ptr += 4;
1568
208
    left -= 4;
1569
1570
208
    bzero(&end4, sizeof(end4));
1571
208
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
208
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
208
    left -= 4;
1577
1578
208
    log_debug("%s: start %s end %s", __func__,
1579
208
        print_addr(&start4), print_addr(&end4));
1580
208
    break;
1581
93
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
93
    if (left < 2 * 16) {
1583
34
      log_debug("%s: malformed payload: too short "
1584
34
          "for ipv6 addr range (%zu < %u)",
1585
34
          __func__, left, 2 * 16);
1586
34
      return (-1);
1587
34
    }
1588
59
    bzero(&start6, sizeof(start6));
1589
59
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
59
    memcpy(&start6.sin6_addr, ptr, 16);
1594
59
    ptr += 16;
1595
59
    left -= 16;
1596
1597
59
    bzero(&end6, sizeof(end6));
1598
59
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
59
    memcpy(&end6.sin6_addr, ptr, 16);
1603
59
    left -= 16;
1604
1605
59
    log_debug("%s: start %s end %s", __func__,
1606
59
        print_addr(&start6), print_addr(&end6));
1607
59
    break;
1608
560
  default:
1609
560
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
560
    return (0);
1611
895
  }
1612
1613
267
  if (left > 0) {
1614
69
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
69
        __func__, left);
1616
69
    return (-1);
1617
69
  }
1618
1619
198
  return (0);
1620
267
}
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
1.30k
{
1876
1.30k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
1.30k
  if (left < sizeof(*cp)) {
1879
236
    log_debug("%s: malformed payload: too short for header "
1880
236
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
236
    return (-1);
1882
236
  }
1883
1.06k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
1.06k
  return (0);
1886
1.30k
}
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
1.30k
{
1892
1.30k
  struct ikev2_cp    cp;
1893
1.30k
  struct ikev2_cfg  *cfg;
1894
1.30k
  struct iked_addr  *addr;
1895
1.30k
  struct sockaddr_in  *in4;
1896
1.30k
  struct sockaddr_in6 *in6;
1897
1.30k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
1.30k
  uint8_t     *ptr;
1899
1.30k
  size_t       len;
1900
1.30k
  int      cfg_type;
1901
1902
1.30k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
236
    return (-1);
1904
1905
1.06k
  ptr = msgbuf + offset + sizeof(cp);
1906
1.06k
  len = left - sizeof(cp);
1907
1908
1.06k
  log_debug("%s: type %s length %zu",
1909
1.06k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
1.06k
  print_hex(ptr, 0, len);
1911
1912
2.18k
  while (len > 0) {
1913
1.34k
    if (len < sizeof(*cfg)) {
1914
102
      log_debug("%s: malformed payload: too short for cfg "
1915
102
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
102
      return (-1);
1917
102
    }
1918
1.23k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
1.23k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
1.23k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
1.23k
        betoh16(cfg->cfg_type),
1923
1.23k
        betoh16(cfg->cfg_length));
1924
1925
1.23k
    ptr += sizeof(*cfg);
1926
1.23k
    len -= sizeof(*cfg);
1927
1928
1.23k
    if (len < betoh16(cfg->cfg_length)) {
1929
121
      log_debug("%s: malformed payload: too short for "
1930
121
          "cfg_length (%zu < %u)", __func__, len,
1931
121
          betoh16(cfg->cfg_length));
1932
121
      return (-1);
1933
121
    }
1934
1935
1.11k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
1.11k
    cfg_type = betoh16(cfg->cfg_type);
1938
1.11k
    switch (cfg_type) {
1939
149
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
253
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
253
      if (!ikev2_msg_frompeer(msg))
1942
121
        break;
1943
132
      if (betoh16(cfg->cfg_length) == 0)
1944
78
        break;
1945
      /* XXX multiple-valued */
1946
54
      if (betoh16(cfg->cfg_length) < 4) {
1947
1
        log_debug("%s: malformed payload: too short "
1948
1
            "for ipv4 addr (%u < %u)",
1949
1
            __func__, betoh16(cfg->cfg_length), 4);
1950
1
        return (-1);
1951
1
      }
1952
53
      switch(cfg_type) {
1953
34
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1954
34
        if (msg->msg_parent->msg_cp_addr != NULL) {
1955
21
          log_debug("%s: address already set", __func__);
1956
21
          goto skip;
1957
21
        }
1958
13
        break;
1959
19
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1960
19
        if (msg->msg_parent->msg_cp_dns != NULL) {
1961
10
          log_debug("%s: dns already set", __func__);
1962
10
          goto skip;
1963
10
        }
1964
9
        break;
1965
9
      default:
1966
0
        break;
1967
53
      }
1968
22
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
1969
0
        log_debug("%s: malloc failed", __func__);
1970
0
        break;
1971
0
      }
1972
22
      addr->addr_af = AF_INET;
1973
22
      in4 = (struct sockaddr_in *)&addr->addr;
1974
22
      in4->sin_family = AF_INET;
1975
#ifdef HAVE_SOCKADDR_SA_LEN
1976
      in4->sin_len = sizeof(*in4);
1977
#endif
1978
22
      memcpy(&in4->sin_addr.s_addr, ptr, 4);
1979
22
      switch(cfg_type) {
1980
13
      case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1981
13
        msg->msg_parent->msg_cp_addr = addr;
1982
13
        log_debug("%s: IP4_ADDRESS %s", __func__,
1983
13
            print_addr(&addr->addr));
1984
13
        break;
1985
9
      case IKEV2_CFG_INTERNAL_IP4_DNS:
1986
9
        msg->msg_parent->msg_cp_dns = addr;
1987
9
        log_debug("%s: IP4_DNS %s", __func__,
1988
9
            print_addr(&addr->addr));
1989
9
        break;
1990
0
      default:
1991
0
        log_debug("%s: cfg %s", __func__,
1992
0
            print_addr(&addr->addr));
1993
0
        break;
1994
22
      }
1995
22
      break;
1996
196
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
289
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
289
      if (!ikev2_msg_frompeer(msg))
1999
233
        break;
2000
56
      if (betoh16(cfg->cfg_length) == 0)
2001
29
        break;
2002
      /* XXX multiple-valued */
2003
27
      if (betoh16(cfg->cfg_length) < 16) {
2004
1
        log_debug("%s: malformed payload: too short "
2005
1
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
1
            __func__, betoh16(cfg->cfg_length), 16);
2007
1
        return (-1);
2008
1
      }
2009
26
      switch(cfg_type) {
2010
15
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
15
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
10
          log_debug("%s: address6 already set", __func__);
2013
10
          goto skip;
2014
10
        }
2015
5
        break;
2016
11
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2017
11
        if (msg->msg_parent->msg_cp_dns != NULL) {
2018
10
          log_debug("%s: dns already set", __func__);
2019
10
          goto skip;
2020
10
        }
2021
1
        break;
2022
26
      }
2023
6
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
6
      addr->addr_af = AF_INET6;
2028
6
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
6
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
6
      memcpy(&in6->sin6_addr, ptr, 16);
2034
6
      switch(cfg_type) {
2035
5
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
5
        msg->msg_parent->msg_cp_addr6 = addr;
2037
5
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
5
            print_addr(&addr->addr));
2039
5
        break;
2040
1
      case IKEV2_CFG_INTERNAL_IP6_DNS:
2041
1
        msg->msg_parent->msg_cp_dns = addr;
2042
1
        log_debug("%s: IP6_DNS %s", __func__,
2043
1
            print_addr(&addr->addr));
2044
1
        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
6
      }
2050
6
      break;
2051
1.11k
    }
2052
2053
1.11k
 skip:
2054
1.11k
    ptr += betoh16(cfg->cfg_length);
2055
1.11k
    len -= betoh16(cfg->cfg_length);
2056
1.11k
  }
2057
2058
842
  if (!ikev2_msg_frompeer(msg))
2059
792
    return (0);
2060
2061
50
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
50
  return (0);
2064
842
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
3.33k
{
2070
3.33k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
3.33k
  if (left < sizeof(*hdr)) {
2073
1.26k
    log_debug("%s: malformed payload: too short for header "
2074
1.26k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
1.26k
    return (-1);
2076
1.26k
  }
2077
2.07k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
2.07k
  return (0);
2080
3.33k
}
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
3.33k
{
2086
3.33k
  struct eap_header    hdr;
2087
3.33k
  struct eap_message    *eap = NULL;
2088
3.33k
  const struct iked_sa    *sa = msg->msg_sa;
2089
3.33k
  size_t         len;
2090
2091
3.33k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
1.26k
    return (-1);
2093
2.07k
  len = betoh16(hdr.eap_length);
2094
2095
2.07k
  if (len < sizeof(*eap)) {
2096
861
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
861
        print_map(hdr.eap_code, eap_code_map),
2098
861
        hdr.eap_id, betoh16(hdr.eap_length));
2099
1.21k
  } else {
2100
    /* Now try to get the indicated length */
2101
1.21k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
477
      log_debug("%s: invalid EAP length", __func__);
2103
477
      return (-1);
2104
477
    }
2105
2106
737
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
737
        print_map(eap->eap_code, eap_code_map),
2108
737
        eap->eap_id, betoh16(eap->eap_length),
2109
737
        print_map(eap->eap_type, eap_type_map));
2110
2111
737
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
737
    msg->msg_parent->msg_eap.eam_found = 1;
2114
737
  }
2115
2116
1.59k
  return (0);
2117
2.07k
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
10.0k
{
119
10.0k
  log_debug("%s: header ispi %s rspi %s"
120
10.0k
      " nextpayload %s version 0x%02x exchange %s flags 0x%02x"
121
10.0k
      " msgid %d length %u response %d", __func__,
122
10.0k
      print_spi(betoh64(hdr->ike_ispi), 8),
123
10.0k
      print_spi(betoh64(hdr->ike_rspi), 8),
124
10.0k
      print_map(hdr->ike_nextpayload, ikev2_payload_map),
125
10.0k
      hdr->ike_version,
126
10.0k
      print_map(hdr->ike_exchange, ikev2_exchange_map),
127
10.0k
      hdr->ike_flags,
128
10.0k
      betoh32(hdr->ike_msgid),
129
10.0k
      betoh32(hdr->ike_length),
130
10.0k
      msg->msg_response);
131
132
10.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
10.0k
  offset += sizeof(*hdr);
138
139
10.0k
  return (ikev2_pld_payloads(env, msg, offset,
140
10.0k
      betoh32(hdr->ike_length), hdr->ike_nextpayload));
141
10.0k
}
142
143
int
144
ikev2_validate_pld(struct iked_message *msg, size_t offset, size_t left,
145
    struct ikev2_payload *pld)
146
202k
{
147
202k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
148
202k
  size_t     pld_length;
149
150
  /* We need at least the generic header. */
151
202k
  if (left < sizeof(*pld)) {
152
1.45k
    log_debug("%s: malformed payload: too short for generic "
153
1.45k
        "header (%zu < %zu)", __func__, left, sizeof(*pld));
154
1.45k
    return (-1);
155
1.45k
  }
156
201k
  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
201k
  pld_length = betoh16(pld->pld_length);
164
201k
  if (left < pld_length) {
165
4.27k
    log_debug("%s: malformed payload: shorter than specified "
166
4.27k
        "(%zu < %zu)", __func__, left, pld_length);
167
4.27k
    return (-1);
168
4.27k
  }
169
  /*
170
   * Sanity check the specified payload size, it must
171
   * be at least the size of the generic payload header.
172
   */
173
197k
  if (pld_length < sizeof(*pld)) {
174
1.66k
    log_debug("%s: malformed payload: shorter than minimum "
175
1.66k
        "header size (%zu < %zu)", __func__, pld_length,
176
1.66k
        sizeof(*pld));
177
1.66k
    return (-1);
178
1.66k
  }
179
180
195k
  return (0);
181
197k
}
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
10.0k
{
187
10.0k
  struct ikev2_payload   pld;
188
10.0k
  unsigned int     e;
189
10.0k
  int      ret;
190
10.0k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
191
10.0k
  size_t       total, left;
192
193
  /* Check if message was decrypted in an E payload */
194
10.0k
  e = msg->msg_e ? IKED_E : 0;
195
196
  /* Bytes left in datagram. */
197
10.0k
  total = length - offset;
198
199
204k
  while (payload != 0 && offset < length) {
200
202k
    if (ikev2_validate_pld(msg, offset, total, &pld))
201
7.39k
      return (-1);
202
203
195k
    log_debug("%s: %spayload %s"
204
195k
        " nextpayload %s critical 0x%02x length %d",
205
195k
        __func__, e ? "decrypted " : "",
206
195k
        print_map(payload, ikev2_payload_map),
207
195k
        print_map(pld.pld_nextpayload, ikev2_payload_map),
208
195k
        pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD,
209
195k
        betoh16(pld.pld_length));
210
211
    /* Skip over generic payload header. */
212
195k
    offset += sizeof(pld);
213
195k
    total -= sizeof(pld);
214
195k
    left = betoh16(pld.pld_length) - sizeof(pld);
215
195k
    ret = 0;
216
217
195k
    switch (payload | e) {
218
0
    case IKEV2_PAYLOAD_SA:
219
27.1k
    case IKEV2_PAYLOAD_SA | IKED_E:
220
27.1k
      ret = ikev2_pld_sa(env, &pld, msg, offset, left);
221
27.1k
      break;
222
0
    case IKEV2_PAYLOAD_KE:
223
5.93k
    case IKEV2_PAYLOAD_KE | IKED_E:
224
5.93k
      ret = ikev2_pld_ke(env, &pld, msg, offset, left);
225
5.93k
      break;
226
12.6k
    case IKEV2_PAYLOAD_IDi | IKED_E:
227
18.5k
    case IKEV2_PAYLOAD_IDr | IKED_E:
228
18.5k
      ret = ikev2_pld_id(env, &pld, msg, offset, left,
229
18.5k
          payload);
230
18.5k
      break;
231
5.21k
    case IKEV2_PAYLOAD_CERT | IKED_E:
232
5.21k
      ret = ikev2_pld_cert(env, &pld, msg, offset, left);
233
5.21k
      break;
234
0
    case IKEV2_PAYLOAD_CERTREQ:
235
10.2k
    case IKEV2_PAYLOAD_CERTREQ | IKED_E:
236
10.2k
      ret = ikev2_pld_certreq(env, &pld, msg, offset, left);
237
10.2k
      break;
238
7.98k
    case IKEV2_PAYLOAD_AUTH | IKED_E:
239
7.98k
      ret = ikev2_pld_auth(env, &pld, msg, offset, left);
240
7.98k
      break;
241
0
    case IKEV2_PAYLOAD_NONCE:
242
229
    case IKEV2_PAYLOAD_NONCE | IKED_E:
243
229
      ret = ikev2_pld_nonce(env, &pld, msg, offset, left);
244
229
      break;
245
0
    case IKEV2_PAYLOAD_NOTIFY:
246
24.5k
    case IKEV2_PAYLOAD_NOTIFY | IKED_E:
247
24.5k
      ret = ikev2_pld_notify(env, &pld, msg, offset, left);
248
24.5k
      break;
249
6.99k
    case IKEV2_PAYLOAD_DELETE | IKED_E:
250
6.99k
      ret = ikev2_pld_delete(env, &pld, msg, offset, left);
251
6.99k
      break;
252
4.44k
    case IKEV2_PAYLOAD_TSi | IKED_E:
253
16.3k
    case IKEV2_PAYLOAD_TSr | IKED_E:
254
16.3k
      ret = ikev2_pld_tss(env, &pld, msg, offset, left);
255
16.3k
      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
8.50k
    case IKEV2_PAYLOAD_CP | IKED_E:
263
8.50k
      ret = ikev2_pld_cp(env, &pld, msg, offset, left);
264
8.50k
      break;
265
16.1k
    case IKEV2_PAYLOAD_EAP | IKED_E:
266
16.1k
      ret = ikev2_pld_eap(env, &pld, msg, offset, left);
267
16.1k
      break;
268
47.8k
    default:
269
47.8k
      print_hex(msgbuf, offset,
270
47.8k
          betoh16(pld.pld_length) - sizeof(pld));
271
47.8k
      break;
272
195k
    }
273
274
195k
    if (ret != 0 && ikev2_msg_frompeer(msg)) {
275
706
      (void)ikev2_send_informational(env, msg);
276
706
      return (-1);
277
706
    }
278
279
    /* Encrypted payloads must appear last */
280
194k
    if ((payload == IKEV2_PAYLOAD_SK) ||
281
194k
        (payload == IKEV2_PAYLOAD_SKF))
282
4
      return (0);
283
284
194k
    payload = pld.pld_nextpayload;
285
194k
    offset += left;
286
194k
    total -= left;
287
194k
  }
288
289
1.95k
  return (0);
290
10.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
31.4k
{
296
31.4k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
297
31.4k
  size_t     sap_length;
298
299
31.4k
  if (left < sizeof(*sap)) {
300
13.3k
    log_debug("%s: malformed payload: too short for header "
301
13.3k
        "(%zu < %zu)", __func__, left, sizeof(*sap));
302
13.3k
    return (-1);
303
13.3k
  }
304
18.0k
  memcpy(sap, msgbuf + offset, sizeof(*sap));
305
306
18.0k
  sap_length = betoh16(sap->sap_length);
307
18.0k
  if (sap_length < sizeof(*sap)) {
308
4.88k
    log_debug("%s: malformed payload: shorter than minimum header "
309
4.88k
        "size (%zu < %zu)", __func__, sap_length, sizeof(*sap));
310
4.88k
    return (-1);
311
4.88k
  }
312
13.1k
  if (left < sap_length) {
313
2.19k
    log_debug("%s: malformed payload: too long for actual payload "
314
2.19k
        "size (%zu < %zu)", __func__, left, sap_length);
315
2.19k
    return (-1);
316
2.19k
  }
317
  /*
318
   * If there is only one proposal, sap_length must be the
319
   * total payload size.
320
   */
321
10.9k
  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
10.9k
  if (sap->sap_more && left <= sap_length) {
332
828
    log_debug("%s: malformed payload: SA payload too small for "
333
828
        "further proposals (%zu <= %zu)", __func__,
334
828
        left, sap_length);
335
828
    return (-1);
336
828
  }
337
10.0k
  return (0);
338
10.9k
}
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
27.1k
{
344
27.1k
  struct ikev2_sa_proposal   sap;
345
27.1k
  struct iked_proposal    *prop = NULL;
346
27.1k
  uint32_t       spi32;
347
27.1k
  uint64_t       spi = 0, spi64;
348
27.1k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
349
27.1k
  int        r;
350
27.1k
  struct iked_proposals   *props;
351
27.1k
  size_t         total;
352
353
31.4k
  do {
354
31.4k
    if (ikev2_validate_sa(msg, offset, left, &sap))
355
21.3k
      return (-1);
356
357
    /* Assumed size of the first proposals, including SPI if present. */
358
10.0k
    total = (betoh16(sap.sap_length) - sizeof(sap));
359
360
10.0k
    props = &msg->msg_parent->msg_proposals;
361
362
10.0k
    offset += sizeof(sap);
363
10.0k
    left -= sizeof(sap);
364
365
10.0k
    if (sap.sap_spisize) {
366
1.38k
      if (left < sap.sap_spisize) {
367
634
        log_debug("%s: malformed payload: SPI larger than "
368
634
            "actual payload (%zu < %d)", __func__, left,
369
634
            sap.sap_spisize);
370
634
        return (-1);
371
634
      }
372
748
      if (total < sap.sap_spisize) {
373
132
        log_debug("%s: malformed payload: SPI larger than "
374
132
            "proposal (%zu < %d)", __func__, total,
375
132
            sap.sap_spisize);
376
132
        return (-1);
377
132
      }
378
616
      switch (sap.sap_spisize) {
379
286
      case 4:
380
286
        memcpy(&spi32, msgbuf + offset, 4);
381
286
        spi = betoh32(spi32);
382
286
        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
616
      }
392
393
486
      offset += sap.sap_spisize;
394
486
      left -= sap.sap_spisize;
395
396
      /* Assumed size of the proposal, now without SPI. */
397
486
      total -= sap.sap_spisize;
398
486
    }
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.18k
    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.18k
    log_debug("%s: more %d reserved %d length %d"
411
9.18k
        " proposal #%d protoid %s spisize %d xforms %d spi %s",
412
9.18k
        __func__, sap.sap_more, sap.sap_reserved,
413
9.18k
        betoh16(sap.sap_length), sap.sap_proposalnr,
414
9.18k
        print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize,
415
9.18k
        sap.sap_transforms, print_spi(spi, sap.sap_spisize));
416
417
9.18k
    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.11k
    if (sap.sap_transforms) {
436
5.13k
      r = ikev2_pld_xform(env, msg, offset, total);
437
5.13k
      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.13k
      } else if (r != 0) {
445
4.07k
        log_debug("%s: invalid proposal transforms",
446
4.07k
            __func__);
447
4.07k
        return (-1);
448
4.07k
      }
449
5.13k
    }
450
451
5.03k
    offset += total;
452
5.03k
    left -= total;
453
5.03k
  } while (sap.sap_more);
454
455
733
  return (0);
456
27.1k
}
457
458
int
459
ikev2_validate_xform(struct iked_message *msg, size_t offset, size_t total,
460
    struct ikev2_transform *xfrm)
461
6.66k
{
462
6.66k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
463
6.66k
  size_t     xfrm_length;
464
465
6.66k
  if (total < sizeof(*xfrm)) {
466
551
    log_debug("%s: malformed payload: too short for header "
467
551
        "(%zu < %zu)", __func__, total, sizeof(*xfrm));
468
551
    return (-1);
469
551
  }
470
6.11k
  memcpy(xfrm, msgbuf + offset, sizeof(*xfrm));
471
472
6.11k
  xfrm_length = betoh16(xfrm->xfrm_length);
473
6.11k
  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
4.99k
  if (total < xfrm_length) {
479
599
    log_debug("%s: malformed payload: too long for payload size "
480
599
        "(%zu < %zu)", __func__, total, xfrm_length);
481
599
    return (-1);
482
599
  }
483
484
4.39k
  return (0);
485
4.99k
}
486
487
int
488
ikev2_pld_xform(struct iked *env, struct iked_message *msg,
489
    size_t offset, size_t total)
490
6.66k
{
491
6.66k
  struct ikev2_transform     xfrm;
492
6.66k
  char         id[BUFSIZ];
493
6.66k
  int        ret = 0;
494
6.66k
  int        r;
495
6.66k
  size_t         xfrm_length;
496
497
6.66k
  if (ikev2_validate_xform(msg, offset, total, &xfrm))
498
2.27k
    return (-1);
499
500
4.39k
  xfrm_length = betoh16(xfrm.xfrm_length);
501
502
4.39k
  switch (xfrm.xfrm_type) {
503
1.05k
  case IKEV2_XFORMTYPE_ENCR:
504
1.05k
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
505
1.05k
        ikev2_xformencr_map), sizeof(id));
506
1.05k
    break;
507
765
  case IKEV2_XFORMTYPE_PRF:
508
765
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
509
765
        ikev2_xformprf_map), sizeof(id));
510
765
    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
247
  case IKEV2_XFORMTYPE_DH:
516
247
    strlcpy(id, print_map(betoh16(xfrm.xfrm_id),
517
247
        ikev2_xformdh_map), sizeof(id));
518
247
    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.16k
  default:
524
1.16k
    snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id));
525
1.16k
    break;
526
4.39k
  }
527
528
4.39k
  log_debug("%s: more %d reserved %d length %zu"
529
4.39k
      " type %s id %s",
530
4.39k
      __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length,
531
4.39k
      print_map(xfrm.xfrm_type, ikev2_xformtype_map), id);
532
533
  /*
534
   * Parse transform attributes, if available
535
   */
536
4.39k
  msg->msg_attrlength = 0;
537
4.39k
  if (xfrm_length > sizeof(xfrm)) {
538
2.18k
    if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm),
539
2.18k
        xfrm_length - sizeof(xfrm)) != 0) {
540
1.65k
      return (-1);
541
1.65k
    }
542
2.18k
  }
543
544
2.73k
  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
2.73k
  offset += xfrm_length;
561
2.73k
  total -= xfrm_length;
562
2.73k
  if (xfrm.xfrm_more == IKEV2_XFORM_MORE)
563
1.53k
    ret = ikev2_pld_xform(env, msg, offset, total);
564
1.20k
  else if (total != 0) {
565
    /* No more transforms but still some data left. */
566
146
    log_debug("%s: less data than specified, %zu bytes left",
567
146
        __func__, total);
568
146
    ret = -1;
569
146
  }
570
571
2.73k
  return (ret);
572
2.73k
}
573
574
int
575
ikev2_validate_attr(struct iked_message *msg, size_t offset, size_t total,
576
    struct ikev2_attribute *attr)
577
28.9k
{
578
28.9k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
579
580
28.9k
  if (total < sizeof(*attr)) {
581
708
    log_debug("%s: malformed payload: too short for header "
582
708
        "(%zu < %zu)", __func__, total, sizeof(*attr));
583
708
    return (-1);
584
708
  }
585
28.2k
  memcpy(attr, msgbuf + offset, sizeof(*attr));
586
587
28.2k
  return (0);
588
28.9k
}
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
28.9k
{
594
28.9k
  struct ikev2_attribute     attr;
595
28.9k
  unsigned int       type;
596
28.9k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
597
28.9k
  int        ret = 0;
598
28.9k
  size_t         attr_length;
599
600
28.9k
  if (ikev2_validate_attr(msg, offset, total, &attr))
601
708
    return (-1);
602
603
28.2k
  type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV;
604
605
28.2k
  log_debug("%s: attribute type %s length %d total %zu",
606
28.2k
      __func__, print_map(type, ikev2_attrtype_map),
607
28.2k
      betoh16(attr.attr_length), total);
608
609
28.2k
  if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) {
610
    /* Type-Value attribute */
611
21.9k
    offset += sizeof(attr);
612
21.9k
    total -= sizeof(attr);
613
614
21.9k
    if (type == IKEV2_ATTRTYPE_KEY_LENGTH)
615
45
      msg->msg_attrlength = betoh16(attr.attr_length);
616
21.9k
  } else {
617
    /* Type-Length-Value attribute */
618
6.31k
    attr_length = betoh16(attr.attr_length);
619
6.31k
    if (attr_length < sizeof(attr)) {
620
526
      log_debug("%s: malformed payload: shorter than "
621
526
          "minimum header size (%zu < %zu)", __func__,
622
526
          attr_length, sizeof(attr));
623
526
      return (-1);
624
526
    }
625
5.78k
    if (total < attr_length) {
626
422
      log_debug("%s: malformed payload: attribute larger "
627
422
          "than actual payload (%zu < %zu)", __func__,
628
422
          total, attr_length);
629
422
      return (-1);
630
422
    }
631
5.36k
    print_hex(msgbuf, offset + sizeof(attr),
632
5.36k
        attr_length - sizeof(attr));
633
5.36k
    offset += attr_length;
634
5.36k
    total -= attr_length;
635
5.36k
  }
636
637
27.3k
  if (total > 0) {
638
    /* Next attribute */
639
26.7k
    ret = ikev2_pld_attr(env, xfrm, msg, offset, total);
640
26.7k
  }
641
642
27.3k
  return (ret);
643
28.2k
}
644
645
int
646
ikev2_validate_ke(struct iked_message *msg, size_t offset, size_t left,
647
    struct ikev2_keyexchange *kex)
648
5.93k
{
649
5.93k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
650
651
5.93k
  if (left < sizeof(*kex)) {
652
3.70k
    log_debug("%s: malformed payload: too short for header "
653
3.70k
        "(%zu < %zu)", __func__, left, sizeof(*kex));
654
3.70k
    return (-1);
655
3.70k
  }
656
2.22k
  memcpy(kex, msgbuf + offset, sizeof(*kex));
657
658
2.22k
  return (0);
659
5.93k
}
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
5.93k
{
665
5.93k
  struct ikev2_keyexchange   kex;
666
5.93k
  uint8_t       *buf;
667
5.93k
  size_t         len;
668
5.93k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
669
670
5.93k
  if (ikev2_validate_ke(msg, offset, left, &kex))
671
3.70k
    return (-1);
672
673
2.22k
  log_debug("%s: dh group %s reserved %d", __func__,
674
2.22k
      print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map),
675
2.22k
      betoh16(kex.kex_reserved));
676
677
2.22k
  buf = msgbuf + offset + sizeof(kex);
678
2.22k
  len = left - sizeof(kex);
679
680
2.22k
  if (len == 0) {
681
651
    log_debug("%s: malformed payload: no KE data given", __func__);
682
651
    return (-1);
683
651
  }
684
685
1.57k
  print_hex(buf, 0, len);
686
687
1.57k
  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.57k
  return (0);
700
1.57k
}
701
702
int
703
ikev2_validate_id(struct iked_message *msg, size_t offset, size_t left,
704
    struct ikev2_id *id)
705
18.5k
{
706
18.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
707
708
18.5k
  if (left < sizeof(*id)) {
709
7.36k
    log_debug("%s: malformed payload: too short for header "
710
7.36k
        "(%zu < %zu)", __func__, left, sizeof(*id));
711
7.36k
    return (-1);
712
7.36k
  }
713
11.1k
  memcpy(id, msgbuf + offset, sizeof(*id));
714
715
11.1k
  if (id->id_type == IKEV2_ID_NONE) {
716
6.41k
    log_debug("%s: malformed payload: invalid ID type.",
717
6.41k
        __func__);
718
6.41k
    return (-1);
719
6.41k
  }
720
721
4.75k
  return (0);
722
11.1k
}
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
18.5k
{
728
18.5k
  uint8_t       *ptr;
729
18.5k
  struct ikev2_id      id;
730
18.5k
  size_t         len;
731
18.5k
  struct iked_id      *idp, idb;
732
18.5k
  const struct iked_sa    *sa = msg->msg_sa;
733
18.5k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
734
18.5k
  char         idstr[IKED_ID_SIZE];
735
736
18.5k
  if (ikev2_validate_id(msg, offset, left, &id))
737
13.7k
    return (-1);
738
739
4.75k
  bzero(&idb, sizeof(idb));
740
741
  /* Don't strip the Id payload header */
742
4.75k
  ptr = msgbuf + offset;
743
4.75k
  len = left;
744
745
4.75k
  idb.id_type = id.id_type;
746
4.75k
  idb.id_offset = sizeof(id);
747
4.75k
  if ((idb.id_buf = ibuf_new(ptr, len)) == NULL)
748
0
    return (-1);
749
750
4.75k
  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
4.75k
  log_debug("%s: id %s length %zu", __func__, idstr, len);
757
758
4.75k
  if (!ikev2_msg_frompeer(msg)) {
759
4.65k
    ibuf_free(idb.id_buf);
760
4.65k
    return (0);
761
4.65k
  }
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.21k
{
791
5.21k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
792
793
5.21k
  if (left < sizeof(*cert)) {
794
1.14k
    log_debug("%s: malformed payload: too short for header "
795
1.14k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
796
1.14k
    return (-1);
797
1.14k
  }
798
4.07k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
799
4.07k
  if (cert->cert_type == IKEV2_CERT_NONE) {
800
912
    log_debug("%s: malformed payload: invalid cert type", __func__);
801
912
    return (-1);
802
912
  }
803
804
3.15k
  return (0);
805
4.07k
}
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.21k
{
811
5.21k
  struct ikev2_cert    cert;
812
5.21k
  uint8_t       *buf;
813
5.21k
  size_t         len;
814
5.21k
  struct iked_id      *certid;
815
5.21k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
816
5.21k
  const struct iked_sa    *sa = msg->msg_sa;
817
5.21k
  int        i;
818
819
5.21k
  if (ikev2_validate_cert(msg, offset, left, &cert))
820
2.05k
    return (-1);
821
3.15k
  offset += sizeof(cert);
822
823
3.15k
  buf = msgbuf + offset;
824
3.15k
  len = left - sizeof(cert);
825
826
3.15k
  log_debug("%s: type %s length %zu",
827
3.15k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
828
829
3.15k
  print_hex(buf, 0, len);
830
831
3.15k
  if (!ikev2_msg_frompeer(msg))
832
1.37k
    return (0);
833
834
  /* do not accept internal encoding in the wire */
835
1.78k
  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.49k
  certid = &msg->msg_parent->msg_cert;
842
1.49k
  if (certid->id_type) {
843
    /* try to set supplemental certs */
844
3.63k
    for (i = 0; i < IKED_SCERT_MAX; i++) {
845
2.97k
      certid = &msg->msg_parent->msg_scert[i];
846
2.97k
      if (!certid->id_type)
847
542
        break;
848
2.97k
    }
849
1.20k
    if (certid->id_type) {
850
663
      log_debug("%s: too many cert payloads, ignoring",
851
663
         SPI_SA(sa, __func__));
852
663
      return (0);
853
663
    }
854
1.20k
  }
855
856
827
  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
827
  certid->id_type = cert.cert_type;
861
827
  certid->id_offset = 0;
862
863
827
  return (0);
864
827
}
865
866
int
867
ikev2_validate_certreq(struct iked_message *msg, size_t offset, size_t left,
868
    struct ikev2_cert *cert)
869
10.2k
{
870
10.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
871
872
10.2k
  if (left < sizeof(*cert)) {
873
2.14k
    log_debug("%s: malformed payload: too short for header "
874
2.14k
        "(%zu < %zu)", __func__, left, sizeof(*cert));
875
2.14k
    return (-1);
876
2.14k
  }
877
8.07k
  memcpy(cert, msgbuf + offset, sizeof(*cert));
878
879
8.07k
  return (0);
880
10.2k
}
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
10.2k
{
886
10.2k
  struct ikev2_cert    cert;
887
10.2k
  struct iked_certreq   *cr;
888
10.2k
  uint8_t       *buf;
889
10.2k
  ssize_t        len;
890
10.2k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
891
892
10.2k
  if (ikev2_validate_certreq(msg, offset, left, &cert))
893
2.14k
    return (-1);
894
8.07k
  offset += sizeof(cert);
895
896
8.07k
  buf = msgbuf + offset;
897
8.07k
  len = left - sizeof(cert);
898
899
8.07k
  log_debug("%s: type %s length %zd",
900
8.07k
      __func__, print_map(cert.cert_type, ikev2_cert_map), len);
901
902
8.07k
  print_hex(buf, 0, len);
903
904
8.07k
  if (!ikev2_msg_frompeer(msg))
905
7.26k
    return (0);
906
907
812
  if (cert.cert_type == IKEV2_CERT_X509_CERT) {
908
319
    if (len == 0) {
909
277
      log_info("%s: invalid length 0", __func__);
910
277
      return (0);
911
277
    }
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
526
  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
526
  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
526
  cr->cr_type = cert.cert_type;
929
526
  SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry);
930
931
526
  return (0);
932
526
}
933
934
int
935
ikev2_validate_auth(struct iked_message *msg, size_t offset, size_t left,
936
    struct ikev2_auth *auth)
937
7.98k
{
938
7.98k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
939
940
7.98k
  if (left < sizeof(*auth)) {
941
1.82k
    log_debug("%s: malformed payload: too short for header "
942
1.82k
        "(%zu < %zu)", __func__, left, sizeof(*auth));
943
1.82k
    return (-1);
944
1.82k
  }
945
6.16k
  memcpy(auth, msgbuf + offset, sizeof(*auth));
946
947
6.16k
  if (auth->auth_method == 0) {
948
3.34k
    log_info("%s: malformed payload: invalid auth method",
949
3.34k
        __func__);
950
3.34k
    return (-1);
951
3.34k
  }
952
953
2.82k
  return (0);
954
6.16k
}
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
7.98k
{
960
7.98k
  struct ikev2_auth    auth;
961
7.98k
  struct iked_id      *idp;
962
7.98k
  uint8_t       *buf;
963
7.98k
  size_t         len;
964
7.98k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
965
966
7.98k
  if (ikev2_validate_auth(msg, offset, left, &auth))
967
5.16k
    return (-1);
968
2.82k
  offset += sizeof(auth);
969
970
2.82k
  buf = msgbuf + offset;
971
2.82k
  len = left - sizeof(auth);
972
973
2.82k
  log_debug("%s: method %s length %zu",
974
2.82k
      __func__, print_map(auth.auth_method, ikev2_auth_map), len);
975
976
2.82k
  print_hex(buf, 0, len);
977
978
2.82k
  if (!ikev2_msg_frompeer(msg))
979
2.77k
    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
229
{
1000
229
  size_t     len;
1001
229
  uint8_t   *buf;
1002
229
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1003
1004
229
  buf = msgbuf + offset;
1005
229
  len = left;
1006
1007
229
  if (len == 0) {
1008
82
    log_debug("%s: malformed payload: no NONCE given", __func__);
1009
82
    return (-1);
1010
82
  }
1011
1012
147
  print_hex(buf, 0, len);
1013
1014
147
  if (ikev2_msg_frompeer(msg)) {
1015
58
    if (msg->msg_parent->msg_nonce != NULL) {
1016
19
      log_info("%s: duplicate NONCE payload", __func__);
1017
19
      return (-1);
1018
19
    }
1019
39
    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
39
    msg->msg_parent->msg_nonce = msg->msg_nonce;
1024
39
  }
1025
1026
128
  return (0);
1027
147
}
1028
1029
int
1030
ikev2_validate_notify(struct iked_message *msg, size_t offset, size_t left,
1031
    struct ikev2_notify *n)
1032
24.5k
{
1033
24.5k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1034
1035
24.5k
  if (left < sizeof(*n)) {
1036
3.14k
    log_debug("%s: malformed payload: too short for header "
1037
3.14k
        "(%zu < %zu)", __func__, left, sizeof(*n));
1038
3.14k
    return (-1);
1039
3.14k
  }
1040
21.4k
  memcpy(n, msgbuf + offset, sizeof(*n));
1041
1042
21.4k
  return (0);
1043
24.5k
}
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
24.5k
{
1049
24.5k
  struct ikev2_notify  n;
1050
24.5k
  const struct iked_sa  *sa = msg->msg_sa;
1051
24.5k
  uint8_t     *buf, md[SHA_DIGEST_LENGTH];
1052
24.5k
  uint32_t     spi32;
1053
24.5k
  uint64_t     spi64;
1054
24.5k
  struct iked_spi   *rekey;
1055
24.5k
  uint16_t     type;
1056
24.5k
  uint16_t     signature_hash;
1057
1058
24.5k
  if (ikev2_validate_notify(msg, offset, left, &n))
1059
3.14k
    return (-1);
1060
21.4k
  type = betoh16(n.n_type);
1061
1062
21.4k
  log_debug("%s: protoid %s spisize %d type %s",
1063
21.4k
      __func__,
1064
21.4k
      print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize,
1065
21.4k
      print_map(type, ikev2_n_map));
1066
1067
21.4k
  left -= sizeof(n);
1068
21.4k
  if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL)
1069
0
    return (-1);
1070
1071
21.4k
  print_hex(buf, 0, left);
1072
1073
21.4k
  if (!ikev2_msg_frompeer(msg))
1074
1.36k
    return (0);
1075
1076
20.0k
  switch (type) {
1077
2.47k
  case IKEV2_N_NAT_DETECTION_SOURCE_IP:
1078
15.9k
  case IKEV2_N_NAT_DETECTION_DESTINATION_IP:
1079
15.9k
    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
15.9k
    if (ikev2_nat_detection(env, msg, md, sizeof(md), type,
1085
15.9k
        ikev2_msg_frompeer(msg)) == -1)
1086
0
      return (-1);
1087
15.9k
    if (memcmp(buf, md, left) != 0) {
1088
15.9k
      log_debug("%s: %s detected NAT", __func__,
1089
15.9k
          print_map(type, ikev2_n_map));
1090
15.9k
      if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP)
1091
2.47k
        msg->msg_parent->msg_nat_detected
1092
2.47k
            |= IKED_MSG_NAT_SRC_IP;
1093
13.5k
      else
1094
13.5k
        msg->msg_parent->msg_nat_detected
1095
13.5k
            |= IKED_MSG_NAT_DST_IP;
1096
15.9k
    }
1097
15.9k
    print_hex(md, 0, sizeof(md));
1098
    /* remember for MOBIKE */
1099
15.9k
    msg->msg_parent->msg_natt_rcvd = 1;
1100
15.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
233
  case IKEV2_N_NO_ADDITIONAL_SAS:
1147
233
    if (!msg->msg_e) {
1148
0
      log_debug("%s: NO_ADDITIONAL_SAS not encrypted",
1149
0
          __func__);
1150
0
      return (-1);
1151
0
    }
1152
233
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS;
1153
233
    break;
1154
64
  case IKEV2_N_REKEY_SA:
1155
64
    if (!msg->msg_e) {
1156
0
      log_debug("%s: N_REKEY_SA not encrypted", __func__);
1157
0
      return (-1);
1158
0
    }
1159
64
    if (left != n.n_spisize) {
1160
5
      log_debug("%s: malformed notification", __func__);
1161
5
      return (-1);
1162
5
    }
1163
59
    rekey = &msg->msg_parent->msg_rekey;
1164
59
    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
54
    switch (n.n_spisize) {
1170
48
    case 4:
1171
48
      memcpy(&spi32, buf, left);
1172
48
      rekey->spi = betoh32(spi32);
1173
48
      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
54
    }
1183
51
    rekey->spi_size = n.n_spisize;
1184
51
    rekey->spi_protoid = n.n_protoid;
1185
1186
51
    log_debug("%s: rekey %s spi %s", __func__,
1187
51
        print_map(n.n_protoid, ikev2_saproto_map),
1188
51
        print_spi(rekey->spi, n.n_spisize));
1189
51
    break;
1190
341
  case IKEV2_N_TEMPORARY_FAILURE:
1191
341
    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
341
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE;
1197
341
    break;
1198
249
  case IKEV2_N_IPCOMP_SUPPORTED:
1199
249
    if (!msg->msg_e) {
1200
0
      log_debug("%s: N_IPCOMP_SUPPORTED not encrypted",
1201
0
          __func__);
1202
0
      return (-1);
1203
0
    }
1204
249
    if (left < sizeof(msg->msg_parent->msg_cpi) +
1205
249
        sizeof(msg->msg_parent->msg_transform)) {
1206
121
      log_debug("%s: ignoring malformed ipcomp notification",
1207
121
          __func__);
1208
121
      return (0);
1209
121
    }
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
263
  case IKEV2_N_MOBIKE_SUPPORTED:
1236
263
    if (!msg->msg_e) {
1237
0
      log_debug("%s: N_MOBIKE_SUPPORTED not encrypted",
1238
0
          __func__);
1239
0
      return (-1);
1240
0
    }
1241
263
    if (left != 0) {
1242
130
      log_debug("%s: ignoring malformed mobike"
1243
130
          " notification: %zu", __func__, left);
1244
130
      return (0);
1245
130
    }
1246
133
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
1247
133
    break;
1248
301
  case IKEV2_N_USE_TRANSPORT_MODE:
1249
301
    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
301
    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
224
    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
224
    msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT;
1267
224
    break;
1268
344
  case IKEV2_N_UPDATE_SA_ADDRESSES:
1269
344
    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
344
    if (!sa->sa_mobike) {
1275
344
      log_debug("%s: ignoring update sa addresses"
1276
344
          " notification w/o mobike: %zu", __func__, left);
1277
344
      return (0);
1278
344
    }
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
201
  case IKEV2_N_COOKIE2:
1287
201
    if (!msg->msg_e) {
1288
0
      log_debug("%s: N_COOKIE2 not encrypted",
1289
0
          __func__);
1290
0
      return (-1);
1291
0
    }
1292
201
    if (!sa->sa_mobike) {
1293
201
      log_debug("%s: ignoring cookie2 notification"
1294
201
          " w/o mobike: %zu", __func__, left);
1295
201
      return (0);
1296
201
    }
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
20.0k
  }
1379
1380
19.1k
  return (0);
1381
20.0k
}
1382
1383
int
1384
ikev2_validate_delete(struct iked_message *msg, size_t offset, size_t left,
1385
    struct ikev2_delete *del)
1386
6.99k
{
1387
6.99k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1388
1389
6.99k
  if (left < sizeof(*del)) {
1390
1.33k
    log_debug("%s: malformed payload: too short for header "
1391
1.33k
        "(%zu < %zu)", __func__, left, sizeof(*del));
1392
1.33k
    return (-1);
1393
1.33k
  }
1394
5.66k
  memcpy(del, msgbuf + offset, sizeof(*del));
1395
1396
5.66k
  if (del->del_protoid == 0) {
1397
84
    log_info("%s: malformed payload: invalid protoid", __func__);
1398
84
    return (-1);
1399
84
  }
1400
1401
5.58k
  return (0);
1402
5.66k
}
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
6.99k
{
1408
6.99k
  struct ikev2_delete  del;
1409
6.99k
  uint8_t     *buf, *msgbuf = ibuf_data(msg->msg_data);
1410
6.99k
  size_t       cnt, sz, len;
1411
1412
6.99k
  if (ikev2_validate_delete(msg, offset, left, &del))
1413
1.41k
    return (-1);
1414
1415
  /* Skip if it's a response, then we don't have to deal with it */
1416
5.58k
  if (ikev2_msg_frompeer(msg) &&
1417
5.58k
      msg->msg_parent->msg_response)
1418
0
    return (0);
1419
1420
5.58k
  cnt = betoh16(del.del_nspi);
1421
5.58k
  sz = del.del_spisize;
1422
1423
5.58k
  log_debug("%s: proto %s spisize %zu nspi %zu",
1424
5.58k
      __func__, print_map(del.del_protoid, ikev2_saproto_map),
1425
5.58k
      sz, cnt);
1426
1427
5.58k
  if (msg->msg_parent->msg_del_protoid) {
1428
5.28k
    log_debug("%s: duplicate delete payload", __func__);
1429
5.28k
    return (0);
1430
5.28k
  }
1431
1432
303
  msg->msg_parent->msg_del_protoid = del.del_protoid;
1433
303
  msg->msg_parent->msg_del_cnt = cnt;
1434
303
  msg->msg_parent->msg_del_spisize = sz;
1435
1436
303
  buf = msgbuf + offset + sizeof(del);
1437
303
  len = left - sizeof(del);
1438
303
  if (len == 0 || sz == 0 || cnt == 0)
1439
280
    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
16.3k
{
1458
16.3k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1459
1460
16.3k
  if (left < sizeof(*tsp)) {
1461
2.36k
    log_debug("%s: malformed payload: too short for header "
1462
2.36k
        "(%zu < %zu)", __func__, left, sizeof(*tsp));
1463
2.36k
    return (-1);
1464
2.36k
  }
1465
13.9k
  memcpy(tsp, msgbuf + offset, sizeof(*tsp));
1466
1467
13.9k
  return (0);
1468
16.3k
}
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
16.3k
{
1474
16.3k
  struct ikev2_tsp     tsp;
1475
16.3k
  struct ikev2_ts      ts;
1476
16.3k
  size_t         ts_len, i;
1477
1478
16.3k
  if (ikev2_validate_tss(msg, offset, left, &tsp))
1479
2.36k
    return (-1);
1480
1481
13.9k
  offset += sizeof(tsp);
1482
13.9k
  left -= sizeof(tsp);
1483
1484
13.9k
  log_debug("%s: count %d length %zu", __func__,
1485
13.9k
      tsp.tsp_count, left);
1486
1487
25.8k
  for (i = 0; i < tsp.tsp_count; i++) {
1488
24.2k
    if (ikev2_validate_ts(msg, offset, left, &ts))
1489
10.9k
      return (-1);
1490
1491
13.3k
    log_debug("%s: type %s protoid %u length %d "
1492
13.3k
        "startport %u endport %u", __func__,
1493
13.3k
        print_map(ts.ts_type, ikev2_ts_map),
1494
13.3k
        ts.ts_protoid, betoh16(ts.ts_length),
1495
13.3k
        betoh16(ts.ts_startport),
1496
13.3k
        betoh16(ts.ts_endport));
1497
1498
13.3k
    offset += sizeof(ts);
1499
13.3k
    left -= sizeof(ts);
1500
1501
13.3k
    ts_len = betoh16(ts.ts_length) - sizeof(ts);
1502
13.3k
    if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type))
1503
1.45k
      return (-1);
1504
1505
11.9k
    offset += ts_len;
1506
11.9k
    left -= ts_len;
1507
11.9k
  }
1508
1509
1.59k
  return (0);
1510
13.9k
}
1511
1512
int
1513
ikev2_validate_ts(struct iked_message *msg, size_t offset, size_t left,
1514
    struct ikev2_ts *ts)
1515
24.2k
{
1516
24.2k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1517
24.2k
  size_t     ts_length;
1518
1519
24.2k
  if (left < sizeof(*ts)) {
1520
9.93k
    log_debug("%s: malformed payload: too short for header "
1521
9.93k
        "(%zu < %zu)", __func__, left, sizeof(*ts));
1522
9.93k
    return (-1);
1523
9.93k
  }
1524
14.3k
  memcpy(ts, msgbuf + offset, sizeof(*ts));
1525
1526
14.3k
  ts_length = betoh16(ts->ts_length);
1527
14.3k
  if (ts_length < sizeof(*ts)) {
1528
289
    log_debug("%s: malformed payload: shorter than minimum header "
1529
289
        "size (%zu < %zu)", __func__, ts_length, sizeof(*ts));
1530
289
    return (-1);
1531
289
  }
1532
14.0k
  if (left < ts_length) {
1533
692
    log_debug("%s: malformed payload: too long for payload size "
1534
692
        "(%zu < %zu)", __func__, left, ts_length);
1535
692
    return (-1);
1536
692
  }
1537
1538
13.3k
  return (0);
1539
14.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
13.3k
{
1545
13.3k
  struct sockaddr_in     start4, end4;
1546
13.3k
  struct sockaddr_in6    start6, end6;
1547
13.3k
  uint8_t       *msgbuf = ibuf_data(msg->msg_data);
1548
13.3k
  uint8_t       *ptr;
1549
1550
13.3k
  ptr = msgbuf + offset;
1551
1552
13.3k
  switch (type) {
1553
4.72k
  case IKEV2_TS_IPV4_ADDR_RANGE:
1554
4.72k
    if (left < 2 * 4) {
1555
307
      log_debug("%s: malformed payload: too short "
1556
307
          "for ipv4 addr range (%zu < %u)",
1557
307
          __func__, left, 2 * 4);
1558
307
      return (-1);
1559
307
    }
1560
1561
4.42k
    bzero(&start4, sizeof(start4));
1562
4.42k
    start4.sin_family = AF_INET;
1563
#ifdef HAVE_SOCKADDR_SA_LEN
1564
    start4.sin_len = sizeof(start4);
1565
#endif
1566
4.42k
    memcpy(&start4.sin_addr.s_addr, ptr, 4);
1567
4.42k
    ptr += 4;
1568
4.42k
    left -= 4;
1569
1570
4.42k
    bzero(&end4, sizeof(end4));
1571
4.42k
    end4.sin_family = AF_INET;
1572
#ifdef HAVE_SOCKADDR_SA_LEN
1573
    end4.sin_len = sizeof(end4);
1574
#endif
1575
4.42k
    memcpy(&end4.sin_addr.s_addr, ptr, 4);
1576
4.42k
    left -= 4;
1577
1578
4.42k
    log_debug("%s: start %s end %s", __func__,
1579
4.42k
        print_addr(&start4), print_addr(&end4));
1580
4.42k
    break;
1581
1.14k
  case IKEV2_TS_IPV6_ADDR_RANGE:
1582
1.14k
    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
890
    bzero(&start6, sizeof(start6));
1589
890
    start6.sin6_family = AF_INET6;
1590
#ifdef HAVE_SOCKADDR_SA_LEN
1591
    start6.sin6_len = sizeof(start6);
1592
#endif
1593
890
    memcpy(&start6.sin6_addr, ptr, 16);
1594
890
    ptr += 16;
1595
890
    left -= 16;
1596
1597
890
    bzero(&end6, sizeof(end6));
1598
890
    end6.sin6_family = AF_INET6;
1599
#ifdef HAVE_SOCKADDR_SA_LEN
1600
    end6.sin6_len = sizeof(end6);
1601
#endif
1602
890
    memcpy(&end6.sin6_addr, ptr, 16);
1603
890
    left -= 16;
1604
1605
890
    log_debug("%s: start %s end %s", __func__,
1606
890
        print_addr(&start6), print_addr(&end6));
1607
890
    break;
1608
7.49k
  default:
1609
7.49k
    log_debug("%s: ignoring unknown TS type %u", __func__, type);
1610
7.49k
    return (0);
1611
13.3k
  }
1612
1613
5.31k
  if (left > 0) {
1614
900
    log_debug("%s: malformed payload: left (%zu) > 0",
1615
900
        __func__, left);
1616
900
    return (-1);
1617
900
  }
1618
1619
4.41k
  return (0);
1620
5.31k
}
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
8.50k
{
1876
8.50k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
1877
1878
8.50k
  if (left < sizeof(*cp)) {
1879
2.70k
    log_debug("%s: malformed payload: too short for header "
1880
2.70k
        "(%zu < %zu)", __func__, left, sizeof(*cp));
1881
2.70k
    return (-1);
1882
2.70k
  }
1883
5.79k
  memcpy(cp, msgbuf + offset, sizeof(*cp));
1884
1885
5.79k
  return (0);
1886
8.50k
}
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
8.50k
{
1892
8.50k
  struct ikev2_cp    cp;
1893
8.50k
  struct ikev2_cfg  *cfg;
1894
8.50k
  struct iked_addr  *addr;
1895
8.50k
  struct sockaddr_in  *in4;
1896
8.50k
  struct sockaddr_in6 *in6;
1897
8.50k
  uint8_t     *msgbuf = ibuf_data(msg->msg_data);
1898
8.50k
  uint8_t     *ptr;
1899
8.50k
  size_t       len;
1900
8.50k
  int      cfg_type;
1901
1902
8.50k
  if (ikev2_validate_cp(msg, offset, left, &cp))
1903
2.70k
    return (-1);
1904
1905
5.79k
  ptr = msgbuf + offset + sizeof(cp);
1906
5.79k
  len = left - sizeof(cp);
1907
1908
5.79k
  log_debug("%s: type %s length %zu",
1909
5.79k
      __func__, print_map(cp.cp_type, ikev2_cp_map), len);
1910
5.79k
  print_hex(ptr, 0, len);
1911
1912
13.1k
  while (len > 0) {
1913
8.63k
    if (len < sizeof(*cfg)) {
1914
339
      log_debug("%s: malformed payload: too short for cfg "
1915
339
          "(%zu < %zu)", __func__, len, sizeof(*cfg));
1916
339
      return (-1);
1917
339
    }
1918
8.29k
    cfg = (struct ikev2_cfg *)ptr;
1919
1920
8.29k
    log_debug("%s: %s 0x%04x length %d", __func__,
1921
8.29k
        print_map(betoh16(cfg->cfg_type), ikev2_cfg_map),
1922
8.29k
        betoh16(cfg->cfg_type),
1923
8.29k
        betoh16(cfg->cfg_length));
1924
1925
8.29k
    ptr += sizeof(*cfg);
1926
8.29k
    len -= sizeof(*cfg);
1927
1928
8.29k
    if (len < betoh16(cfg->cfg_length)) {
1929
932
      log_debug("%s: malformed payload: too short for "
1930
932
          "cfg_length (%zu < %u)", __func__, len,
1931
932
          betoh16(cfg->cfg_length));
1932
932
      return (-1);
1933
932
    }
1934
1935
7.36k
    print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length));
1936
1937
7.36k
    cfg_type = betoh16(cfg->cfg_type);
1938
7.36k
    switch (cfg_type) {
1939
833
    case IKEV2_CFG_INTERNAL_IP4_ADDRESS:
1940
1.43k
    case IKEV2_CFG_INTERNAL_IP4_DNS:
1941
1.43k
      if (!ikev2_msg_frompeer(msg))
1942
668
        break;
1943
767
      if (betoh16(cfg->cfg_length) == 0)
1944
307
        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.05k
    case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
1997
2.85k
    case IKEV2_CFG_INTERNAL_IP6_DNS:
1998
2.85k
      if (!ikev2_msg_frompeer(msg))
1999
2.67k
        break;
2000
185
      if (betoh16(cfg->cfg_length) == 0)
2001
58
        break;
2002
      /* XXX multiple-valued */
2003
127
      if (betoh16(cfg->cfg_length) < 16) {
2004
1
        log_debug("%s: malformed payload: too short "
2005
1
            "for ipv6 addr w/prefixlen (%u < %u)",
2006
1
            __func__, betoh16(cfg->cfg_length), 16);
2007
1
        return (-1);
2008
1
      }
2009
126
      switch(cfg_type) {
2010
86
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2011
86
        if (msg->msg_parent->msg_cp_addr6 != NULL) {
2012
47
          log_debug("%s: address6 already set", __func__);
2013
47
          goto skip;
2014
47
        }
2015
39
        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
126
      }
2023
43
      if ((addr = calloc(1, sizeof(*addr))) == NULL) {
2024
0
        log_debug("%s: malloc failed", __func__);
2025
0
        break;
2026
0
      }
2027
43
      addr->addr_af = AF_INET6;
2028
43
      in6 = (struct sockaddr_in6 *)&addr->addr;
2029
43
      in6->sin6_family = AF_INET6;
2030
#ifdef HAVE_SOCKADDR_SA_LEN
2031
      in6->sin6_len = sizeof(*in6);
2032
#endif
2033
43
      memcpy(&in6->sin6_addr, ptr, 16);
2034
43
      switch(cfg_type) {
2035
39
      case IKEV2_CFG_INTERNAL_IP6_ADDRESS:
2036
39
        msg->msg_parent->msg_cp_addr6 = addr;
2037
39
        log_debug("%s: IP6_ADDRESS %s", __func__,
2038
39
            print_addr(&addr->addr));
2039
39
        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
43
      }
2050
43
      break;
2051
7.36k
    }
2052
2053
7.35k
 skip:
2054
7.35k
    ptr += betoh16(cfg->cfg_length);
2055
7.35k
    len -= betoh16(cfg->cfg_length);
2056
7.35k
  }
2057
2058
4.52k
  if (!ikev2_msg_frompeer(msg))
2059
4.33k
    return (0);
2060
2061
189
  msg->msg_parent->msg_cp = cp.cp_type;
2062
2063
189
  return (0);
2064
4.52k
}
2065
2066
int
2067
ikev2_validate_eap(struct iked_message *msg, size_t offset, size_t left,
2068
    struct eap_header *hdr)
2069
16.1k
{
2070
16.1k
  uint8_t   *msgbuf = ibuf_data(msg->msg_data);
2071
2072
16.1k
  if (left < sizeof(*hdr)) {
2073
6.77k
    log_debug("%s: malformed payload: too short for header "
2074
6.77k
        "(%zu < %zu)", __func__, left, sizeof(*hdr));
2075
6.77k
    return (-1);
2076
6.77k
  }
2077
9.33k
  memcpy(hdr, msgbuf + offset, sizeof(*hdr));
2078
2079
9.33k
  return (0);
2080
16.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
16.1k
{
2086
16.1k
  struct eap_header    hdr;
2087
16.1k
  struct eap_message    *eap = NULL;
2088
16.1k
  const struct iked_sa    *sa = msg->msg_sa;
2089
16.1k
  size_t         len;
2090
2091
16.1k
  if (ikev2_validate_eap(msg, offset, left, &hdr))
2092
6.77k
    return (-1);
2093
9.33k
  len = betoh16(hdr.eap_length);
2094
2095
9.33k
  if (len < sizeof(*eap)) {
2096
3.37k
    log_info("%s: %s id %d length %d", SPI_SA(sa, __func__),
2097
3.37k
        print_map(hdr.eap_code, eap_code_map),
2098
3.37k
        hdr.eap_id, betoh16(hdr.eap_length));
2099
5.96k
  } else {
2100
    /* Now try to get the indicated length */
2101
5.96k
    if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) {
2102
2.86k
      log_debug("%s: invalid EAP length", __func__);
2103
2.86k
      return (-1);
2104
2.86k
    }
2105
2106
3.10k
    log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__),
2107
3.10k
        print_map(eap->eap_code, eap_code_map),
2108
3.10k
        eap->eap_id, betoh16(eap->eap_length),
2109
3.10k
        print_map(eap->eap_type, eap_type_map));
2110
2111
3.10k
    if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1)
2112
0
      return (-1);
2113
3.10k
    msg->msg_parent->msg_eap.eam_found = 1;
2114
3.10k
  }
2115
2116
6.47k
  return (0);
2117
9.33k
}
\ 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 1042be240..dc5bf3425 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-10-30 00:56

/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
1.51k
{
42
1.51k
  struct ibuf *buf;
43
44
1.51k
  if ((buf = ibuf_dynamic(len,
45
1.51k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
1.51k
  if (len == 0)
49
113
    return (buf);
50
51
1.40k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
1.40k
  } else {
57
1.40k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
1.40k
  }
62
63
1.40k
  return (buf);
64
1.40k
}
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-10-31 00:56

/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
16.2k
{
42
16.2k
  struct ibuf *buf;
43
44
16.2k
  if ((buf = ibuf_dynamic(len,
45
16.2k
      IKED_MSGBUF_MAX)) == NULL)
46
0
    return (NULL);
47
48
16.2k
  if (len == 0)
49
988
    return (buf);
50
51
15.2k
  if (data == NULL) {
52
0
    if (ibuf_add_zero(buf, len) != 0) {
53
0
      ibuf_free(buf);
54
0
      return (NULL);
55
0
    }
56
15.2k
  } else {
57
15.2k
    if (ibuf_add(buf, data, len) != 0) {
58
0
      ibuf_free(buf);
59
0
      return (NULL);
60
0
    }
61
15.2k
  }
62
63
15.2k
  return (buf);
64
15.2k
}
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 c9f552a1e..e06b05a24 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-10-30 00:56

/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
9.34k
{
83
9.34k
  return (verbose);
84
9.34k
}
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
1.97k
{
99
1.97k
  char  *nfmt;
100
1.97k
  int  saved_errno = errno;
101
102
1.97k
  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
1.97k
    vsyslog(pri, fmt, ap);
114
115
1.97k
  errno = saved_errno;
116
1.97k
}
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
1.97k
{
159
1.97k
  va_list  ap;
160
161
1.97k
  va_start(ap, emsg);
162
1.97k
  vlog(LOG_INFO, emsg, ap);
163
1.97k
  va_end(ap);
164
1.97k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
50.0k
{
169
50.0k
  va_list  ap;
170
171
50.0k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
50.0k
}
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-10-31 00:56

/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
119k
{
83
119k
  return (verbose);
84
119k
}
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.2k
{
99
10.2k
  char  *nfmt;
100
10.2k
  int  saved_errno = errno;
101
102
10.2k
  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.2k
    vsyslog(pri, fmt, ap);
114
115
10.2k
  errno = saved_errno;
116
10.2k
}
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.2k
{
159
10.2k
  va_list  ap;
160
161
10.2k
  va_start(ap, emsg);
162
10.2k
  vlog(LOG_INFO, emsg, ap);
163
10.2k
  va_end(ap);
164
10.2k
}
165
166
void
167
log_debug(const char *emsg, ...)
168
468k
{
169
468k
  va_list  ap;
170
171
468k
  if (verbose > 1) {
172
0
    va_start(ap, emsg);
173
0
    vlog(LOG_DEBUG, emsg, ap);
174
0
    va_end(ap);
175
0
  }
176
468k
}
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 d9e78e09b..eafdf99da 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-10-30 00:56

/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
1.51k
#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
65.4k
#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
19.7k
#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-10-31 00:56

/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
16.2k
#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
614k
#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
174k
#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 05015dda8..314bd899e 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-10-30 00:56

/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
562
{
72
562
  switch (sa->sa_family) {
73
438
  case AF_INET:
74
438
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
124
  case AF_INET6:
76
124
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
562
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
562
}
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
3.79k
{
500
3.79k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
3.79k
  static int     i = 0;
502
3.79k
  char      *ptr;
503
504
3.79k
  ptr = buf[i];
505
506
3.79k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
93
  case 4:
511
93
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
93
    break;
513
1.53k
  case 8:
514
1.53k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
1.53k
    break;
516
2.16k
  default:
517
2.16k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
2.16k
    break;
519
3.79k
  }
520
521
3.79k
  if (++i >= IKED_CYCLE_BUFFERS)
522
474
    i = 0;
523
524
3.79k
  return (ptr);
525
3.79k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
61.0k
{
530
61.0k
  unsigned int     i;
531
61.0k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
61.0k
  static int     idx = 0;
533
61.0k
  const char    *name = NULL;
534
535
61.0k
  if (idx >= IKED_CYCLE_BUFFERS)
536
7.63k
    idx = 0;
537
61.0k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
1.10M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
1.04M
    if (map[i].cm_type == type)
541
45.3k
      name = map[i].cm_name;
542
1.04M
  }
543
544
61.0k
  if (name == NULL)
545
15.6k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
45.3k
  else
547
45.3k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
61.0k
  return (buf[idx++]);
550
61.0k
}
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
9.34k
{
562
9.34k
  unsigned int   i;
563
564
9.34k
  if (log_getverbose() < 3 || !length)
565
9.34k
    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
562
{
738
562
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
562
  static int   idx;
740
562
  struct sockaddr *sa = addr;
741
562
  char    *buf;
742
562
  size_t     len;
743
562
  char     pbuf[7];
744
562
  in_port_t  port;
745
746
562
  buf = sbuf[idx];
747
562
  len = sizeof(sbuf[idx]);
748
562
  if (++idx >= IKED_CYCLE_BUFFERS)
749
70
    idx = 0;
750
751
562
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
562
  if (getnameinfo(sa, SA_LEN(sa),
757
562
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
562
  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
562
  return (buf);
768
562
}
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-10-31 00:56

/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
10.8k
{
72
10.8k
  switch (sa->sa_family) {
73
9.00k
  case AF_INET:
74
9.00k
    return (ntohs(((struct sockaddr_in *)sa)->sin_port));
75
1.82k
  case AF_INET6:
76
1.82k
    return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port));
77
0
  default:
78
0
    return (0);
79
10.8k
  }
80
81
  /* NOTREACHED */
82
0
  return (0);
83
10.8k
}
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
29.3k
{
500
29.3k
  static char    buf[IKED_CYCLE_BUFFERS][32];
501
29.3k
  static int     i = 0;
502
29.3k
  char      *ptr;
503
504
29.3k
  ptr = buf[i];
505
506
29.3k
  switch (size) {
507
0
  case 2:
508
0
    snprintf(ptr, 32, "0x%04x", (uint16_t)spi);
509
0
    break;
510
334
  case 4:
511
334
    snprintf(ptr, 32, "0x%08x", (uint32_t)spi);
512
334
    break;
513
20.3k
  case 8:
514
20.3k
    snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi);
515
20.3k
    break;
516
8.69k
  default:
517
8.69k
    snprintf(ptr, 32, "%llu", (long long unsigned)spi);
518
8.69k
    break;
519
29.3k
  }
520
521
29.3k
  if (++i >= IKED_CYCLE_BUFFERS)
522
3.66k
    i = 0;
523
524
29.3k
  return (ptr);
525
29.3k
}
526
527
const char *
528
print_map(unsigned int type, struct iked_constmap *map)
529
574k
{
530
574k
  unsigned int     i;
531
574k
  static char    buf[IKED_CYCLE_BUFFERS][32];
532
574k
  static int     idx = 0;
533
574k
  const char    *name = NULL;
534
535
574k
  if (idx >= IKED_CYCLE_BUFFERS)
536
71.7k
    idx = 0;
537
574k
  bzero(buf[idx], sizeof(buf[idx]));
538
539
11.7M
  for (i = 0; map[i].cm_name != NULL; i++) {
540
11.2M
    if (map[i].cm_type == type)
541
401k
      name = map[i].cm_name;
542
11.2M
  }
543
544
574k
  if (name == NULL)
545
172k
    snprintf(buf[idx], sizeof(buf[idx]), "<UNKNOWN:%u>", type);
546
401k
  else
547
401k
    strlcpy(buf[idx], name, sizeof(buf[idx]));
548
549
574k
  return (buf[idx++]);
550
574k
}
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
119k
{
562
119k
  unsigned int   i;
563
564
119k
  if (log_getverbose() < 3 || !length)
565
119k
    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
10.8k
{
738
10.8k
  static char  sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
739
10.8k
  static int   idx;
740
10.8k
  struct sockaddr *sa = addr;
741
10.8k
  char    *buf;
742
10.8k
  size_t     len;
743
10.8k
  char     pbuf[7];
744
10.8k
  in_port_t  port;
745
746
10.8k
  buf = sbuf[idx];
747
10.8k
  len = sizeof(sbuf[idx]);
748
10.8k
  if (++idx >= IKED_CYCLE_BUFFERS)
749
1.35k
    idx = 0;
750
751
10.8k
  if (sa->sa_family == AF_UNSPEC) {
752
0
    strlcpy(buf, "any", len);
753
0
    return (buf);
754
0
  }
755
756
10.8k
  if (getnameinfo(sa, SA_LEN(sa),
757
10.8k
      buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
758
0
    strlcpy(buf, "unknown", len);
759
0
    return (buf);
760
0
  }
761
762
10.8k
  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
10.8k
  return (buf);
768
10.8k
}
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 77be77340..28e2e45fd 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-10-30 00:56

/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
19.5k
#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
737
{
61
737
  return (0);
62
737
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
19.5k
{
68
19.5k
  struct iked_sa    *sa = msg->msg_sa;
69
19.5k
  struct ike_header *hdr;
70
71
19.5k
  msg = msg->msg_parent;
72
73
19.5k
  if (sa == NULL ||
74
19.5k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
19.5k
  if (!sa->sa_hdr.sh_initiator &&
78
19.5k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
999
    return (1);
80
18.5k
  else if (sa->sa_hdr.sh_initiator &&
81
18.5k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
18.5k
  return (0);
85
19.5k
}
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
1.70k
{
102
1.70k
  return "";
103
1.70k
}
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
12
{
121
12
  return (0);
122
12
}
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
48
{
165
48
  return (0);
166
48
}
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
658
{
179
658
  return (0);
180
658
}
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
3
{
192
3
  return (NULL);
193
3
}
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
70
{
209
70
  return (0);
210
70
}
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
717
{
251
717
  struct iked_certreq *cr;
252
717
  struct iked_proposal *prop, *proptmp;
253
717
  int      i;
254
255
717
  if (msg == msg->msg_parent) {
256
717
    ibuf_free(msg->msg_nonce);
257
717
    ibuf_free(msg->msg_ke);
258
717
    ibuf_free(msg->msg_auth.id_buf);
259
717
    ibuf_free(msg->msg_peerid.id_buf);
260
717
    ibuf_free(msg->msg_localid.id_buf);
261
717
    ibuf_free(msg->msg_cert.id_buf);
262
2.86k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
2.15k
      ibuf_free(msg->msg_scert[i].id_buf);
264
717
    ibuf_free(msg->msg_cookie);
265
717
    ibuf_free(msg->msg_cookie2);
266
717
    ibuf_free(msg->msg_del_buf);
267
717
    free(msg->msg_eap.eam_user);
268
717
    free(msg->msg_cp_addr);
269
717
    free(msg->msg_cp_addr6);
270
717
    free(msg->msg_cp_dns);
271
272
717
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
717
        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
717
    msg->msg_nonce = NULL;
281
717
    msg->msg_ke = NULL;
282
717
    msg->msg_auth.id_buf = NULL;
283
717
    msg->msg_peerid.id_buf = NULL;
284
717
    msg->msg_localid.id_buf = NULL;
285
717
    msg->msg_cert.id_buf = NULL;
286
2.86k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
2.15k
      msg->msg_scert[i].id_buf = NULL;
288
717
    msg->msg_cookie = NULL;
289
717
    msg->msg_cookie2 = NULL;
290
717
    msg->msg_del_buf = NULL;
291
717
    msg->msg_eap.eam_user = NULL;
292
717
    msg->msg_cp_addr = NULL;
293
717
    msg->msg_cp_addr6 = NULL;
294
717
    msg->msg_cp_dns = NULL;
295
296
802
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
85
      ibuf_free(cr->cr_data);
298
85
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
85
      free(cr);
300
85
    }
301
717
  }
302
303
717
  if (msg->msg_data != NULL) {
304
717
    ibuf_free(msg->msg_data);
305
717
    msg->msg_data = NULL;
306
717
  }
307
717
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
171k
#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.10k
{
61
3.10k
  return (0);
62
3.10k
}
63
64
/* Copied from ikev2_msg.c for better coverage */
65
int
66
ikev2_msg_frompeer(struct iked_message *msg)
67
171k
{
68
171k
  struct iked_sa    *sa = msg->msg_sa;
69
171k
  struct ike_header *hdr;
70
71
171k
  msg = msg->msg_parent;
72
73
171k
  if (sa == NULL ||
74
171k
      (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL)
75
0
    return (0);
76
77
171k
  if (!sa->sa_hdr.sh_initiator &&
78
171k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR))
79
40.9k
    return (1);
80
130k
  else if (sa->sa_hdr.sh_initiator &&
81
130k
      (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0)
82
0
    return (1);
83
84
130k
  return (0);
85
171k
}
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.42k
{
102
7.42k
  return "";
103
7.42k
}
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
15.9k
{
165
15.9k
  return (0);
166
15.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
4.75k
{
179
4.75k
  return (0);
180
4.75k
}
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
706
{
209
706
  return (0);
210
706
}
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
10.0k
{
251
10.0k
  struct iked_certreq *cr;
252
10.0k
  struct iked_proposal *prop, *proptmp;
253
10.0k
  int      i;
254
255
10.0k
  if (msg == msg->msg_parent) {
256
10.0k
    ibuf_free(msg->msg_nonce);
257
10.0k
    ibuf_free(msg->msg_ke);
258
10.0k
    ibuf_free(msg->msg_auth.id_buf);
259
10.0k
    ibuf_free(msg->msg_peerid.id_buf);
260
10.0k
    ibuf_free(msg->msg_localid.id_buf);
261
10.0k
    ibuf_free(msg->msg_cert.id_buf);
262
40.2k
    for (i = 0; i < IKED_SCERT_MAX; i++)
263
30.1k
      ibuf_free(msg->msg_scert[i].id_buf);
264
10.0k
    ibuf_free(msg->msg_cookie);
265
10.0k
    ibuf_free(msg->msg_cookie2);
266
10.0k
    ibuf_free(msg->msg_del_buf);
267
10.0k
    free(msg->msg_eap.eam_user);
268
10.0k
    free(msg->msg_cp_addr);
269
10.0k
    free(msg->msg_cp_addr6);
270
10.0k
    free(msg->msg_cp_dns);
271
272
10.0k
    TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry,
273
10.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
10.0k
    msg->msg_nonce = NULL;
281
10.0k
    msg->msg_ke = NULL;
282
10.0k
    msg->msg_auth.id_buf = NULL;
283
10.0k
    msg->msg_peerid.id_buf = NULL;
284
10.0k
    msg->msg_localid.id_buf = NULL;
285
10.0k
    msg->msg_cert.id_buf = NULL;
286
40.2k
    for (i = 0; i < IKED_SCERT_MAX; i++)
287
30.1k
      msg->msg_scert[i].id_buf = NULL;
288
10.0k
    msg->msg_cookie = NULL;
289
10.0k
    msg->msg_cookie2 = NULL;
290
10.0k
    msg->msg_del_buf = NULL;
291
10.0k
    msg->msg_eap.eam_user = NULL;
292
10.0k
    msg->msg_cp_addr = NULL;
293
10.0k
    msg->msg_cp_addr6 = NULL;
294
10.0k
    msg->msg_cp_dns = NULL;
295
296
10.5k
    while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) {
297
526
      ibuf_free(cr->cr_data);
298
526
      SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry);
299
526
      free(cr);
300
526
    }
301
10.0k
  }
302
303
10.0k
  if (msg->msg_data != NULL) {
304
10.0k
    ibuf_free(msg->msg_data);
305
10.0k
    msg->msg_data = NULL;
306
10.0k
  }
307
10.0k
}
\ 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 2de4ffb01..cc12552ea 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-10-30 00:56

/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
717
#define OFFSET_ICOOKIE    0
31
717
#define OFFSET_RCOOKIE    8
32
717
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
717
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
717
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
717
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
717
{
40
717
  return &data[OFFSET_ICOOKIE];
41
717
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
717
{
46
717
  return &data[OFFSET_RCOOKIE];
47
717
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
717
{
52
717
  return data[OFFSET_NEXTPAYLOAD];
53
717
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
717
{
58
717
  return data[OFFSET_VERSION];
59
717
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
717
{
64
717
  return data[OFFSET_EXCHANGE];
65
717
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
717
{
70
717
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
717
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
717
{
76
717
  bzero(hdr, sizeof(*hdr));
77
717
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
717
      sizeof(hdr->ike_ispi));
79
717
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
717
      sizeof(hdr->ike_rspi));
81
717
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
717
  hdr->ike_version = get_version(ibuf_data(data));
83
717
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
717
  hdr->ike_length = get_length(ibuf_data(data));
85
717
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
717
{
90
717
  static struct iked_sa sa;
91
92
717
  bzero(&sa, sizeof(sa));
93
717
  bzero(msg, sizeof(*msg));
94
95
717
  msg->msg_sa = &sa;
96
717
  msg->msg_data = data;
97
717
  msg->msg_e = 1;
98
717
  msg->msg_parent = msg;
99
100
717
  TAILQ_INIT(&msg->msg_proposals);
101
717
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
717
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
718
{
108
718
  struct ibuf   *fuzzed;
109
718
  struct ike_header  hdr;
110
718
  struct iked_message  msg;
111
112
718
  bzero(&hdr, sizeof(hdr));
113
718
  bzero(&msg, sizeof(msg));
114
115
718
  fuzzed = ibuf_new(data, size);
116
718
  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
718
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
717
  prepare_header(&hdr, fuzzed);
129
717
  prepare_message(&msg, fuzzed);
130
131
717
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
717
  ikev2_msg_cleanup(NULL, &msg);
134
135
717
  return 0;
136
718
}
\ No newline at end of file +

Coverage Report

Created: 2023-10-31 00:56

/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
10.0k
#define OFFSET_ICOOKIE    0
31
10.0k
#define OFFSET_RCOOKIE    8
32
10.0k
#define OFFSET_NEXTPAYLOAD  (0 + sizeof(cookies))
33
10.0k
#define OFFSET_VERSION    (1 + sizeof(cookies))
34
10.0k
#define OFFSET_EXCHANGE   (2 + sizeof(cookies))
35
10.0k
#define OFFSET_LENGTH   (8 + sizeof(cookies))
36
37
static u_int8_t *
38
get_icookie(u_int8_t *data)
39
10.0k
{
40
10.0k
  return &data[OFFSET_ICOOKIE];
41
10.0k
}
42
43
static u_int8_t *
44
get_rcookie(u_int8_t *data)
45
10.0k
{
46
10.0k
  return &data[OFFSET_RCOOKIE];
47
10.0k
}
48
49
static u_int8_t
50
get_nextpayload(u_int8_t *data)
51
10.0k
{
52
10.0k
  return data[OFFSET_NEXTPAYLOAD];
53
10.0k
}
54
55
static u_int8_t
56
get_version(u_int8_t *data)
57
10.0k
{
58
10.0k
  return data[OFFSET_VERSION];
59
10.0k
}
60
61
static u_int8_t
62
get_exchange(u_int8_t *data)
63
10.0k
{
64
10.0k
  return data[OFFSET_EXCHANGE];
65
10.0k
}
66
67
static u_int32_t
68
get_length(u_int8_t *data)
69
10.0k
{
70
10.0k
  return *(u_int32_t *)&data[OFFSET_LENGTH];
71
10.0k
}
72
73
static void
74
prepare_header(struct ike_header *hdr, struct ibuf *data)
75
10.0k
{
76
10.0k
  bzero(hdr, sizeof(*hdr));
77
10.0k
  bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi,
78
10.0k
      sizeof(hdr->ike_ispi));
79
10.0k
  bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi,
80
10.0k
      sizeof(hdr->ike_rspi));
81
10.0k
  hdr->ike_nextpayload = get_nextpayload(ibuf_data(data));
82
10.0k
  hdr->ike_version = get_version(ibuf_data(data));
83
10.0k
  hdr->ike_exchange = get_exchange(ibuf_data(data));
84
10.0k
  hdr->ike_length = get_length(ibuf_data(data));
85
10.0k
}
86
87
static void
88
prepare_message(struct iked_message *msg, struct ibuf *data)
89
10.0k
{
90
10.0k
  static struct iked_sa sa;
91
92
10.0k
  bzero(&sa, sizeof(sa));
93
10.0k
  bzero(msg, sizeof(*msg));
94
95
10.0k
  msg->msg_sa = &sa;
96
10.0k
  msg->msg_data = data;
97
10.0k
  msg->msg_e = 1;
98
10.0k
  msg->msg_parent = msg;
99
100
10.0k
  TAILQ_INIT(&msg->msg_proposals);
101
10.0k
  SIMPLEQ_INIT(&msg->msg_certreqs);
102
10.0k
}
103
104
/* Entry-Point for libFuzzer */
105
int
106
LLVMFuzzerTestOneInput(const char *data, size_t size)
107
10.0k
{
108
10.0k
  struct ibuf   *fuzzed;
109
10.0k
  struct ike_header  hdr;
110
10.0k
  struct iked_message  msg;
111
112
10.0k
  bzero(&hdr, sizeof(hdr));
113
10.0k
  bzero(&msg, sizeof(msg));
114
115
10.0k
  fuzzed = ibuf_new(data, size);
116
10.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
10.0k
  if (size < sizeof(cookies) + sizeof(genhdr)){
124
1
    ibuf_free(fuzzed);
125
1
    return 0;
126
1
  }         
127
128
10.0k
  prepare_header(&hdr, fuzzed);
129
10.0k
  prepare_message(&msg, fuzzed);
130
131
10.0k
  ikev2_pld_parse(NULL, &hdr, &msg, 0);
132
133
10.0k
  ikev2_msg_cleanup(NULL, &msg);
134
135
10.0k
  return 0;
136
10.0k
}
\ 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 a2c373cf7..97d0b3225 100644 --- a/coverage/latest/textcov_reports/test_libfuzzer.covreport +++ b/coverage/latest/textcov_reports/test_libfuzzer.covreport @@ -1,66 +1,66 @@ freezero: - 25| 1.51k|{ + 25| 16.2k|{ 26| | /* This is legal. */ - 27| 1.51k| if (ptr == NULL) + 27| 16.2k| if (ptr == NULL) ------------------ - | Branch (27:6): [True: 113, False: 1.40k] + | Branch (27:6): [True: 988, False: 15.2k] ------------------ - 28| 113| return; + 28| 988| return; 29| | - 30| 1.40k| explicit_bzero(ptr, sz); - 31| 1.40k| free(ptr); - 32| 1.40k|} + 30| 15.2k| explicit_bzero(ptr, sz); + 31| 15.2k| free(ptr); + 32| 15.2k|} ibuf_dynamic: - 62| 1.51k|{ - 63| 1.51k| struct ibuf *buf; + 62| 16.2k|{ + 63| 16.2k| struct ibuf *buf; 64| | - 65| 1.51k| if (max < len) { + 65| 16.2k| if (max < len) { ------------------ - | Branch (65:6): [True: 0, False: 1.51k] + | Branch (65:6): [True: 0, False: 16.2k] ------------------ 66| 0| errno = EINVAL; 67| 0| return (NULL); 68| 0| } 69| | - 70| 1.51k| if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) + 70| 16.2k| if ((buf = calloc(1, sizeof(struct ibuf))) == NULL) ------------------ - | Branch (70:6): [True: 0, False: 1.51k] + | Branch (70:6): [True: 0, False: 16.2k] ------------------ 71| 0| return (NULL); - 72| 1.51k| if (len > 0) { + 72| 16.2k| if (len > 0) { ------------------ - | Branch (72:6): [True: 1.40k, False: 113] + | Branch (72:6): [True: 15.2k, False: 988] ------------------ - 73| 1.40k| if ((buf->buf = calloc(len, 1)) == NULL) { + 73| 15.2k| if ((buf->buf = calloc(len, 1)) == NULL) { ------------------ - | Branch (73:7): [True: 0, False: 1.40k] + | Branch (73:7): [True: 0, False: 15.2k] ------------------ 74| 0| free(buf); 75| 0| return (NULL); 76| 0| } - 77| 1.40k| } - 78| 1.51k| buf->size = len; - 79| 1.51k| buf->max = max; - 80| 1.51k| buf->fd = -1; + 77| 15.2k| } + 78| 16.2k| buf->size = len; + 79| 16.2k| buf->max = max; + 80| 16.2k| buf->fd = -1; 81| | - 82| 1.51k| return (buf); - 83| 1.51k|} + 82| 16.2k| return (buf); + 83| 16.2k|} ibuf_reserve: - 107| 1.40k|{ - 108| 1.40k| void *b; + 107| 15.2k|{ + 108| 15.2k| void *b; 109| | - 110| 1.40k| if (len > SIZE_MAX - buf->wpos) { + 110| 15.2k| if (len > SIZE_MAX - buf->wpos) { ------------------ - | Branch (110:6): [True: 0, False: 1.40k] + | Branch (110:6): [True: 0, False: 15.2k] ------------------ 111| 0| errno = ERANGE; 112| 0| return (NULL); 113| 0| } 114| | - 115| 1.40k| if (buf->wpos + len > buf->size) + 115| 15.2k| if (buf->wpos + len > buf->size) ------------------ - | Branch (115:6): [True: 0, False: 1.40k] + | Branch (115:6): [True: 0, False: 15.2k] ------------------ 116| 0| if (ibuf_realloc(buf, len) == -1) ------------------ @@ -68,404 +68,404 @@ ibuf_reserve: ------------------ 117| 0| return (NULL); 118| | - 119| 1.40k| b = buf->buf + buf->wpos; - 120| 1.40k| buf->wpos += len; - 121| 1.40k| memset(b, 0, len); - 122| 1.40k| return (b); - 123| 1.40k|} + 119| 15.2k| b = buf->buf + buf->wpos; + 120| 15.2k| buf->wpos += len; + 121| 15.2k| memset(b, 0, len); + 122| 15.2k| return (b); + 123| 15.2k|} ibuf_add: - 127| 1.40k|{ - 128| 1.40k| void *b; + 127| 15.2k|{ + 128| 15.2k| void *b; 129| | - 130| 1.40k| if ((b = ibuf_reserve(buf, len)) == NULL) + 130| 15.2k| if ((b = ibuf_reserve(buf, len)) == NULL) ------------------ - | Branch (130:6): [True: 0, False: 1.40k] + | Branch (130:6): [True: 0, False: 15.2k] ------------------ 131| 0| return (-1); 132| | - 133| 1.40k| memcpy(b, data, len); - 134| 1.40k| return (0); - 135| 1.40k|} + 133| 15.2k| memcpy(b, data, len); + 134| 15.2k| return (0); + 135| 15.2k|} ibuf_seek: - 202| 21.3k|{ + 202| 198k|{ 203| | /* only allowed to seek in already written parts */ - 204| 21.3k| if (len > SIZE_MAX - pos || pos + len > buf->wpos) { + 204| 198k| if (len > SIZE_MAX - pos || pos + len > buf->wpos) { ------------------ - | Branch (204:6): [True: 0, False: 21.3k] - | Branch (204:30): [True: 477, False: 20.8k] + | Branch (204:6): [True: 0, False: 198k] + | Branch (204:30): [True: 2.86k, False: 195k] ------------------ - 205| 477| errno = ERANGE; - 206| 477| return (NULL); - 207| 477| } + 205| 2.86k| errno = ERANGE; + 206| 2.86k| return (NULL); + 207| 2.86k| } 208| | - 209| 20.8k| return (buf->buf + pos); - 210| 21.3k|} + 209| 195k| return (buf->buf + pos); + 210| 198k|} ibuf_data: - 272| 65.8k|{ - 273| 65.8k| return (buf->buf); - 274| 65.8k|} + 272| 618k|{ + 273| 618k| return (buf->buf); + 274| 618k|} ibuf_size: - 278| 717|{ - 279| 717| return (buf->wpos); - 280| 717|} + 278| 10.0k|{ + 279| 10.0k| return (buf->wpos); + 280| 10.0k|} ibuf_free: - 296| 10.0k|{ - 297| 10.0k| if (buf == NULL) + 296| 136k|{ + 297| 136k| if (buf == NULL) ------------------ - | Branch (297:6): [True: 8.54k, False: 1.51k] + | Branch (297:6): [True: 119k, False: 16.2k] ------------------ - 298| 8.54k| return; + 298| 119k| return; 299| |#ifdef NOTYET 300| | if (buf->fd != -1) 301| | close(buf->fd); 302| |#endif - 303| 1.51k| freezero(buf->buf, buf->size); - 304| 1.51k| free(buf); - 305| 1.51k|} + 303| 16.2k| freezero(buf->buf, buf->size); + 304| 16.2k| free(buf); + 305| 16.2k|} strlcpy: - 29| 46.3k|{ - 30| 46.3k| const char *osrc = src; - 31| 46.3k| size_t nleft = dsize; + 29| 405k|{ + 30| 405k| const char *osrc = src; + 31| 405k| size_t nleft = dsize; 32| | 33| | /* Copy as many bytes as will fit. */ - 34| 46.3k| if (nleft != 0) { + 34| 405k| if (nleft != 0) { ------------------ - | Branch (34:6): [True: 46.3k, False: 0] + | Branch (34:6): [True: 405k, False: 0] ------------------ - 35| 255k| while (--nleft != 0) { + 35| 2.99M| while (--nleft != 0) { ------------------ - | Branch (35:10): [True: 254k, False: 123] + | Branch (35:10): [True: 2.99M, False: 1.45k] ------------------ - 36| 254k| if ((*dst++ = *src++) == '\0') + 36| 2.99M| if ((*dst++ = *src++) == '\0') ------------------ - | Branch (36:8): [True: 46.2k, False: 208k] + | Branch (36:8): [True: 403k, False: 2.58M] ------------------ - 37| 46.2k| break; - 38| 254k| } - 39| 46.3k| } + 37| 403k| break; + 38| 2.99M| } + 39| 405k| } 40| | 41| | /* Not enough room in dst, add NUL and traverse rest of src. */ - 42| 46.3k| if (nleft == 0) { + 42| 405k| if (nleft == 0) { ------------------ - | Branch (42:6): [True: 123, False: 46.2k] + | Branch (42:6): [True: 1.45k, False: 403k] ------------------ - 43| 123| if (dsize != 0) + 43| 1.45k| if (dsize != 0) ------------------ - | Branch (43:7): [True: 123, False: 0] + | Branch (43:7): [True: 1.45k, False: 0] ------------------ - 44| 123| *dst = '\0'; /* NUL-terminate dst */ - 45| 123| while (*src++) + 44| 1.45k| *dst = '\0'; /* NUL-terminate dst */ + 45| 1.45k| while (*src++) ------------------ - | Branch (45:10): [True: 0, False: 123] + | Branch (45:10): [True: 0, False: 1.45k] ------------------ 46| 0| ; - 47| 123| } + 47| 1.45k| } 48| | - 49| 46.3k| return(src - osrc - 1); /* count does not include NUL */ - 50| 46.3k|} + 49| 405k| return(src - osrc - 1); /* count does not include NUL */ + 50| 405k|} ikev2_pld_parse: - 118| 717|{ - 119| 717| log_debug("%s: header ispi %s rspi %s" - 120| 717| " nextpayload %s version 0x%02x exchange %s flags 0x%02x" - 121| 717| " msgid %d length %u response %d", __func__, - 122| 717| print_spi(betoh64(hdr->ike_ispi), 8), - 123| 717| print_spi(betoh64(hdr->ike_rspi), 8), - 124| 717| print_map(hdr->ike_nextpayload, ikev2_payload_map), - 125| 717| hdr->ike_version, - 126| 717| print_map(hdr->ike_exchange, ikev2_exchange_map), - 127| 717| hdr->ike_flags, - 128| 717| betoh32(hdr->ike_msgid), - 129| 717| betoh32(hdr->ike_length), - 130| 717| msg->msg_response); + 118| 10.0k|{ + 119| 10.0k| log_debug("%s: header ispi %s rspi %s" + 120| 10.0k| " nextpayload %s version 0x%02x exchange %s flags 0x%02x" + 121| 10.0k| " msgid %d length %u response %d", __func__, + 122| 10.0k| print_spi(betoh64(hdr->ike_ispi), 8), + 123| 10.0k| print_spi(betoh64(hdr->ike_rspi), 8), + 124| 10.0k| print_map(hdr->ike_nextpayload, ikev2_payload_map), + 125| 10.0k| hdr->ike_version, + 126| 10.0k| print_map(hdr->ike_exchange, ikev2_exchange_map), + 127| 10.0k| hdr->ike_flags, + 128| 10.0k| betoh32(hdr->ike_msgid), + 129| 10.0k| betoh32(hdr->ike_length), + 130| 10.0k| msg->msg_response); 131| | - 132| 717| if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) { + 132| 10.0k| if (ibuf_size(msg->msg_data) < betoh32(hdr->ike_length)) { ------------------ - | Branch (132:6): [True: 4, False: 713] + | Branch (132:6): [True: 4, False: 10.0k] ------------------ 133| 4| log_debug("%s: short message", __func__); 134| 4| return (-1); 135| 4| } 136| | - 137| 713| offset += sizeof(*hdr); + 137| 10.0k| offset += sizeof(*hdr); 138| | - 139| 713| return (ikev2_pld_payloads(env, msg, offset, - 140| 713| betoh32(hdr->ike_length), hdr->ike_nextpayload)); - 141| 717|} + 139| 10.0k| return (ikev2_pld_payloads(env, msg, offset, + 140| 10.0k| betoh32(hdr->ike_length), hdr->ike_nextpayload)); + 141| 10.0k|} ikev2_validate_pld: - 146| 21.9k|{ - 147| 21.9k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 148| 21.9k| size_t pld_length; + 146| 202k|{ + 147| 202k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 148| 202k| size_t pld_length; 149| | 150| | /* We need at least the generic header. */ - 151| 21.9k| if (left < sizeof(*pld)) { + 151| 202k| if (left < sizeof(*pld)) { ------------------ - | Branch (151:6): [True: 66, False: 21.8k] + | Branch (151:6): [True: 1.45k, False: 201k] ------------------ - 152| 66| log_debug("%s: malformed payload: too short for generic " - 153| 66| "header (%zu < %zu)", __func__, left, sizeof(*pld)); - 154| 66| return (-1); - 155| 66| } - 156| 21.8k| memcpy(pld, msgbuf + offset, sizeof(*pld)); + 152| 1.45k| log_debug("%s: malformed payload: too short for generic " + 153| 1.45k| "header (%zu < %zu)", __func__, left, sizeof(*pld)); + 154| 1.45k| return (-1); + 155| 1.45k| } + 156| 201k| 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| 21.8k| pld_length = betoh16(pld->pld_length); - 164| 21.8k| if (left < pld_length) { + 163| 201k| pld_length = betoh16(pld->pld_length); + 164| 201k| if (left < pld_length) { ------------------ - | Branch (164:6): [True: 90, False: 21.7k] + | Branch (164:6): [True: 4.27k, False: 197k] ------------------ - 165| 90| log_debug("%s: malformed payload: shorter than specified " - 166| 90| "(%zu < %zu)", __func__, left, pld_length); - 167| 90| return (-1); - 168| 90| } + 165| 4.27k| log_debug("%s: malformed payload: shorter than specified " + 166| 4.27k| "(%zu < %zu)", __func__, left, pld_length); + 167| 4.27k| return (-1); + 168| 4.27k| } 169| | /* 170| | * Sanity check the specified payload size, it must 171| | * be at least the size of the generic payload header. 172| | */ - 173| 21.7k| if (pld_length < sizeof(*pld)) { + 173| 197k| if (pld_length < sizeof(*pld)) { ------------------ - | Branch (173:6): [True: 29, False: 21.7k] + | Branch (173:6): [True: 1.66k, False: 195k] ------------------ - 174| 29| log_debug("%s: malformed payload: shorter than minimum " - 175| 29| "header size (%zu < %zu)", __func__, pld_length, - 176| 29| sizeof(*pld)); - 177| 29| return (-1); - 178| 29| } + 174| 1.66k| log_debug("%s: malformed payload: shorter than minimum " + 175| 1.66k| "header size (%zu < %zu)", __func__, pld_length, + 176| 1.66k| sizeof(*pld)); + 177| 1.66k| return (-1); + 178| 1.66k| } 179| | - 180| 21.7k| return (0); - 181| 21.7k|} + 180| 195k| return (0); + 181| 197k|} ikev2_pld_payloads: - 186| 713|{ - 187| 713| struct ikev2_payload pld; - 188| 713| unsigned int e; - 189| 713| int ret; - 190| 713| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 191| 713| size_t total, left; + 186| 10.0k|{ + 187| 10.0k| struct ikev2_payload pld; + 188| 10.0k| unsigned int e; + 189| 10.0k| int ret; + 190| 10.0k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 191| 10.0k| size_t total, left; 192| | 193| | /* Check if message was decrypted in an E payload */ - 194| 713| e = msg->msg_e ? IKED_E : 0; + 194| 10.0k| e = msg->msg_e ? IKED_E : 0; ------------------ - | | 76| 713|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 10.0k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (194:6): [True: 713, False: 0] + | Branch (194:6): [True: 10.0k, False: 0] ------------------ 195| | 196| | /* Bytes left in datagram. */ - 197| 713| total = length - offset; + 197| 10.0k| total = length - offset; 198| | - 199| 22.3k| while (payload != 0 && offset < length) { + 199| 204k| while (payload != 0 && offset < length) { ------------------ - | Branch (199:9): [True: 22.3k, False: 92] - | Branch (199:25): [True: 21.9k, False: 364] + | Branch (199:9): [True: 204k, False: 426] + | Branch (199:25): [True: 202k, False: 1.53k] ------------------ - 200| 21.9k| if (ikev2_validate_pld(msg, offset, total, &pld)) + 200| 202k| if (ikev2_validate_pld(msg, offset, total, &pld)) ------------------ - | Branch (200:7): [True: 185, False: 21.7k] + | Branch (200:7): [True: 7.39k, False: 195k] ------------------ - 201| 185| return (-1); + 201| 7.39k| return (-1); 202| | - 203| 21.7k| log_debug("%s: %spayload %s" - 204| 21.7k| " nextpayload %s critical 0x%02x length %d", - 205| 21.7k| __func__, e ? "decrypted " : "", + 203| 195k| log_debug("%s: %spayload %s" + 204| 195k| " nextpayload %s critical 0x%02x length %d", + 205| 195k| __func__, e ? "decrypted " : "", ------------------ - | Branch (205:17): [True: 21.7k, False: 0] + | Branch (205:17): [True: 195k, False: 0] ------------------ - 206| 21.7k| print_map(payload, ikev2_payload_map), - 207| 21.7k| print_map(pld.pld_nextpayload, ikev2_payload_map), - 208| 21.7k| pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD, + 206| 195k| print_map(payload, ikev2_payload_map), + 207| 195k| print_map(pld.pld_nextpayload, ikev2_payload_map), + 208| 195k| pld.pld_reserved & IKEV2_CRITICAL_PAYLOAD, ------------------ - | | 89| 21.7k|#define IKEV2_CRITICAL_PAYLOAD 0x01 /* First bit in the reserved field */ + | | 89| 195k|#define IKEV2_CRITICAL_PAYLOAD 0x01 /* First bit in the reserved field */ ------------------ - 209| 21.7k| betoh16(pld.pld_length)); + 209| 195k| betoh16(pld.pld_length)); 210| | 211| | /* Skip over generic payload header. */ - 212| 21.7k| offset += sizeof(pld); - 213| 21.7k| total -= sizeof(pld); - 214| 21.7k| left = betoh16(pld.pld_length) - sizeof(pld); - 215| 21.7k| ret = 0; + 212| 195k| offset += sizeof(pld); + 213| 195k| total -= sizeof(pld); + 214| 195k| left = betoh16(pld.pld_length) - sizeof(pld); + 215| 195k| ret = 0; 216| | - 217| 21.7k| switch (payload | e) { + 217| 195k| switch (payload | e) { 218| 0| case IKEV2_PAYLOAD_SA: ------------------ | | 93| 0|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ ------------------ - | Branch (218:3): [True: 0, False: 21.7k] + | Branch (218:3): [True: 0, False: 195k] ------------------ - 219| 4.38k| case IKEV2_PAYLOAD_SA | IKED_E: + 219| 27.1k| case IKEV2_PAYLOAD_SA | IKED_E: ------------------ - | | 93| 4.38k|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ + | | 93| 27.1k|#define IKEV2_PAYLOAD_SA 33 /* Security Association */ ------------------ case IKEV2_PAYLOAD_SA | IKED_E: ------------------ - | | 76| 4.38k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 27.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (219:3): [True: 4.38k, False: 17.3k] + | Branch (219:3): [True: 27.1k, False: 168k] ------------------ - 220| 4.38k| ret = ikev2_pld_sa(env, &pld, msg, offset, left); - 221| 4.38k| break; + 220| 27.1k| ret = ikev2_pld_sa(env, &pld, msg, offset, left); + 221| 27.1k| break; 222| 0| case IKEV2_PAYLOAD_KE: ------------------ | | 94| 0|#define IKEV2_PAYLOAD_KE 34 /* Key Exchange */ ------------------ - | Branch (222:3): [True: 0, False: 21.7k] + | Branch (222:3): [True: 0, False: 195k] ------------------ - 223| 644| case IKEV2_PAYLOAD_KE | IKED_E: + 223| 5.93k| case IKEV2_PAYLOAD_KE | IKED_E: ------------------ - | | 94| 644|#define IKEV2_PAYLOAD_KE 34 /* Key Exchange */ + | | 94| 5.93k|#define IKEV2_PAYLOAD_KE 34 /* Key Exchange */ ------------------ case IKEV2_PAYLOAD_KE | IKED_E: ------------------ - | | 76| 644|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 5.93k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (223:3): [True: 644, False: 21.1k] + | Branch (223:3): [True: 5.93k, False: 189k] ------------------ - 224| 644| ret = ikev2_pld_ke(env, &pld, msg, offset, left); - 225| 644| break; - 226| 993| case IKEV2_PAYLOAD_IDi | IKED_E: + 224| 5.93k| ret = ikev2_pld_ke(env, &pld, msg, offset, left); + 225| 5.93k| break; + 226| 12.6k| case IKEV2_PAYLOAD_IDi | IKED_E: ------------------ - | | 95| 993|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ + | | 95| 12.6k|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ ------------------ case IKEV2_PAYLOAD_IDi | IKED_E: ------------------ - | | 76| 993|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 12.6k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (226:3): [True: 993, False: 20.7k] + | Branch (226:3): [True: 12.6k, False: 182k] ------------------ - 227| 1.77k| case IKEV2_PAYLOAD_IDr | IKED_E: + 227| 18.5k| case IKEV2_PAYLOAD_IDr | IKED_E: ------------------ - | | 96| 1.77k|#define IKEV2_PAYLOAD_IDr 36 /* Identification - Responder */ + | | 96| 18.5k|#define IKEV2_PAYLOAD_IDr 36 /* Identification - Responder */ ------------------ case IKEV2_PAYLOAD_IDr | IKED_E: ------------------ - | | 76| 1.77k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 18.5k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (227:3): [True: 780, False: 20.9k] + | Branch (227:3): [True: 5.85k, False: 189k] ------------------ - 228| 1.77k| ret = ikev2_pld_id(env, &pld, msg, offset, left, - 229| 1.77k| payload); - 230| 1.77k| break; - 231| 410| case IKEV2_PAYLOAD_CERT | IKED_E: + 228| 18.5k| ret = ikev2_pld_id(env, &pld, msg, offset, left, + 229| 18.5k| payload); + 230| 18.5k| break; + 231| 5.21k| case IKEV2_PAYLOAD_CERT | IKED_E: ------------------ - | | 97| 410|#define IKEV2_PAYLOAD_CERT 37 /* Certificate */ + | | 97| 5.21k|#define IKEV2_PAYLOAD_CERT 37 /* Certificate */ ------------------ case IKEV2_PAYLOAD_CERT | IKED_E: ------------------ - | | 76| 410|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 5.21k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (231:3): [True: 410, False: 21.3k] + | Branch (231:3): [True: 5.21k, False: 190k] ------------------ - 232| 410| ret = ikev2_pld_cert(env, &pld, msg, offset, left); - 233| 410| break; + 232| 5.21k| ret = ikev2_pld_cert(env, &pld, msg, offset, left); + 233| 5.21k| break; 234| 0| case IKEV2_PAYLOAD_CERTREQ: ------------------ | | 98| 0|#define IKEV2_PAYLOAD_CERTREQ 38 /* Certificate Request */ ------------------ - | Branch (234:3): [True: 0, False: 21.7k] + | Branch (234:3): [True: 0, False: 195k] ------------------ - 235| 1.77k| case IKEV2_PAYLOAD_CERTREQ | IKED_E: + 235| 10.2k| case IKEV2_PAYLOAD_CERTREQ | IKED_E: ------------------ - | | 98| 1.77k|#define IKEV2_PAYLOAD_CERTREQ 38 /* Certificate Request */ + | | 98| 10.2k|#define IKEV2_PAYLOAD_CERTREQ 38 /* Certificate Request */ ------------------ case IKEV2_PAYLOAD_CERTREQ | IKED_E: ------------------ - | | 76| 1.77k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 10.2k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (235:3): [True: 1.77k, False: 19.9k] + | Branch (235:3): [True: 10.2k, False: 185k] ------------------ - 236| 1.77k| ret = ikev2_pld_certreq(env, &pld, msg, offset, left); - 237| 1.77k| break; - 238| 773| case IKEV2_PAYLOAD_AUTH | IKED_E: + 236| 10.2k| ret = ikev2_pld_certreq(env, &pld, msg, offset, left); + 237| 10.2k| break; + 238| 7.98k| case IKEV2_PAYLOAD_AUTH | IKED_E: ------------------ - | | 99| 773|#define IKEV2_PAYLOAD_AUTH 39 /* Authentication */ + | | 99| 7.98k|#define IKEV2_PAYLOAD_AUTH 39 /* Authentication */ ------------------ case IKEV2_PAYLOAD_AUTH | IKED_E: ------------------ - | | 76| 773|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 7.98k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (238:3): [True: 773, False: 20.9k] + | Branch (238:3): [True: 7.98k, False: 187k] ------------------ - 239| 773| ret = ikev2_pld_auth(env, &pld, msg, offset, left); - 240| 773| break; + 239| 7.98k| ret = ikev2_pld_auth(env, &pld, msg, offset, left); + 240| 7.98k| break; 241| 0| case IKEV2_PAYLOAD_NONCE: ------------------ | | 100| 0|#define IKEV2_PAYLOAD_NONCE 40 /* Nonce */ ------------------ - | Branch (241:3): [True: 0, False: 21.7k] + | Branch (241:3): [True: 0, False: 195k] ------------------ - 242| 57| case IKEV2_PAYLOAD_NONCE | IKED_E: + 242| 229| case IKEV2_PAYLOAD_NONCE | IKED_E: ------------------ - | | 100| 57|#define IKEV2_PAYLOAD_NONCE 40 /* Nonce */ + | | 100| 229|#define IKEV2_PAYLOAD_NONCE 40 /* Nonce */ ------------------ case IKEV2_PAYLOAD_NONCE | IKED_E: ------------------ - | | 76| 57|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 229|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (242:3): [True: 57, False: 21.6k] + | Branch (242:3): [True: 229, False: 195k] ------------------ - 243| 57| ret = ikev2_pld_nonce(env, &pld, msg, offset, left); - 244| 57| break; + 243| 229| ret = ikev2_pld_nonce(env, &pld, msg, offset, left); + 244| 229| break; 245| 0| case IKEV2_PAYLOAD_NOTIFY: ------------------ | | 101| 0|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ ------------------ - | Branch (245:3): [True: 0, False: 21.7k] + | Branch (245:3): [True: 0, False: 195k] ------------------ - 246| 1.12k| case IKEV2_PAYLOAD_NOTIFY | IKED_E: + 246| 24.5k| case IKEV2_PAYLOAD_NOTIFY | IKED_E: ------------------ - | | 101| 1.12k|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ + | | 101| 24.5k|#define IKEV2_PAYLOAD_NOTIFY 41 /* Notify */ ------------------ case IKEV2_PAYLOAD_NOTIFY | IKED_E: ------------------ - | | 76| 1.12k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 24.5k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (246:3): [True: 1.12k, False: 20.6k] + | Branch (246:3): [True: 24.5k, False: 171k] ------------------ - 247| 1.12k| ret = ikev2_pld_notify(env, &pld, msg, offset, left); - 248| 1.12k| break; - 249| 812| case IKEV2_PAYLOAD_DELETE | IKED_E: + 247| 24.5k| ret = ikev2_pld_notify(env, &pld, msg, offset, left); + 248| 24.5k| break; + 249| 6.99k| case IKEV2_PAYLOAD_DELETE | IKED_E: ------------------ - | | 102| 812|#define IKEV2_PAYLOAD_DELETE 42 /* Delete */ + | | 102| 6.99k|#define IKEV2_PAYLOAD_DELETE 42 /* Delete */ ------------------ case IKEV2_PAYLOAD_DELETE | IKED_E: ------------------ - | | 76| 812|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 6.99k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (249:3): [True: 812, False: 20.9k] + | Branch (249:3): [True: 6.99k, False: 188k] ------------------ - 250| 812| ret = ikev2_pld_delete(env, &pld, msg, offset, left); - 251| 812| break; - 252| 351| case IKEV2_PAYLOAD_TSi | IKED_E: + 250| 6.99k| ret = ikev2_pld_delete(env, &pld, msg, offset, left); + 251| 6.99k| break; + 252| 4.44k| case IKEV2_PAYLOAD_TSi | IKED_E: ------------------ - | | 104| 351|#define IKEV2_PAYLOAD_TSi 44 /* Traffic Selector - Initiator */ + | | 104| 4.44k|#define IKEV2_PAYLOAD_TSi 44 /* Traffic Selector - Initiator */ ------------------ case IKEV2_PAYLOAD_TSi | IKED_E: ------------------ - | | 76| 351|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 4.44k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (252:3): [True: 351, False: 21.4k] + | Branch (252:3): [True: 4.44k, False: 191k] ------------------ - 253| 1.27k| case IKEV2_PAYLOAD_TSr | IKED_E: + 253| 16.3k| case IKEV2_PAYLOAD_TSr | IKED_E: ------------------ - | | 105| 1.27k|#define IKEV2_PAYLOAD_TSr 45 /* Traffic Selector - Responder */ + | | 105| 16.3k|#define IKEV2_PAYLOAD_TSr 45 /* Traffic Selector - Responder */ ------------------ case IKEV2_PAYLOAD_TSr | IKED_E: ------------------ - | | 76| 1.27k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 16.3k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (253:3): [True: 920, False: 20.8k] + | Branch (253:3): [True: 11.8k, False: 183k] ------------------ - 254| 1.27k| ret = ikev2_pld_tss(env, &pld, msg, offset, left); - 255| 1.27k| break; + 254| 16.3k| ret = ikev2_pld_tss(env, &pld, msg, offset, left); + 255| 16.3k| break; 256| 0| case IKEV2_PAYLOAD_SK: ------------------ | | 106| 0|#define IKEV2_PAYLOAD_SK 46 /* Encrypted */ ------------------ - | Branch (256:3): [True: 0, False: 21.7k] + | Branch (256:3): [True: 0, False: 195k] ------------------ 257| 0| ret = ikev2_pld_e(env, &pld, msg, offset, left); 258| 0| break; @@ -473,247 +473,247 @@ ikev2_pld_payloads: ------------------ | | 110| 0|#define IKEV2_PAYLOAD_SKF 53 /* RFC7383 Encrypted Fragment Payload */ ------------------ - | Branch (259:3): [True: 0, False: 21.7k] + | Branch (259:3): [True: 0, False: 195k] ------------------ 260| 0| ret = ikev2_pld_ef(env, &pld, msg, offset, left); 261| 0| break; - 262| 1.30k| case IKEV2_PAYLOAD_CP | IKED_E: + 262| 8.50k| case IKEV2_PAYLOAD_CP | IKED_E: ------------------ - | | 107| 1.30k|#define IKEV2_PAYLOAD_CP 47 /* Configuration Payload */ + | | 107| 8.50k|#define IKEV2_PAYLOAD_CP 47 /* Configuration Payload */ ------------------ case IKEV2_PAYLOAD_CP | IKED_E: ------------------ - | | 76| 1.30k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 8.50k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (262:3): [True: 1.30k, False: 20.4k] + | Branch (262:3): [True: 8.50k, False: 187k] ------------------ - 263| 1.30k| ret = ikev2_pld_cp(env, &pld, msg, offset, left); - 264| 1.30k| break; - 265| 3.33k| case IKEV2_PAYLOAD_EAP | IKED_E: + 263| 8.50k| ret = ikev2_pld_cp(env, &pld, msg, offset, left); + 264| 8.50k| break; + 265| 16.1k| case IKEV2_PAYLOAD_EAP | IKED_E: ------------------ - | | 108| 3.33k|#define IKEV2_PAYLOAD_EAP 48 /* Extensible Authentication */ + | | 108| 16.1k|#define IKEV2_PAYLOAD_EAP 48 /* Extensible Authentication */ ------------------ case IKEV2_PAYLOAD_EAP | IKED_E: ------------------ - | | 76| 3.33k|#define IKED_E 0x1000 /* Decrypted flag */ + | | 76| 16.1k|#define IKED_E 0x1000 /* Decrypted flag */ ------------------ - | Branch (265:3): [True: 3.33k, False: 18.4k] + | Branch (265:3): [True: 16.1k, False: 179k] ------------------ - 266| 3.33k| ret = ikev2_pld_eap(env, &pld, msg, offset, left); - 267| 3.33k| break; - 268| 4.09k| default: + 266| 16.1k| ret = ikev2_pld_eap(env, &pld, msg, offset, left); + 267| 16.1k| break; + 268| 47.8k| default: ------------------ - | Branch (268:3): [True: 4.09k, False: 17.6k] + | Branch (268:3): [True: 47.8k, False: 147k] ------------------ - 269| 4.09k| print_hex(msgbuf, offset, - 270| 4.09k| betoh16(pld.pld_length) - sizeof(pld)); - 271| 4.09k| break; - 272| 21.7k| } + 269| 47.8k| print_hex(msgbuf, offset, + 270| 47.8k| betoh16(pld.pld_length) - sizeof(pld)); + 271| 47.8k| break; + 272| 195k| } 273| | - 274| 21.7k| if (ret != 0 && ikev2_msg_frompeer(msg)) { + 274| 195k| if (ret != 0 && ikev2_msg_frompeer(msg)) { ------------------ - | Branch (274:7): [True: 10.8k, False: 10.8k] - | Branch (274:19): [True: 70, False: 10.8k] + | Branch (274:7): [True: 87.0k, False: 108k] + | Branch (274:19): [True: 706, False: 86.2k] ------------------ - 275| 70| (void)ikev2_send_informational(env, msg); - 276| 70| return (-1); - 277| 70| } + 275| 706| (void)ikev2_send_informational(env, msg); + 276| 706| return (-1); + 277| 706| } 278| | 279| | /* Encrypted payloads must appear last */ - 280| 21.6k| if ((payload == IKEV2_PAYLOAD_SK) || + 280| 194k| if ((payload == IKEV2_PAYLOAD_SK) || ------------------ - | | 106| 21.6k|#define IKEV2_PAYLOAD_SK 46 /* Encrypted */ + | | 106| 194k|#define IKEV2_PAYLOAD_SK 46 /* Encrypted */ ------------------ - | Branch (280:7): [True: 1, False: 21.6k] + | Branch (280:7): [True: 2, False: 194k] ------------------ - 281| 21.6k| (payload == IKEV2_PAYLOAD_SKF)) + 281| 194k| (payload == IKEV2_PAYLOAD_SKF)) ------------------ - | | 110| 21.6k|#define IKEV2_PAYLOAD_SKF 53 /* RFC7383 Encrypted Fragment Payload */ + | | 110| 194k|#define IKEV2_PAYLOAD_SKF 53 /* RFC7383 Encrypted Fragment Payload */ ------------------ - | Branch (281:7): [True: 1, False: 21.6k] + | Branch (281:7): [True: 2, False: 194k] ------------------ - 282| 2| return (0); + 282| 4| return (0); 283| | - 284| 21.6k| payload = pld.pld_nextpayload; - 285| 21.6k| offset += left; - 286| 21.6k| total -= left; - 287| 21.6k| } + 284| 194k| payload = pld.pld_nextpayload; + 285| 194k| offset += left; + 286| 194k| total -= left; + 287| 194k| } 288| | - 289| 456| return (0); - 290| 713|} + 289| 1.95k| return (0); + 290| 10.0k|} ikev2_validate_sa: - 295| 5.47k|{ - 296| 5.47k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 297| 5.47k| size_t sap_length; + 295| 31.4k|{ + 296| 31.4k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 297| 31.4k| size_t sap_length; 298| | - 299| 5.47k| if (left < sizeof(*sap)) { + 299| 31.4k| if (left < sizeof(*sap)) { ------------------ - | Branch (299:6): [True: 1.96k, False: 3.51k] + | Branch (299:6): [True: 13.3k, False: 18.0k] ------------------ - 300| 1.96k| log_debug("%s: malformed payload: too short for header " - 301| 1.96k| "(%zu < %zu)", __func__, left, sizeof(*sap)); - 302| 1.96k| return (-1); - 303| 1.96k| } - 304| 3.51k| memcpy(sap, msgbuf + offset, sizeof(*sap)); + 300| 13.3k| log_debug("%s: malformed payload: too short for header " + 301| 13.3k| "(%zu < %zu)", __func__, left, sizeof(*sap)); + 302| 13.3k| return (-1); + 303| 13.3k| } + 304| 18.0k| memcpy(sap, msgbuf + offset, sizeof(*sap)); 305| | - 306| 3.51k| sap_length = betoh16(sap->sap_length); - 307| 3.51k| if (sap_length < sizeof(*sap)) { + 306| 18.0k| sap_length = betoh16(sap->sap_length); + 307| 18.0k| if (sap_length < sizeof(*sap)) { ------------------ - | Branch (307:6): [True: 592, False: 2.92k] + | Branch (307:6): [True: 4.88k, False: 13.1k] ------------------ - 308| 592| log_debug("%s: malformed payload: shorter than minimum header " - 309| 592| "size (%zu < %zu)", __func__, sap_length, sizeof(*sap)); - 310| 592| return (-1); - 311| 592| } - 312| 2.92k| if (left < sap_length) { + 308| 4.88k| log_debug("%s: malformed payload: shorter than minimum header " + 309| 4.88k| "size (%zu < %zu)", __func__, sap_length, sizeof(*sap)); + 310| 4.88k| return (-1); + 311| 4.88k| } + 312| 13.1k| if (left < sap_length) { ------------------ - | Branch (312:6): [True: 298, False: 2.62k] + | Branch (312:6): [True: 2.19k, False: 10.9k] ------------------ - 313| 298| log_debug("%s: malformed payload: too long for actual payload " - 314| 298| "size (%zu < %zu)", __func__, left, sap_length); - 315| 298| return (-1); - 316| 298| } + 313| 2.19k| log_debug("%s: malformed payload: too long for actual payload " + 314| 2.19k| "size (%zu < %zu)", __func__, left, sap_length); + 315| 2.19k| return (-1); + 316| 2.19k| } 317| | /* 318| | * If there is only one proposal, sap_length must be the 319| | * total payload size. 320| | */ - 321| 2.62k| if (!sap->sap_more && left != sap_length) { + 321| 10.9k| if (!sap->sap_more && left != sap_length) { ------------------ - | Branch (321:6): [True: 307, False: 2.31k] - | Branch (321:24): [True: 10, False: 297] + | Branch (321:6): [True: 1.57k, False: 9.35k] + | Branch (321:24): [True: 30, False: 1.54k] ------------------ - 322| 10| log_debug("%s: malformed payload: SA payload length mismatches " - 323| 10| "single proposal substructure length (%zu != %zu)", - 324| 10| __func__, left, sap_length); - 325| 10| return (-1); - 326| 10| } + 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| 2.61k| if (sap->sap_more && left <= sap_length) { - ------------------ - | Branch (331:6): [True: 2.31k, False: 297] - | Branch (331:23): [True: 66, False: 2.25k] - ------------------ - 332| 66| log_debug("%s: malformed payload: SA payload too small for " - 333| 66| "further proposals (%zu <= %zu)", __func__, - 334| 66| left, sap_length); - 335| 66| return (-1); - 336| 66| } - 337| 2.54k| return (0); - 338| 2.61k|} + 331| 10.9k| if (sap->sap_more && left <= sap_length) { + ------------------ + | Branch (331:6): [True: 9.35k, False: 1.54k] + | Branch (331:23): [True: 828, False: 8.52k] + ------------------ + 332| 828| log_debug("%s: malformed payload: SA payload too small for " + 333| 828| "further proposals (%zu <= %zu)", __func__, + 334| 828| left, sap_length); + 335| 828| return (-1); + 336| 828| } + 337| 10.0k| return (0); + 338| 10.9k|} ikev2_pld_sa: - 343| 4.38k|{ - 344| 4.38k| struct ikev2_sa_proposal sap; - 345| 4.38k| struct iked_proposal *prop = NULL; - 346| 4.38k| uint32_t spi32; - 347| 4.38k| uint64_t spi = 0, spi64; - 348| 4.38k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 349| 4.38k| int r; - 350| 4.38k| struct iked_proposals *props; - 351| 4.38k| size_t total; + 343| 27.1k|{ + 344| 27.1k| struct ikev2_sa_proposal sap; + 345| 27.1k| struct iked_proposal *prop = NULL; + 346| 27.1k| uint32_t spi32; + 347| 27.1k| uint64_t spi = 0, spi64; + 348| 27.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 349| 27.1k| int r; + 350| 27.1k| struct iked_proposals *props; + 351| 27.1k| size_t total; 352| | - 353| 5.47k| do { - 354| 5.47k| if (ikev2_validate_sa(msg, offset, left, &sap)) + 353| 31.4k| do { + 354| 31.4k| if (ikev2_validate_sa(msg, offset, left, &sap)) ------------------ - | Branch (354:7): [True: 2.92k, False: 2.54k] + | Branch (354:7): [True: 21.3k, False: 10.0k] ------------------ - 355| 2.92k| return (-1); + 355| 21.3k| return (-1); 356| | 357| | /* Assumed size of the first proposals, including SPI if present. */ - 358| 2.54k| total = (betoh16(sap.sap_length) - sizeof(sap)); + 358| 10.0k| total = (betoh16(sap.sap_length) - sizeof(sap)); 359| | - 360| 2.54k| props = &msg->msg_parent->msg_proposals; + 360| 10.0k| props = &msg->msg_parent->msg_proposals; 361| | - 362| 2.54k| offset += sizeof(sap); - 363| 2.54k| left -= sizeof(sap); + 362| 10.0k| offset += sizeof(sap); + 363| 10.0k| left -= sizeof(sap); 364| | - 365| 2.54k| if (sap.sap_spisize) { + 365| 10.0k| if (sap.sap_spisize) { ------------------ - | Branch (365:7): [True: 381, False: 2.16k] + | Branch (365:7): [True: 1.38k, False: 8.69k] ------------------ - 366| 381| if (left < sap.sap_spisize) { + 366| 1.38k| if (left < sap.sap_spisize) { ------------------ - | Branch (366:8): [True: 69, False: 312] + | Branch (366:8): [True: 634, False: 748] ------------------ - 367| 69| log_debug("%s: malformed payload: SPI larger than " - 368| 69| "actual payload (%zu < %d)", __func__, left, - 369| 69| sap.sap_spisize); - 370| 69| return (-1); - 371| 69| } - 372| 312| if (total < sap.sap_spisize) { + 367| 634| log_debug("%s: malformed payload: SPI larger than " + 368| 634| "actual payload (%zu < %d)", __func__, left, + 369| 634| sap.sap_spisize); + 370| 634| return (-1); + 371| 634| } + 372| 748| if (total < sap.sap_spisize) { ------------------ - | Branch (372:8): [True: 66, False: 246] + | Branch (372:8): [True: 132, False: 616] ------------------ - 373| 66| log_debug("%s: malformed payload: SPI larger than " - 374| 66| "proposal (%zu < %d)", __func__, total, - 375| 66| sap.sap_spisize); - 376| 66| return (-1); - 377| 66| } - 378| 246| switch (sap.sap_spisize) { - 379| 80| case 4: + 373| 132| log_debug("%s: malformed payload: SPI larger than " + 374| 132| "proposal (%zu < %d)", __func__, total, + 375| 132| sap.sap_spisize); + 376| 132| return (-1); + 377| 132| } + 378| 616| switch (sap.sap_spisize) { + 379| 286| case 4: ------------------ - | Branch (379:4): [True: 80, False: 166] + | Branch (379:4): [True: 286, False: 330] ------------------ - 380| 80| memcpy(&spi32, msgbuf + offset, 4); - 381| 80| spi = betoh32(spi32); - 382| 80| break; - 383| 98| case 8: + 380| 286| memcpy(&spi32, msgbuf + offset, 4); + 381| 286| spi = betoh32(spi32); + 382| 286| break; + 383| 200| case 8: ------------------ - | Branch (383:4): [True: 98, False: 148] + | Branch (383:4): [True: 200, False: 416] ------------------ - 384| 98| memcpy(&spi64, msgbuf + offset, 8); - 385| 98| spi = betoh64(spi64); - 386| 98| break; - 387| 68| default: + 384| 200| memcpy(&spi64, msgbuf + offset, 8); + 385| 200| spi = betoh64(spi64); + 386| 200| break; + 387| 130| default: ------------------ - | Branch (387:4): [True: 68, False: 178] + | Branch (387:4): [True: 130, False: 486] ------------------ - 388| 68| log_debug("%s: unsupported SPI size %d", - 389| 68| __func__, sap.sap_spisize); - 390| 68| return (-1); - 391| 246| } + 388| 130| log_debug("%s: unsupported SPI size %d", + 389| 130| __func__, sap.sap_spisize); + 390| 130| return (-1); + 391| 616| } 392| | - 393| 178| offset += sap.sap_spisize; - 394| 178| left -= sap.sap_spisize; + 393| 486| offset += sap.sap_spisize; + 394| 486| left -= sap.sap_spisize; 395| | 396| | /* Assumed size of the proposal, now without SPI. */ - 397| 178| total -= sap.sap_spisize; - 398| 178| } + 397| 486| total -= sap.sap_spisize; + 398| 486| } 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| 2.34k| if (left < total) { + 404| 9.18k| if (left < total) { ------------------ - | Branch (404:7): [True: 0, False: 2.34k] + | Branch (404:7): [True: 0, False: 9.18k] ------------------ 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| 2.34k| log_debug("%s: more %d reserved %d length %d" - 411| 2.34k| " proposal #%d protoid %s spisize %d xforms %d spi %s", - 412| 2.34k| __func__, sap.sap_more, sap.sap_reserved, - 413| 2.34k| betoh16(sap.sap_length), sap.sap_proposalnr, - 414| 2.34k| print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize, - 415| 2.34k| sap.sap_transforms, print_spi(spi, sap.sap_spisize)); + 410| 9.18k| log_debug("%s: more %d reserved %d length %d" + 411| 9.18k| " proposal #%d protoid %s spisize %d xforms %d spi %s", + 412| 9.18k| __func__, sap.sap_more, sap.sap_reserved, + 413| 9.18k| betoh16(sap.sap_length), sap.sap_proposalnr, + 414| 9.18k| print_map(sap.sap_protoid, ikev2_saproto_map), sap.sap_spisize, + 415| 9.18k| sap.sap_transforms, print_spi(spi, sap.sap_spisize)); 416| | - 417| 2.34k| if (ikev2_msg_frompeer(msg)) { + 417| 9.18k| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (417:7): [True: 3, False: 2.34k] + | Branch (417:7): [True: 69, False: 9.11k] ------------------ - 418| 3| if ((msg->msg_parent->msg_prop = config_add_proposal(props, + 418| 69| if ((msg->msg_parent->msg_prop = config_add_proposal(props, ------------------ - | Branch (418:8): [True: 3, False: 0] + | Branch (418:8): [True: 69, False: 0] ------------------ - 419| 3| sap.sap_proposalnr, sap.sap_protoid)) == NULL) { - 420| 3| log_debug("%s: invalid proposal", __func__); - 421| 3| return (-1); - 422| 3| } + 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; @@ -726,14 +726,14 @@ ikev2_pld_sa: 432| | /* 433| | * Parse the attached transforms 434| | */ - 435| 2.34k| if (sap.sap_transforms) { + 435| 9.11k| if (sap.sap_transforms) { ------------------ - | Branch (435:7): [True: 1.37k, False: 972] + | Branch (435:7): [True: 5.13k, False: 3.98k] ------------------ - 436| 1.37k| r = ikev2_pld_xform(env, msg, offset, total); - 437| 1.37k| if ((r == -2) && ikev2_msg_frompeer(msg)) { + 436| 5.13k| r = ikev2_pld_xform(env, msg, offset, total); + 437| 5.13k| if ((r == -2) && ikev2_msg_frompeer(msg)) { ------------------ - | Branch (437:8): [True: 0, False: 1.37k] + | Branch (437:8): [True: 0, False: 5.13k] | Branch (437:21): [True: 0, False: 0] ------------------ 438| 0| log_debug("%s: invalid proposal transform", @@ -742,155 +742,155 @@ 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| 1.37k| } else if (r != 0) { + 444| 5.13k| } else if (r != 0) { ------------------ - | Branch (444:15): [True: 1.05k, False: 314] + | Branch (444:15): [True: 4.07k, False: 1.05k] ------------------ - 445| 1.05k| log_debug("%s: invalid proposal transforms", - 446| 1.05k| __func__); - 447| 1.05k| return (-1); - 448| 1.05k| } - 449| 1.37k| } + 445| 4.07k| log_debug("%s: invalid proposal transforms", + 446| 4.07k| __func__); + 447| 4.07k| return (-1); + 448| 4.07k| } + 449| 5.13k| } 450| | - 451| 1.28k| offset += total; - 452| 1.28k| left -= total; - 453| 1.28k| } while (sap.sap_more); + 451| 5.03k| offset += total; + 452| 5.03k| left -= total; + 453| 5.03k| } while (sap.sap_more); ------------------ - | Branch (453:11): [True: 1.09k, False: 190] + | Branch (453:11): [True: 4.30k, False: 733] ------------------ 454| | - 455| 190| return (0); - 456| 4.38k|} + 455| 733| return (0); + 456| 27.1k|} ikev2_validate_xform: - 461| 1.76k|{ - 462| 1.76k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 463| 1.76k| size_t xfrm_length; + 461| 6.66k|{ + 462| 6.66k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 463| 6.66k| size_t xfrm_length; 464| | - 465| 1.76k| if (total < sizeof(*xfrm)) { + 465| 6.66k| if (total < sizeof(*xfrm)) { ------------------ - | Branch (465:6): [True: 168, False: 1.59k] + | Branch (465:6): [True: 551, False: 6.11k] ------------------ - 466| 168| log_debug("%s: malformed payload: too short for header " - 467| 168| "(%zu < %zu)", __func__, total, sizeof(*xfrm)); - 468| 168| return (-1); - 469| 168| } - 470| 1.59k| memcpy(xfrm, msgbuf + offset, sizeof(*xfrm)); + 466| 551| log_debug("%s: malformed payload: too short for header " + 467| 551| "(%zu < %zu)", __func__, total, sizeof(*xfrm)); + 468| 551| return (-1); + 469| 551| } + 470| 6.11k| memcpy(xfrm, msgbuf + offset, sizeof(*xfrm)); 471| | - 472| 1.59k| xfrm_length = betoh16(xfrm->xfrm_length); - 473| 1.59k| if (xfrm_length < sizeof(*xfrm)) { + 472| 6.11k| xfrm_length = betoh16(xfrm->xfrm_length); + 473| 6.11k| if (xfrm_length < sizeof(*xfrm)) { ------------------ - | Branch (473:6): [True: 129, False: 1.46k] + | Branch (473:6): [True: 1.12k, False: 4.99k] ------------------ - 474| 129| log_debug("%s: malformed payload: shorter than minimum header " - 475| 129| "size (%zu < %zu)", __func__, xfrm_length, sizeof(*xfrm)); - 476| 129| return (-1); - 477| 129| } - 478| 1.46k| if (total < xfrm_length) { + 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| 4.99k| if (total < xfrm_length) { ------------------ - | Branch (478:6): [True: 113, False: 1.35k] + | Branch (478:6): [True: 599, False: 4.39k] ------------------ - 479| 113| log_debug("%s: malformed payload: too long for payload size " - 480| 113| "(%zu < %zu)", __func__, total, xfrm_length); - 481| 113| return (-1); - 482| 113| } + 479| 599| log_debug("%s: malformed payload: too long for payload size " + 480| 599| "(%zu < %zu)", __func__, total, xfrm_length); + 481| 599| return (-1); + 482| 599| } 483| | - 484| 1.35k| return (0); - 485| 1.46k|} + 484| 4.39k| return (0); + 485| 4.99k|} ikev2_pld_xform: - 490| 1.76k|{ - 491| 1.76k| struct ikev2_transform xfrm; - 492| 1.76k| char id[BUFSIZ]; - 493| 1.76k| int ret = 0; - 494| 1.76k| int r; - 495| 1.76k| size_t xfrm_length; + 490| 6.66k|{ + 491| 6.66k| struct ikev2_transform xfrm; + 492| 6.66k| char id[BUFSIZ]; + 493| 6.66k| int ret = 0; + 494| 6.66k| int r; + 495| 6.66k| size_t xfrm_length; 496| | - 497| 1.76k| if (ikev2_validate_xform(msg, offset, total, &xfrm)) + 497| 6.66k| if (ikev2_validate_xform(msg, offset, total, &xfrm)) ------------------ - | Branch (497:6): [True: 410, False: 1.35k] + | Branch (497:6): [True: 2.27k, False: 4.39k] ------------------ - 498| 410| return (-1); + 498| 2.27k| return (-1); 499| | - 500| 1.35k| xfrm_length = betoh16(xfrm.xfrm_length); + 500| 4.39k| xfrm_length = betoh16(xfrm.xfrm_length); 501| | - 502| 1.35k| switch (xfrm.xfrm_type) { - 503| 334| case IKEV2_XFORMTYPE_ENCR: + 502| 4.39k| switch (xfrm.xfrm_type) { + 503| 1.05k| case IKEV2_XFORMTYPE_ENCR: ------------------ - | | 156| 334|#define IKEV2_XFORMTYPE_ENCR 1 /* Encryption */ + | | 156| 1.05k|#define IKEV2_XFORMTYPE_ENCR 1 /* Encryption */ ------------------ - | Branch (503:2): [True: 334, False: 1.01k] + | Branch (503:2): [True: 1.05k, False: 3.33k] ------------------ - 504| 334| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), - 505| 334| ikev2_xformencr_map), sizeof(id)); - 506| 334| break; - 507| 434| case IKEV2_XFORMTYPE_PRF: + 504| 1.05k| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), + 505| 1.05k| ikev2_xformencr_map), sizeof(id)); + 506| 1.05k| break; + 507| 765| case IKEV2_XFORMTYPE_PRF: ------------------ - | | 157| 434|#define IKEV2_XFORMTYPE_PRF 2 /* Pseudo-Random Function */ + | | 157| 765|#define IKEV2_XFORMTYPE_PRF 2 /* Pseudo-Random Function */ ------------------ - | Branch (507:2): [True: 434, False: 916] + | Branch (507:2): [True: 765, False: 3.62k] ------------------ - 508| 434| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), - 509| 434| ikev2_xformprf_map), sizeof(id)); - 510| 434| break; - 511| 67| case IKEV2_XFORMTYPE_INTEGR: + 508| 765| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), + 509| 765| ikev2_xformprf_map), sizeof(id)); + 510| 765| break; + 511| 154| case IKEV2_XFORMTYPE_INTEGR: ------------------ - | | 158| 67|#define IKEV2_XFORMTYPE_INTEGR 3 /* Integrity Algorithm */ + | | 158| 154|#define IKEV2_XFORMTYPE_INTEGR 3 /* Integrity Algorithm */ ------------------ - | Branch (511:2): [True: 67, False: 1.28k] + | Branch (511:2): [True: 154, False: 4.23k] ------------------ - 512| 67| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), - 513| 67| ikev2_xformauth_map), sizeof(id)); - 514| 67| break; - 515| 68| case IKEV2_XFORMTYPE_DH: + 512| 154| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), + 513| 154| ikev2_xformauth_map), sizeof(id)); + 514| 154| break; + 515| 247| case IKEV2_XFORMTYPE_DH: ------------------ - | | 159| 68|#define IKEV2_XFORMTYPE_DH 4 /* Diffie-Hellman Group */ + | | 159| 247|#define IKEV2_XFORMTYPE_DH 4 /* Diffie-Hellman Group */ ------------------ - | Branch (515:2): [True: 68, False: 1.28k] + | Branch (515:2): [True: 247, False: 4.14k] ------------------ - 516| 68| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), - 517| 68| ikev2_xformdh_map), sizeof(id)); - 518| 68| break; - 519| 66| case IKEV2_XFORMTYPE_ESN: + 516| 247| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), + 517| 247| ikev2_xformdh_map), sizeof(id)); + 518| 247| break; + 519| 1.00k| case IKEV2_XFORMTYPE_ESN: ------------------ - | | 160| 66|#define IKEV2_XFORMTYPE_ESN 5 /* Extended Sequence Numbers */ + | | 160| 1.00k|#define IKEV2_XFORMTYPE_ESN 5 /* Extended Sequence Numbers */ ------------------ - | Branch (519:2): [True: 66, False: 1.28k] + | Branch (519:2): [True: 1.00k, False: 3.39k] ------------------ - 520| 66| strlcpy(id, print_map(betoh16(xfrm.xfrm_id), - 521| 66| ikev2_xformesn_map), sizeof(id)); - 522| 66| break; - 523| 381| default: + 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.16k| default: ------------------ - | Branch (523:2): [True: 381, False: 969] + | Branch (523:2): [True: 1.16k, False: 3.22k] ------------------ - 524| 381| snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id)); - 525| 381| break; - 526| 1.35k| } + 524| 1.16k| snprintf(id, sizeof(id), "<%d>", betoh16(xfrm.xfrm_id)); + 525| 1.16k| break; + 526| 4.39k| } 527| | - 528| 1.35k| log_debug("%s: more %d reserved %d length %zu" - 529| 1.35k| " type %s id %s", - 530| 1.35k| __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length, - 531| 1.35k| print_map(xfrm.xfrm_type, ikev2_xformtype_map), id); + 528| 4.39k| log_debug("%s: more %d reserved %d length %zu" + 529| 4.39k| " type %s id %s", + 530| 4.39k| __func__, xfrm.xfrm_more, xfrm.xfrm_reserved, xfrm_length, + 531| 4.39k| print_map(xfrm.xfrm_type, ikev2_xformtype_map), id); 532| | 533| | /* 534| | * Parse transform attributes, if available 535| | */ - 536| 1.35k| msg->msg_attrlength = 0; - 537| 1.35k| if (xfrm_length > sizeof(xfrm)) { + 536| 4.39k| msg->msg_attrlength = 0; + 537| 4.39k| if (xfrm_length > sizeof(xfrm)) { ------------------ - | Branch (537:6): [True: 839, False: 511] + | Branch (537:6): [True: 2.18k, False: 2.20k] ------------------ - 538| 839| if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm), + 538| 2.18k| if (ikev2_pld_attr(env, &xfrm, msg, offset + sizeof(xfrm), ------------------ - | Branch (538:7): [True: 568, False: 271] + | Branch (538:7): [True: 1.65k, False: 528] ------------------ - 539| 839| xfrm_length - sizeof(xfrm)) != 0) { - 540| 568| return (-1); - 541| 568| } - 542| 839| } + 539| 2.18k| xfrm_length - sizeof(xfrm)) != 0) { + 540| 1.65k| return (-1); + 541| 1.65k| } + 542| 2.18k| } 543| | - 544| 782| if (ikev2_msg_frompeer(msg)) { + 544| 2.73k| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (544:6): [True: 0, False: 782] + | Branch (544:6): [True: 0, False: 2.73k] ------------------ 545| 0| r = config_add_transform(msg->msg_parent->msg_prop, 546| 0| xfrm.xfrm_type, betoh16(xfrm.xfrm_id), @@ -913,765 +913,765 @@ ikev2_pld_xform: 557| 0| } 558| | 559| | /* Next transform */ - 560| 782| offset += xfrm_length; - 561| 782| total -= xfrm_length; - 562| 782| if (xfrm.xfrm_more == IKEV2_XFORM_MORE) + 560| 2.73k| offset += xfrm_length; + 561| 2.73k| total -= xfrm_length; + 562| 2.73k| if (xfrm.xfrm_more == IKEV2_XFORM_MORE) ------------------ - | | 154| 782|#define IKEV2_XFORM_MORE 3 + | | 154| 2.73k|#define IKEV2_XFORM_MORE 3 ------------------ - | Branch (562:6): [True: 389, False: 393] + | Branch (562:6): [True: 1.53k, False: 1.20k] ------------------ - 563| 389| ret = ikev2_pld_xform(env, msg, offset, total); - 564| 393| else if (total != 0) { + 563| 1.53k| ret = ikev2_pld_xform(env, msg, offset, total); + 564| 1.20k| else if (total != 0) { ------------------ - | Branch (564:11): [True: 79, False: 314] + | Branch (564:11): [True: 146, False: 1.05k] ------------------ 565| | /* No more transforms but still some data left. */ - 566| 79| log_debug("%s: less data than specified, %zu bytes left", - 567| 79| __func__, total); - 568| 79| ret = -1; - 569| 79| } + 566| 146| log_debug("%s: less data than specified, %zu bytes left", + 567| 146| __func__, total); + 568| 146| ret = -1; + 569| 146| } 570| | - 571| 782| return (ret); - 572| 782|} + 571| 2.73k| return (ret); + 572| 2.73k|} ikev2_validate_attr: - 577| 1.91k|{ - 578| 1.91k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 577| 28.9k|{ + 578| 28.9k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 579| | - 580| 1.91k| if (total < sizeof(*attr)) { + 580| 28.9k| if (total < sizeof(*attr)) { ------------------ - | Branch (580:6): [True: 104, False: 1.80k] + | Branch (580:6): [True: 708, False: 28.2k] ------------------ - 581| 104| log_debug("%s: malformed payload: too short for header " - 582| 104| "(%zu < %zu)", __func__, total, sizeof(*attr)); - 583| 104| return (-1); - 584| 104| } - 585| 1.80k| memcpy(attr, msgbuf + offset, sizeof(*attr)); + 581| 708| log_debug("%s: malformed payload: too short for header " + 582| 708| "(%zu < %zu)", __func__, total, sizeof(*attr)); + 583| 708| return (-1); + 584| 708| } + 585| 28.2k| memcpy(attr, msgbuf + offset, sizeof(*attr)); 586| | - 587| 1.80k| return (0); - 588| 1.91k|} + 587| 28.2k| return (0); + 588| 28.9k|} ikev2_pld_attr: - 593| 1.91k|{ - 594| 1.91k| struct ikev2_attribute attr; - 595| 1.91k| unsigned int type; - 596| 1.91k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 597| 1.91k| int ret = 0; - 598| 1.91k| size_t attr_length; + 593| 28.9k|{ + 594| 28.9k| struct ikev2_attribute attr; + 595| 28.9k| unsigned int type; + 596| 28.9k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 597| 28.9k| int ret = 0; + 598| 28.9k| size_t attr_length; 599| | - 600| 1.91k| if (ikev2_validate_attr(msg, offset, total, &attr)) + 600| 28.9k| if (ikev2_validate_attr(msg, offset, total, &attr)) ------------------ - | Branch (600:6): [True: 104, False: 1.80k] + | Branch (600:6): [True: 708, False: 28.2k] ------------------ - 601| 104| return (-1); + 601| 708| return (-1); 602| | - 603| 1.80k| type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV; + 603| 28.2k| type = betoh16(attr.attr_type) & ~IKEV2_ATTRAF_TV; ------------------ - | | 279| 1.80k|#define IKEV2_ATTRAF_TV 0x8000 /* Type-Value format */ + | | 279| 28.2k|#define IKEV2_ATTRAF_TV 0x8000 /* Type-Value format */ ------------------ 604| | - 605| 1.80k| log_debug("%s: attribute type %s length %d total %zu", - 606| 1.80k| __func__, print_map(type, ikev2_attrtype_map), - 607| 1.80k| betoh16(attr.attr_length), total); + 605| 28.2k| log_debug("%s: attribute type %s length %d total %zu", + 606| 28.2k| __func__, print_map(type, ikev2_attrtype_map), + 607| 28.2k| betoh16(attr.attr_length), total); 608| | - 609| 1.80k| if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) { + 609| 28.2k| if (betoh16(attr.attr_type) & IKEV2_ATTRAF_TV) { ------------------ - | | 279| 1.80k|#define IKEV2_ATTRAF_TV 0x8000 /* Type-Value format */ + | | 279| 28.2k|#define IKEV2_ATTRAF_TV 0x8000 /* Type-Value format */ ------------------ - | Branch (609:6): [True: 1.07k, False: 732] + | Branch (609:6): [True: 21.9k, False: 6.31k] ------------------ 610| | /* Type-Value attribute */ - 611| 1.07k| offset += sizeof(attr); - 612| 1.07k| total -= sizeof(attr); + 611| 21.9k| offset += sizeof(attr); + 612| 21.9k| total -= sizeof(attr); 613| | - 614| 1.07k| if (type == IKEV2_ATTRTYPE_KEY_LENGTH) + 614| 21.9k| if (type == IKEV2_ATTRTYPE_KEY_LENGTH) ------------------ - | | 281| 1.07k|#define IKEV2_ATTRTYPE_KEY_LENGTH 14 /* Key length */ + | | 281| 21.9k|#define IKEV2_ATTRTYPE_KEY_LENGTH 14 /* Key length */ ------------------ - | Branch (614:7): [True: 34, False: 1.04k] + | Branch (614:7): [True: 45, False: 21.9k] ------------------ - 615| 34| msg->msg_attrlength = betoh16(attr.attr_length); - 616| 1.07k| } else { + 615| 45| msg->msg_attrlength = betoh16(attr.attr_length); + 616| 21.9k| } else { 617| | /* Type-Length-Value attribute */ - 618| 732| attr_length = betoh16(attr.attr_length); - 619| 732| if (attr_length < sizeof(attr)) { - ------------------ - | Branch (619:7): [True: 244, False: 488] - ------------------ - 620| 244| log_debug("%s: malformed payload: shorter than " - 621| 244| "minimum header size (%zu < %zu)", __func__, - 622| 244| attr_length, sizeof(attr)); - 623| 244| return (-1); - 624| 244| } - 625| 488| if (total < attr_length) { - ------------------ - | Branch (625:7): [True: 220, False: 268] - ------------------ - 626| 220| log_debug("%s: malformed payload: attribute larger " - 627| 220| "than actual payload (%zu < %zu)", __func__, - 628| 220| total, attr_length); - 629| 220| return (-1); - 630| 220| } - 631| 268| print_hex(msgbuf, offset + sizeof(attr), - 632| 268| attr_length - sizeof(attr)); - 633| 268| offset += attr_length; - 634| 268| total -= attr_length; - 635| 268| } + 618| 6.31k| attr_length = betoh16(attr.attr_length); + 619| 6.31k| if (attr_length < sizeof(attr)) { + ------------------ + | Branch (619:7): [True: 526, False: 5.78k] + ------------------ + 620| 526| log_debug("%s: malformed payload: shorter than " + 621| 526| "minimum header size (%zu < %zu)", __func__, + 622| 526| attr_length, sizeof(attr)); + 623| 526| return (-1); + 624| 526| } + 625| 5.78k| if (total < attr_length) { + ------------------ + | Branch (625:7): [True: 422, False: 5.36k] + ------------------ + 626| 422| log_debug("%s: malformed payload: attribute larger " + 627| 422| "than actual payload (%zu < %zu)", __func__, + 628| 422| total, attr_length); + 629| 422| return (-1); + 630| 422| } + 631| 5.36k| print_hex(msgbuf, offset + sizeof(attr), + 632| 5.36k| attr_length - sizeof(attr)); + 633| 5.36k| offset += attr_length; + 634| 5.36k| total -= attr_length; + 635| 5.36k| } 636| | - 637| 1.34k| if (total > 0) { + 637| 27.3k| if (total > 0) { ------------------ - | Branch (637:6): [True: 1.07k, False: 271] + | Branch (637:6): [True: 26.7k, False: 528] ------------------ 638| | /* Next attribute */ - 639| 1.07k| ret = ikev2_pld_attr(env, xfrm, msg, offset, total); - 640| 1.07k| } + 639| 26.7k| ret = ikev2_pld_attr(env, xfrm, msg, offset, total); + 640| 26.7k| } 641| | - 642| 1.34k| return (ret); - 643| 1.80k|} + 642| 27.3k| return (ret); + 643| 28.2k|} ikev2_validate_ke: - 648| 644|{ - 649| 644| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 648| 5.93k|{ + 649| 5.93k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 650| | - 651| 644| if (left < sizeof(*kex)) { + 651| 5.93k| if (left < sizeof(*kex)) { ------------------ - | Branch (651:6): [True: 440, False: 204] + | Branch (651:6): [True: 3.70k, False: 2.22k] ------------------ - 652| 440| log_debug("%s: malformed payload: too short for header " - 653| 440| "(%zu < %zu)", __func__, left, sizeof(*kex)); - 654| 440| return (-1); - 655| 440| } - 656| 204| memcpy(kex, msgbuf + offset, sizeof(*kex)); + 652| 3.70k| log_debug("%s: malformed payload: too short for header " + 653| 3.70k| "(%zu < %zu)", __func__, left, sizeof(*kex)); + 654| 3.70k| return (-1); + 655| 3.70k| } + 656| 2.22k| memcpy(kex, msgbuf + offset, sizeof(*kex)); 657| | - 658| 204| return (0); - 659| 644|} + 658| 2.22k| return (0); + 659| 5.93k|} ikev2_pld_ke: - 664| 644|{ - 665| 644| struct ikev2_keyexchange kex; - 666| 644| uint8_t *buf; - 667| 644| size_t len; - 668| 644| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 664| 5.93k|{ + 665| 5.93k| struct ikev2_keyexchange kex; + 666| 5.93k| uint8_t *buf; + 667| 5.93k| size_t len; + 668| 5.93k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 669| | - 670| 644| if (ikev2_validate_ke(msg, offset, left, &kex)) + 670| 5.93k| if (ikev2_validate_ke(msg, offset, left, &kex)) ------------------ - | Branch (670:6): [True: 440, False: 204] + | Branch (670:6): [True: 3.70k, False: 2.22k] ------------------ - 671| 440| return (-1); + 671| 3.70k| return (-1); 672| | - 673| 204| log_debug("%s: dh group %s reserved %d", __func__, - 674| 204| print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map), - 675| 204| betoh16(kex.kex_reserved)); + 673| 2.22k| log_debug("%s: dh group %s reserved %d", __func__, + 674| 2.22k| print_map(betoh16(kex.kex_dhgroup), ikev2_xformdh_map), + 675| 2.22k| betoh16(kex.kex_reserved)); 676| | - 677| 204| buf = msgbuf + offset + sizeof(kex); - 678| 204| len = left - sizeof(kex); + 677| 2.22k| buf = msgbuf + offset + sizeof(kex); + 678| 2.22k| len = left - sizeof(kex); 679| | - 680| 204| if (len == 0) { + 680| 2.22k| if (len == 0) { ------------------ - | Branch (680:6): [True: 68, False: 136] + | Branch (680:6): [True: 651, False: 1.57k] ------------------ - 681| 68| log_debug("%s: malformed payload: no KE data given", __func__); - 682| 68| return (-1); - 683| 68| } + 681| 651| log_debug("%s: malformed payload: no KE data given", __func__); + 682| 651| return (-1); + 683| 651| } 684| | - 685| 136| print_hex(buf, 0, len); + 685| 1.57k| print_hex(buf, 0, len); 686| | - 687| 136| if (ikev2_msg_frompeer(msg)) { + 687| 1.57k| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (687:6): [True: 3, False: 133] + | Branch (687:6): [True: 27, False: 1.54k] ------------------ - 688| 3| if (msg->msg_parent->msg_ke != NULL) { + 688| 27| if (msg->msg_parent->msg_ke != NULL) { ------------------ - | Branch (688:7): [True: 1, False: 2] + | Branch (688:7): [True: 4, False: 23] ------------------ - 689| 1| log_info("%s: duplicate KE payload", __func__); - 690| 1| return (-1); - 691| 1| } - 692| 2| if ((msg->msg_parent->msg_ke = ibuf_new(buf, len)) == 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) { ------------------ - | Branch (692:7): [True: 0, False: 2] + | Branch (692:7): [True: 0, False: 23] ------------------ 693| 0| log_debug("%s: failed to get exchange", __func__); 694| 0| return (-1); 695| 0| } - 696| 2| msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup); - 697| 2| } + 696| 23| msg->msg_parent->msg_dhgroup = betoh16(kex.kex_dhgroup); + 697| 23| } 698| | - 699| 135| return (0); - 700| 136|} + 699| 1.57k| return (0); + 700| 1.57k|} ikev2_validate_id: - 705| 1.77k|{ - 706| 1.77k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 705| 18.5k|{ + 706| 18.5k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 707| | - 708| 1.77k| if (left < sizeof(*id)) { + 708| 18.5k| if (left < sizeof(*id)) { ------------------ - | Branch (708:6): [True: 893, False: 880] + | Branch (708:6): [True: 7.36k, False: 11.1k] ------------------ - 709| 893| log_debug("%s: malformed payload: too short for header " - 710| 893| "(%zu < %zu)", __func__, left, sizeof(*id)); - 711| 893| return (-1); - 712| 893| } - 713| 880| memcpy(id, msgbuf + offset, sizeof(*id)); + 709| 7.36k| log_debug("%s: malformed payload: too short for header " + 710| 7.36k| "(%zu < %zu)", __func__, left, sizeof(*id)); + 711| 7.36k| return (-1); + 712| 7.36k| } + 713| 11.1k| memcpy(id, msgbuf + offset, sizeof(*id)); 714| | - 715| 880| if (id->id_type == IKEV2_ID_NONE) { + 715| 11.1k| if (id->id_type == IKEV2_ID_NONE) { ------------------ - | | 397| 880|#define IKEV2_ID_NONE 0 /* No ID */ + | | 397| 11.1k|#define IKEV2_ID_NONE 0 /* No ID */ ------------------ - | Branch (715:6): [True: 222, False: 658] + | Branch (715:6): [True: 6.41k, False: 4.75k] ------------------ - 716| 222| log_debug("%s: malformed payload: invalid ID type.", - 717| 222| __func__); - 718| 222| return (-1); - 719| 222| } + 716| 6.41k| log_debug("%s: malformed payload: invalid ID type.", + 717| 6.41k| __func__); + 718| 6.41k| return (-1); + 719| 6.41k| } 720| | - 721| 658| return (0); - 722| 880|} + 721| 4.75k| return (0); + 722| 11.1k|} ikev2_pld_id: - 727| 1.77k|{ - 728| 1.77k| uint8_t *ptr; - 729| 1.77k| struct ikev2_id id; - 730| 1.77k| size_t len; - 731| 1.77k| struct iked_id *idp, idb; - 732| 1.77k| const struct iked_sa *sa = msg->msg_sa; - 733| 1.77k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 734| 1.77k| char idstr[IKED_ID_SIZE]; + 727| 18.5k|{ + 728| 18.5k| uint8_t *ptr; + 729| 18.5k| struct ikev2_id id; + 730| 18.5k| size_t len; + 731| 18.5k| struct iked_id *idp, idb; + 732| 18.5k| const struct iked_sa *sa = msg->msg_sa; + 733| 18.5k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 734| 18.5k| char idstr[IKED_ID_SIZE]; 735| | - 736| 1.77k| if (ikev2_validate_id(msg, offset, left, &id)) + 736| 18.5k| if (ikev2_validate_id(msg, offset, left, &id)) ------------------ - | Branch (736:6): [True: 1.11k, False: 658] + | Branch (736:6): [True: 13.7k, False: 4.75k] ------------------ - 737| 1.11k| return (-1); + 737| 13.7k| return (-1); 738| | - 739| 658| bzero(&idb, sizeof(idb)); + 739| 4.75k| bzero(&idb, sizeof(idb)); 740| | 741| | /* Don't strip the Id payload header */ - 742| 658| ptr = msgbuf + offset; - 743| 658| len = left; + 742| 4.75k| ptr = msgbuf + offset; + 743| 4.75k| len = left; 744| | - 745| 658| idb.id_type = id.id_type; - 746| 658| idb.id_offset = sizeof(id); - 747| 658| if ((idb.id_buf = ibuf_new(ptr, len)) == NULL) + 745| 4.75k| idb.id_type = id.id_type; + 746| 4.75k| idb.id_offset = sizeof(id); + 747| 4.75k| if ((idb.id_buf = ibuf_new(ptr, len)) == NULL) ------------------ - | Branch (747:6): [True: 0, False: 658] + | Branch (747:6): [True: 0, False: 4.75k] ------------------ 748| 0| return (-1); 749| | - 750| 658| if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) { + 750| 4.75k| if (ikev2_print_id(&idb, idstr, sizeof(idstr)) == -1) { ------------------ - | Branch (750:6): [True: 0, False: 658] + | Branch (750:6): [True: 0, False: 4.75k] ------------------ 751| 0| ibuf_free(idb.id_buf); 752| 0| log_debug("%s: malformed id", __func__); 753| 0| return (-1); 754| 0| } 755| | - 756| 658| log_debug("%s: id %s length %zu", __func__, idstr, len); + 756| 4.75k| log_debug("%s: id %s length %zu", __func__, idstr, len); 757| | - 758| 658| if (!ikev2_msg_frompeer(msg)) { + 758| 4.75k| if (!ikev2_msg_frompeer(msg)) { ------------------ - | Branch (758:6): [True: 648, False: 10] + | Branch (758:6): [True: 4.65k, False: 101] ------------------ - 759| 648| ibuf_free(idb.id_buf); - 760| 648| return (0); - 761| 648| } + 759| 4.65k| ibuf_free(idb.id_buf); + 760| 4.65k| return (0); + 761| 4.65k| } 762| | - 763| 10| if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) || + 763| 101| if (((sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) || ------------------ | | 96| 0|#define IKEV2_PAYLOAD_IDr 36 /* Identification - Responder */ ------------------ - | Branch (763:8): [True: 0, False: 10] + | Branch (763:8): [True: 0, False: 101] | Branch (763:35): [True: 0, False: 0] ------------------ - 764| 10| (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi))) + 764| 101| (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDi))) ------------------ - | | 95| 10|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ + | | 95| 101|#define IKEV2_PAYLOAD_IDi 35 /* Identification - Initiator */ ------------------ - | Branch (764:7): [True: 10, False: 0] - | Branch (764:35): [True: 6, False: 4] + | Branch (764:7): [True: 101, False: 0] + | Branch (764:35): [True: 59, False: 42] ------------------ - 765| 6| idp = &msg->msg_parent->msg_peerid; - 766| 4| else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) + 765| 59| idp = &msg->msg_parent->msg_peerid; + 766| 42| else if (!sa->sa_hdr.sh_initiator && payload == IKEV2_PAYLOAD_IDr) ------------------ - | | 96| 4|#define IKEV2_PAYLOAD_IDr 36 /* Identification - Responder */ + | | 96| 42|#define IKEV2_PAYLOAD_IDr 36 /* Identification - Responder */ ------------------ - | Branch (766:11): [True: 4, False: 0] - | Branch (766:39): [True: 4, False: 0] + | Branch (766:11): [True: 42, False: 0] + | Branch (766:39): [True: 42, False: 0] ------------------ - 767| 4| idp = &msg->msg_parent->msg_localid; + 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| 10| if (idp->id_type) { + 774| 101| if (idp->id_type) { ------------------ - | Branch (774:6): [True: 2, False: 8] + | Branch (774:6): [True: 16, False: 85] ------------------ - 775| 2| ibuf_free(idb.id_buf); - 776| 2| log_debug("%s: duplicate id payload", __func__); - 777| 2| return (-1); - 778| 2| } + 775| 16| ibuf_free(idb.id_buf); + 776| 16| log_debug("%s: duplicate id payload", __func__); + 777| 16| return (-1); + 778| 16| } 779| | - 780| 8| idp->id_buf = idb.id_buf; - 781| 8| idp->id_offset = idb.id_offset; - 782| 8| idp->id_type = idb.id_type; + 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| 8| return (0); - 785| 10|} + 784| 85| return (0); + 785| 101|} ikev2_validate_cert: - 790| 410|{ - 791| 410| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 790| 5.21k|{ + 791| 5.21k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 792| | - 793| 410| if (left < sizeof(*cert)) { + 793| 5.21k| if (left < sizeof(*cert)) { ------------------ - | Branch (793:6): [True: 75, False: 335] + | Branch (793:6): [True: 1.14k, False: 4.07k] ------------------ - 794| 75| log_debug("%s: malformed payload: too short for header " - 795| 75| "(%zu < %zu)", __func__, left, sizeof(*cert)); - 796| 75| return (-1); - 797| 75| } - 798| 335| memcpy(cert, msgbuf + offset, sizeof(*cert)); - 799| 335| if (cert->cert_type == IKEV2_CERT_NONE) { + 794| 1.14k| log_debug("%s: malformed payload: too short for header " + 795| 1.14k| "(%zu < %zu)", __func__, left, sizeof(*cert)); + 796| 1.14k| return (-1); + 797| 1.14k| } + 798| 4.07k| memcpy(cert, msgbuf + offset, sizeof(*cert)); + 799| 4.07k| if (cert->cert_type == IKEV2_CERT_NONE) { ------------------ - | | 418| 335|#define IKEV2_CERT_NONE 0 /* None */ + | | 418| 4.07k|#define IKEV2_CERT_NONE 0 /* None */ ------------------ - | Branch (799:6): [True: 24, False: 311] + | Branch (799:6): [True: 912, False: 3.15k] ------------------ - 800| 24| log_debug("%s: malformed payload: invalid cert type", __func__); - 801| 24| return (-1); - 802| 24| } + 800| 912| log_debug("%s: malformed payload: invalid cert type", __func__); + 801| 912| return (-1); + 802| 912| } 803| | - 804| 311| return (0); - 805| 335|} + 804| 3.15k| return (0); + 805| 4.07k|} ikev2_pld_cert: - 810| 410|{ - 811| 410| struct ikev2_cert cert; - 812| 410| uint8_t *buf; - 813| 410| size_t len; - 814| 410| struct iked_id *certid; - 815| 410| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 816| 410| const struct iked_sa *sa = msg->msg_sa; - 817| 410| int i; + 810| 5.21k|{ + 811| 5.21k| struct ikev2_cert cert; + 812| 5.21k| uint8_t *buf; + 813| 5.21k| size_t len; + 814| 5.21k| struct iked_id *certid; + 815| 5.21k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 816| 5.21k| const struct iked_sa *sa = msg->msg_sa; + 817| 5.21k| int i; 818| | - 819| 410| if (ikev2_validate_cert(msg, offset, left, &cert)) + 819| 5.21k| if (ikev2_validate_cert(msg, offset, left, &cert)) ------------------ - | Branch (819:6): [True: 99, False: 311] + | Branch (819:6): [True: 2.05k, False: 3.15k] ------------------ - 820| 99| return (-1); - 821| 311| offset += sizeof(cert); + 820| 2.05k| return (-1); + 821| 3.15k| offset += sizeof(cert); 822| | - 823| 311| buf = msgbuf + offset; - 824| 311| len = left - sizeof(cert); + 823| 3.15k| buf = msgbuf + offset; + 824| 3.15k| len = left - sizeof(cert); 825| | - 826| 311| log_debug("%s: type %s length %zu", - 827| 311| __func__, print_map(cert.cert_type, ikev2_cert_map), len); + 826| 3.15k| log_debug("%s: type %s length %zu", + 827| 3.15k| __func__, print_map(cert.cert_type, ikev2_cert_map), len); 828| | - 829| 311| print_hex(buf, 0, len); + 829| 3.15k| print_hex(buf, 0, len); 830| | - 831| 311| if (!ikev2_msg_frompeer(msg)) + 831| 3.15k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (831:6): [True: 160, False: 151] + | Branch (831:6): [True: 1.37k, False: 1.78k] ------------------ - 832| 160| return (0); + 832| 1.37k| return (0); 833| | 834| | /* do not accept internal encoding in the wire */ - 835| 151| if (cert.cert_type == IKEV2_CERT_BUNDLE) { + 835| 1.78k| if (cert.cert_type == IKEV2_CERT_BUNDLE) { ------------------ - | | 438| 151|#define IKEV2_CERT_BUNDLE 254 /* Private */ + | | 438| 1.78k|#define IKEV2_CERT_BUNDLE 254 /* Private */ ------------------ - | Branch (835:6): [True: 34, False: 117] + | Branch (835:6): [True: 290, False: 1.49k] ------------------ - 836| 34| log_debug("%s: ignoring IKEV2_CERT_BUNDLE", - 837| 34| SPI_SA(sa, __func__)); + 836| 290| log_debug("%s: ignoring IKEV2_CERT_BUNDLE", + 837| 290| SPI_SA(sa, __func__)); ------------------ - | | 1105| 34|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) + | | 1105| 290|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) | | ------------------ - | | | | 1104| 34|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) + | | | | 1104| 290|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) | | ------------------ ------------------ - 838| 34| return (0); - 839| 34| } + 838| 290| return (0); + 839| 290| } 840| | - 841| 117| certid = &msg->msg_parent->msg_cert; - 842| 117| if (certid->id_type) { + 841| 1.49k| certid = &msg->msg_parent->msg_cert; + 842| 1.49k| if (certid->id_type) { ------------------ - | Branch (842:6): [True: 103, False: 14] + | Branch (842:6): [True: 1.20k, False: 285] ------------------ 843| | /* try to set supplemental certs */ - 844| 344| for (i = 0; i < IKED_SCERT_MAX; i++) { + 844| 3.63k| for (i = 0; i < IKED_SCERT_MAX; i++) { ------------------ - | | 477| 344|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ + | | 477| 3.63k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ ------------------ - | Branch (844:15): [True: 274, False: 70] + | Branch (844:15): [True: 2.97k, False: 663] ------------------ - 845| 274| certid = &msg->msg_parent->msg_scert[i]; - 846| 274| if (!certid->id_type) + 845| 2.97k| certid = &msg->msg_parent->msg_scert[i]; + 846| 2.97k| if (!certid->id_type) ------------------ - | Branch (846:8): [True: 33, False: 241] + | Branch (846:8): [True: 542, False: 2.43k] ------------------ - 847| 33| break; - 848| 274| } - 849| 103| if (certid->id_type) { + 847| 542| break; + 848| 2.97k| } + 849| 1.20k| if (certid->id_type) { ------------------ - | Branch (849:7): [True: 70, False: 33] + | Branch (849:7): [True: 663, False: 542] ------------------ - 850| 70| log_debug("%s: too many cert payloads, ignoring", - 851| 70| SPI_SA(sa, __func__)); + 850| 663| log_debug("%s: too many cert payloads, ignoring", + 851| 663| SPI_SA(sa, __func__)); ------------------ - | | 1105| 70|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) + | | 1105| 663|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) | | ------------------ - | | | | 1104| 70|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) + | | | | 1104| 663|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) | | ------------------ ------------------ - 852| 70| return (0); - 853| 70| } - 854| 103| } + 852| 663| return (0); + 853| 663| } + 854| 1.20k| } 855| | - 856| 47| if ((certid->id_buf = ibuf_new(buf, len)) == NULL) { + 856| 827| if ((certid->id_buf = ibuf_new(buf, len)) == NULL) { ------------------ - | Branch (856:6): [True: 0, False: 47] + | Branch (856:6): [True: 0, False: 827] ------------------ 857| 0| log_debug("%s: failed to save cert", __func__); 858| 0| return (-1); 859| 0| } - 860| 47| certid->id_type = cert.cert_type; - 861| 47| certid->id_offset = 0; + 860| 827| certid->id_type = cert.cert_type; + 861| 827| certid->id_offset = 0; 862| | - 863| 47| return (0); - 864| 47|} + 863| 827| return (0); + 864| 827|} ikev2_validate_certreq: - 869| 1.77k|{ - 870| 1.77k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 869| 10.2k|{ + 870| 10.2k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 871| | - 872| 1.77k| if (left < sizeof(*cert)) { + 872| 10.2k| if (left < sizeof(*cert)) { ------------------ - | Branch (872:6): [True: 406, False: 1.36k] + | Branch (872:6): [True: 2.14k, False: 8.07k] ------------------ - 873| 406| log_debug("%s: malformed payload: too short for header " - 874| 406| "(%zu < %zu)", __func__, left, sizeof(*cert)); - 875| 406| return (-1); - 876| 406| } - 877| 1.36k| memcpy(cert, msgbuf + offset, sizeof(*cert)); + 873| 2.14k| log_debug("%s: malformed payload: too short for header " + 874| 2.14k| "(%zu < %zu)", __func__, left, sizeof(*cert)); + 875| 2.14k| return (-1); + 876| 2.14k| } + 877| 8.07k| memcpy(cert, msgbuf + offset, sizeof(*cert)); 878| | - 879| 1.36k| return (0); - 880| 1.77k|} + 879| 8.07k| return (0); + 880| 10.2k|} ikev2_pld_certreq: - 885| 1.77k|{ - 886| 1.77k| struct ikev2_cert cert; - 887| 1.77k| struct iked_certreq *cr; - 888| 1.77k| uint8_t *buf; - 889| 1.77k| ssize_t len; - 890| 1.77k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 885| 10.2k|{ + 886| 10.2k| struct ikev2_cert cert; + 887| 10.2k| struct iked_certreq *cr; + 888| 10.2k| uint8_t *buf; + 889| 10.2k| ssize_t len; + 890| 10.2k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 891| | - 892| 1.77k| if (ikev2_validate_certreq(msg, offset, left, &cert)) + 892| 10.2k| if (ikev2_validate_certreq(msg, offset, left, &cert)) ------------------ - | Branch (892:6): [True: 406, False: 1.36k] + | Branch (892:6): [True: 2.14k, False: 8.07k] ------------------ - 893| 406| return (-1); - 894| 1.36k| offset += sizeof(cert); + 893| 2.14k| return (-1); + 894| 8.07k| offset += sizeof(cert); 895| | - 896| 1.36k| buf = msgbuf + offset; - 897| 1.36k| len = left - sizeof(cert); + 896| 8.07k| buf = msgbuf + offset; + 897| 8.07k| len = left - sizeof(cert); 898| | - 899| 1.36k| log_debug("%s: type %s length %zd", - 900| 1.36k| __func__, print_map(cert.cert_type, ikev2_cert_map), len); + 899| 8.07k| log_debug("%s: type %s length %zd", + 900| 8.07k| __func__, print_map(cert.cert_type, ikev2_cert_map), len); 901| | - 902| 1.36k| print_hex(buf, 0, len); + 902| 8.07k| print_hex(buf, 0, len); 903| | - 904| 1.36k| if (!ikev2_msg_frompeer(msg)) + 904| 8.07k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (904:6): [True: 1.26k, False: 108] + | Branch (904:6): [True: 7.26k, False: 812] ------------------ - 905| 1.26k| return (0); + 905| 7.26k| return (0); 906| | - 907| 108| if (cert.cert_type == IKEV2_CERT_X509_CERT) { + 907| 812| if (cert.cert_type == IKEV2_CERT_X509_CERT) { ------------------ - | | 422| 108|#define IKEV2_CERT_X509_CERT 4 /* RFC7296 */ + | | 422| 812|#define IKEV2_CERT_X509_CERT 4 /* RFC7296 */ ------------------ - | Branch (907:6): [True: 33, False: 75] + | Branch (907:6): [True: 319, False: 493] ------------------ - 908| 33| if (len == 0) { + 908| 319| if (len == 0) { ------------------ - | Branch (908:7): [True: 22, False: 11] + | Branch (908:7): [True: 277, False: 42] ------------------ - 909| 22| log_info("%s: invalid length 0", __func__); - 910| 22| return (0); - 911| 22| } - 912| 11| if ((len % SHA_DIGEST_LENGTH) != 0) { + 909| 277| log_info("%s: invalid length 0", __func__); + 910| 277| return (0); + 911| 277| } + 912| 42| if ((len % SHA_DIGEST_LENGTH) != 0) { ------------------ - | Branch (912:7): [True: 1, False: 10] + | Branch (912:7): [True: 9, False: 33] ------------------ - 913| 1| log_info("%s: invalid certificate request", - 914| 1| __func__); - 915| 1| return (-1); - 916| 1| } - 917| 11| } + 913| 9| log_info("%s: invalid certificate request", + 914| 9| __func__); + 915| 9| return (-1); + 916| 9| } + 917| 42| } 918| | - 919| 85| if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) { + 919| 526| if ((cr = calloc(1, sizeof(struct iked_certreq))) == NULL) { ------------------ - | Branch (919:6): [True: 0, False: 85] + | Branch (919:6): [True: 0, False: 526] ------------------ 920| 0| log_info("%s: failed to allocate certreq.", __func__); 921| 0| return (-1); 922| 0| } - 923| 85| if ((cr->cr_data = ibuf_new(buf, len)) == NULL) { + 923| 526| if ((cr->cr_data = ibuf_new(buf, len)) == NULL) { ------------------ - | Branch (923:6): [True: 0, False: 85] + | Branch (923:6): [True: 0, False: 526] ------------------ 924| 0| log_info("%s: failed to allocate buffer.", __func__); 925| 0| free(cr); 926| 0| return (-1); 927| 0| } - 928| 85| cr->cr_type = cert.cert_type; - 929| 85| SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry); - ------------------ - | | 296| 85|#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - | | 297| 85| (elm)->field.sqe_next = NULL; \ - | | 298| 85| *(head)->sqh_last = (elm); \ - | | 299| 85| (head)->sqh_last = &(elm)->field.sqe_next; \ - | | 300| 85|} while (0) + 928| 526| cr->cr_type = cert.cert_type; + 929| 526| SIMPLEQ_INSERT_TAIL(&msg->msg_parent->msg_certreqs, cr, cr_entry); + ------------------ + | | 296| 526|#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + | | 297| 526| (elm)->field.sqe_next = NULL; \ + | | 298| 526| *(head)->sqh_last = (elm); \ + | | 299| 526| (head)->sqh_last = &(elm)->field.sqe_next; \ + | | 300| 526|} while (0) | | ------------------ | | | Branch (300:10): [Folded - Ignored] | | ------------------ ------------------ 930| | - 931| 85| return (0); - 932| 85|} + 931| 526| return (0); + 932| 526|} ikev2_validate_auth: - 937| 773|{ - 938| 773| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 937| 7.98k|{ + 938| 7.98k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 939| | - 940| 773| if (left < sizeof(*auth)) { + 940| 7.98k| if (left < sizeof(*auth)) { ------------------ - | Branch (940:6): [True: 130, False: 643] + | Branch (940:6): [True: 1.82k, False: 6.16k] ------------------ - 941| 130| log_debug("%s: malformed payload: too short for header " - 942| 130| "(%zu < %zu)", __func__, left, sizeof(*auth)); - 943| 130| return (-1); - 944| 130| } - 945| 643| memcpy(auth, msgbuf + offset, sizeof(*auth)); + 941| 1.82k| log_debug("%s: malformed payload: too short for header " + 942| 1.82k| "(%zu < %zu)", __func__, left, sizeof(*auth)); + 943| 1.82k| return (-1); + 944| 1.82k| } + 945| 6.16k| memcpy(auth, msgbuf + offset, sizeof(*auth)); 946| | - 947| 643| if (auth->auth_method == 0) { + 947| 6.16k| if (auth->auth_method == 0) { ------------------ - | Branch (947:6): [True: 325, False: 318] + | Branch (947:6): [True: 3.34k, False: 2.82k] ------------------ - 948| 325| log_info("%s: malformed payload: invalid auth method", - 949| 325| __func__); - 950| 325| return (-1); - 951| 325| } + 948| 3.34k| log_info("%s: malformed payload: invalid auth method", + 949| 3.34k| __func__); + 950| 3.34k| return (-1); + 951| 3.34k| } 952| | - 953| 318| return (0); - 954| 643|} + 953| 2.82k| return (0); + 954| 6.16k|} ikev2_pld_auth: - 959| 773|{ - 960| 773| struct ikev2_auth auth; - 961| 773| struct iked_id *idp; - 962| 773| uint8_t *buf; - 963| 773| size_t len; - 964| 773| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 959| 7.98k|{ + 960| 7.98k| struct ikev2_auth auth; + 961| 7.98k| struct iked_id *idp; + 962| 7.98k| uint8_t *buf; + 963| 7.98k| size_t len; + 964| 7.98k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 965| | - 966| 773| if (ikev2_validate_auth(msg, offset, left, &auth)) + 966| 7.98k| if (ikev2_validate_auth(msg, offset, left, &auth)) ------------------ - | Branch (966:6): [True: 455, False: 318] + | Branch (966:6): [True: 5.16k, False: 2.82k] ------------------ - 967| 455| return (-1); - 968| 318| offset += sizeof(auth); + 967| 5.16k| return (-1); + 968| 2.82k| offset += sizeof(auth); 969| | - 970| 318| buf = msgbuf + offset; - 971| 318| len = left - sizeof(auth); + 970| 2.82k| buf = msgbuf + offset; + 971| 2.82k| len = left - sizeof(auth); 972| | - 973| 318| log_debug("%s: method %s length %zu", - 974| 318| __func__, print_map(auth.auth_method, ikev2_auth_map), len); + 973| 2.82k| log_debug("%s: method %s length %zu", + 974| 2.82k| __func__, print_map(auth.auth_method, ikev2_auth_map), len); 975| | - 976| 318| print_hex(buf, 0, len); + 976| 2.82k| print_hex(buf, 0, len); 977| | - 978| 318| if (!ikev2_msg_frompeer(msg)) + 978| 2.82k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (978:6): [True: 315, False: 3] + | Branch (978:6): [True: 2.77k, False: 42] ------------------ - 979| 315| return (0); + 979| 2.77k| return (0); 980| | - 981| 3| idp = &msg->msg_parent->msg_auth; - 982| 3| if (idp->id_type) { + 981| 42| idp = &msg->msg_parent->msg_auth; + 982| 42| if (idp->id_type) { ------------------ - | Branch (982:6): [True: 1, False: 2] + | Branch (982:6): [True: 1, False: 41] ------------------ 983| 1| log_debug("%s: duplicate auth payload", __func__); 984| 1| return (-1); 985| 1| } 986| | - 987| 2| ibuf_free(idp->id_buf); - 988| 2| idp->id_type = auth.auth_method; - 989| 2| idp->id_offset = 0; - 990| 2| if ((idp->id_buf = ibuf_new(buf, len)) == NULL) + 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) ------------------ - | Branch (990:6): [True: 0, False: 2] + | Branch (990:6): [True: 0, False: 41] ------------------ 991| 0| return (-1); 992| | - 993| 2| return (0); - 994| 2|} + 993| 41| return (0); + 994| 41|} ikev2_pld_nonce: - 999| 57|{ - 1000| 57| size_t len; - 1001| 57| uint8_t *buf; - 1002| 57| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 999| 229|{ + 1000| 229| size_t len; + 1001| 229| uint8_t *buf; + 1002| 229| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1003| | - 1004| 57| buf = msgbuf + offset; - 1005| 57| len = left; + 1004| 229| buf = msgbuf + offset; + 1005| 229| len = left; 1006| | - 1007| 57| if (len == 0) { + 1007| 229| if (len == 0) { ------------------ - | Branch (1007:6): [True: 18, False: 39] + | Branch (1007:6): [True: 82, False: 147] ------------------ - 1008| 18| log_debug("%s: malformed payload: no NONCE given", __func__); - 1009| 18| return (-1); - 1010| 18| } + 1008| 82| log_debug("%s: malformed payload: no NONCE given", __func__); + 1009| 82| return (-1); + 1010| 82| } 1011| | - 1012| 39| print_hex(buf, 0, len); + 1012| 147| print_hex(buf, 0, len); 1013| | - 1014| 39| if (ikev2_msg_frompeer(msg)) { + 1014| 147| if (ikev2_msg_frompeer(msg)) { ------------------ - | Branch (1014:6): [True: 2, False: 37] + | Branch (1014:6): [True: 58, False: 89] ------------------ - 1015| 2| if (msg->msg_parent->msg_nonce != NULL) { + 1015| 58| if (msg->msg_parent->msg_nonce != NULL) { ------------------ - | Branch (1015:7): [True: 1, False: 1] + | Branch (1015:7): [True: 19, False: 39] ------------------ - 1016| 1| log_info("%s: duplicate NONCE payload", __func__); - 1017| 1| return (-1); - 1018| 1| } - 1019| 1| if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) { + 1016| 19| log_info("%s: duplicate NONCE payload", __func__); + 1017| 19| return (-1); + 1018| 19| } + 1019| 39| if ((msg->msg_nonce = ibuf_new(buf, len)) == NULL) { ------------------ - | Branch (1019:7): [True: 0, False: 1] + | Branch (1019:7): [True: 0, False: 39] ------------------ 1020| 0| log_debug("%s: failed to get peer nonce", __func__); 1021| 0| return (-1); 1022| 0| } - 1023| 1| msg->msg_parent->msg_nonce = msg->msg_nonce; - 1024| 1| } + 1023| 39| msg->msg_parent->msg_nonce = msg->msg_nonce; + 1024| 39| } 1025| | - 1026| 38| return (0); - 1027| 39|} + 1026| 128| return (0); + 1027| 147|} ikev2_validate_notify: - 1032| 1.12k|{ - 1033| 1.12k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1032| 24.5k|{ + 1033| 24.5k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1034| | - 1035| 1.12k| if (left < sizeof(*n)) { + 1035| 24.5k| if (left < sizeof(*n)) { ------------------ - | Branch (1035:6): [True: 549, False: 580] + | Branch (1035:6): [True: 3.14k, False: 21.4k] ------------------ - 1036| 549| log_debug("%s: malformed payload: too short for header " - 1037| 549| "(%zu < %zu)", __func__, left, sizeof(*n)); - 1038| 549| return (-1); - 1039| 549| } - 1040| 580| memcpy(n, msgbuf + offset, sizeof(*n)); + 1036| 3.14k| log_debug("%s: malformed payload: too short for header " + 1037| 3.14k| "(%zu < %zu)", __func__, left, sizeof(*n)); + 1038| 3.14k| return (-1); + 1039| 3.14k| } + 1040| 21.4k| memcpy(n, msgbuf + offset, sizeof(*n)); 1041| | - 1042| 580| return (0); - 1043| 1.12k|} + 1042| 21.4k| return (0); + 1043| 24.5k|} ikev2_pld_notify: - 1048| 1.12k|{ - 1049| 1.12k| struct ikev2_notify n; - 1050| 1.12k| const struct iked_sa *sa = msg->msg_sa; - 1051| 1.12k| uint8_t *buf, md[SHA_DIGEST_LENGTH]; - 1052| 1.12k| uint32_t spi32; - 1053| 1.12k| uint64_t spi64; - 1054| 1.12k| struct iked_spi *rekey; - 1055| 1.12k| uint16_t type; - 1056| 1.12k| uint16_t signature_hash; + 1048| 24.5k|{ + 1049| 24.5k| struct ikev2_notify n; + 1050| 24.5k| const struct iked_sa *sa = msg->msg_sa; + 1051| 24.5k| uint8_t *buf, md[SHA_DIGEST_LENGTH]; + 1052| 24.5k| uint32_t spi32; + 1053| 24.5k| uint64_t spi64; + 1054| 24.5k| struct iked_spi *rekey; + 1055| 24.5k| uint16_t type; + 1056| 24.5k| uint16_t signature_hash; 1057| | - 1058| 1.12k| if (ikev2_validate_notify(msg, offset, left, &n)) + 1058| 24.5k| if (ikev2_validate_notify(msg, offset, left, &n)) ------------------ - | Branch (1058:6): [True: 549, False: 580] + | Branch (1058:6): [True: 3.14k, False: 21.4k] ------------------ - 1059| 549| return (-1); - 1060| 580| type = betoh16(n.n_type); + 1059| 3.14k| return (-1); + 1060| 21.4k| type = betoh16(n.n_type); 1061| | - 1062| 580| log_debug("%s: protoid %s spisize %d type %s", - 1063| 580| __func__, - 1064| 580| print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize, - 1065| 580| print_map(type, ikev2_n_map)); + 1062| 21.4k| log_debug("%s: protoid %s spisize %d type %s", + 1063| 21.4k| __func__, + 1064| 21.4k| print_map(n.n_protoid, ikev2_saproto_map), n.n_spisize, + 1065| 21.4k| print_map(type, ikev2_n_map)); 1066| | - 1067| 580| left -= sizeof(n); - 1068| 580| if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL) + 1067| 21.4k| left -= sizeof(n); + 1068| 21.4k| if ((buf = ibuf_seek(msg->msg_data, offset + sizeof(n), left)) == NULL) ------------------ - | Branch (1068:6): [True: 0, False: 580] + | Branch (1068:6): [True: 0, False: 21.4k] ------------------ 1069| 0| return (-1); 1070| | - 1071| 580| print_hex(buf, 0, left); + 1071| 21.4k| print_hex(buf, 0, left); 1072| | - 1073| 580| if (!ikev2_msg_frompeer(msg)) + 1073| 21.4k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (1073:6): [True: 261, False: 319] + | Branch (1073:6): [True: 1.36k, False: 20.0k] ------------------ - 1074| 261| return (0); + 1074| 1.36k| return (0); 1075| | - 1076| 319| switch (type) { + 1076| 20.0k| switch (type) { ------------------ - | Branch (1076:10): [True: 67, False: 252] + | Branch (1076:10): [True: 1.77k, False: 18.2k] ------------------ - 1077| 13| case IKEV2_N_NAT_DETECTION_SOURCE_IP: + 1077| 2.47k| case IKEV2_N_NAT_DETECTION_SOURCE_IP: ------------------ - | | 330| 13|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ + | | 330| 2.47k|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ ------------------ - | Branch (1077:2): [True: 13, False: 306] + | Branch (1077:2): [True: 2.47k, False: 17.5k] ------------------ - 1078| 50| case IKEV2_N_NAT_DETECTION_DESTINATION_IP: + 1078| 15.9k| case IKEV2_N_NAT_DETECTION_DESTINATION_IP: ------------------ - | | 331| 50|#define IKEV2_N_NAT_DETECTION_DESTINATION_IP 16389 /* RFC7296 */ + | | 331| 15.9k|#define IKEV2_N_NAT_DETECTION_DESTINATION_IP 16389 /* RFC7296 */ ------------------ - | Branch (1078:2): [True: 37, False: 282] + | Branch (1078:2): [True: 13.5k, False: 6.52k] ------------------ - 1079| 50| if (left != sizeof(md)) { + 1079| 15.9k| if (left != sizeof(md)) { ------------------ - | Branch (1079:7): [True: 2, False: 48] + | Branch (1079:7): [True: 16, False: 15.9k] ------------------ - 1080| 2| log_debug("%s: malformed payload: hash size mismatch" - 1081| 2| " (%zu != %zu)", __func__, left, sizeof(md)); - 1082| 2| return (-1); - 1083| 2| } - 1084| 48| if (ikev2_nat_detection(env, msg, md, sizeof(md), type, + 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| 15.9k| if (ikev2_nat_detection(env, msg, md, sizeof(md), type, ------------------ - | Branch (1084:7): [True: 0, False: 48] + | Branch (1084:7): [True: 0, False: 15.9k] ------------------ - 1085| 48| ikev2_msg_frompeer(msg)) == -1) + 1085| 15.9k| ikev2_msg_frompeer(msg)) == -1) 1086| 0| return (-1); - 1087| 48| if (memcmp(buf, md, left) != 0) { + 1087| 15.9k| if (memcmp(buf, md, left) != 0) { ------------------ - | Branch (1087:7): [True: 48, False: 0] + | Branch (1087:7): [True: 15.9k, False: 0] ------------------ - 1088| 48| log_debug("%s: %s detected NAT", __func__, - 1089| 48| print_map(type, ikev2_n_map)); - 1090| 48| if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP) + 1088| 15.9k| log_debug("%s: %s detected NAT", __func__, + 1089| 15.9k| print_map(type, ikev2_n_map)); + 1090| 15.9k| if (type == IKEV2_N_NAT_DETECTION_SOURCE_IP) ------------------ - | | 330| 48|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ + | | 330| 15.9k|#define IKEV2_N_NAT_DETECTION_SOURCE_IP 16388 /* RFC7296 */ ------------------ - | Branch (1090:8): [True: 12, False: 36] + | Branch (1090:8): [True: 2.47k, False: 13.5k] ------------------ - 1091| 12| msg->msg_parent->msg_nat_detected - 1092| 12| |= IKED_MSG_NAT_SRC_IP; + 1091| 2.47k| msg->msg_parent->msg_nat_detected + 1092| 2.47k| |= IKED_MSG_NAT_SRC_IP; ------------------ - | | 687| 12|#define IKED_MSG_NAT_SRC_IP 0x01 + | | 687| 2.47k|#define IKED_MSG_NAT_SRC_IP 0x01 ------------------ - 1093| 36| else - 1094| 36| msg->msg_parent->msg_nat_detected - 1095| 36| |= IKED_MSG_NAT_DST_IP; + 1093| 13.5k| else + 1094| 13.5k| msg->msg_parent->msg_nat_detected + 1095| 13.5k| |= IKED_MSG_NAT_DST_IP; ------------------ - | | 688| 36|#define IKED_MSG_NAT_DST_IP 0x02 + | | 688| 13.5k|#define IKED_MSG_NAT_DST_IP 0x02 ------------------ - 1096| 48| } - 1097| 48| print_hex(md, 0, sizeof(md)); + 1096| 15.9k| } + 1097| 15.9k| print_hex(md, 0, sizeof(md)); 1098| | /* remember for MOBIKE */ - 1099| 48| msg->msg_parent->msg_natt_rcvd = 1; - 1100| 48| break; - 1101| 1| case IKEV2_N_AUTHENTICATION_FAILED: + 1099| 15.9k| msg->msg_parent->msg_natt_rcvd = 1; + 1100| 15.9k| break; + 1101| 6| case IKEV2_N_AUTHENTICATION_FAILED: ------------------ - | | 314| 1|#define IKEV2_N_AUTHENTICATION_FAILED 24 /* RFC7296 */ + | | 314| 6|#define IKEV2_N_AUTHENTICATION_FAILED 24 /* RFC7296 */ ------------------ - | Branch (1101:2): [True: 1, False: 318] + | Branch (1101:2): [True: 6, False: 20.0k] ------------------ - 1102| 1| if (!msg->msg_e) { + 1102| 6| if (!msg->msg_e) { ------------------ - | Branch (1102:7): [True: 0, False: 1] + | Branch (1102:7): [True: 0, False: 6] ------------------ 1103| 0| log_debug("%s: AUTHENTICATION_FAILED not encrypted", 1104| 0| __func__); @@ -1682,22 +1682,22 @@ ikev2_pld_notify: 1109| | * AUTHENTICATION_FAILED from authenticated peers. 1110| | * If we are the initiator, the peer cannot be authenticated. 1111| | */ - 1112| 1| if (!sa->sa_hdr.sh_initiator) { + 1112| 6| if (!sa->sa_hdr.sh_initiator) { ------------------ - | Branch (1112:7): [True: 1, False: 0] + | Branch (1112:7): [True: 6, False: 0] ------------------ - 1113| 1| if (!sa_stateok(sa, IKEV2_STATE_VALID)) { + 1113| 6| if (!sa_stateok(sa, IKEV2_STATE_VALID)) { ------------------ - | | 41| 1|#define IKEV2_STATE_VALID 7 /* authenticated AND validated certs */ + | | 41| 6|#define IKEV2_STATE_VALID 7 /* authenticated AND validated certs */ ------------------ - | Branch (1113:8): [True: 1, False: 0] + | Branch (1113:8): [True: 6, False: 0] ------------------ - 1114| 1| log_debug("%s: ignoring AUTHENTICATION_FAILED" - 1115| 1| " from unauthenticated initiator", - 1116| 1| __func__); - 1117| 1| return (-1); - 1118| 1| } - 1119| 1| } else { + 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)) { ------------------ | | 41| 0|#define IKEV2_STATE_VALID 7 /* authenticated AND validated certs */ @@ -1716,19 +1716,19 @@ ikev2_pld_notify: | | 695| 0|#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED 0x0020 ------------------ 1129| 0| break; - 1130| 11| case IKEV2_N_INVALID_KE_PAYLOAD: + 1130| 135| case IKEV2_N_INVALID_KE_PAYLOAD: ------------------ - | | 313| 11|#define IKEV2_N_INVALID_KE_PAYLOAD 17 /* RFC7296 */ + | | 313| 135|#define IKEV2_N_INVALID_KE_PAYLOAD 17 /* RFC7296 */ ------------------ - | Branch (1130:2): [True: 11, False: 308] + | Branch (1130:2): [True: 135, False: 19.9k] ------------------ - 1131| 11| if (sa_stateok(sa, IKEV2_STATE_VALID) && + 1131| 135| if (sa_stateok(sa, IKEV2_STATE_VALID) && ------------------ - | | 41| 11|#define IKEV2_STATE_VALID 7 /* authenticated AND validated certs */ + | | 41| 135|#define IKEV2_STATE_VALID 7 /* authenticated AND validated certs */ ------------------ - | Branch (1131:7): [True: 0, False: 11] + | Branch (1131:7): [True: 0, False: 135] ------------------ - 1132| 11| !msg->msg_e) { + 1132| 135| !msg->msg_e) { ------------------ | Branch (1132:7): [True: 0, False: 0] ------------------ @@ -1736,243 +1736,243 @@ ikev2_pld_notify: 1134| 0| __func__); 1135| 0| return (-1); 1136| 0| } - 1137| 11| if (left != sizeof(msg->msg_parent->msg_group)) { + 1137| 135| if (left != sizeof(msg->msg_parent->msg_group)) { ------------------ - | Branch (1137:7): [True: 1, False: 10] + | Branch (1137:7): [True: 4, False: 131] ------------------ - 1138| 1| log_debug("%s: malformed payload: group size mismatch" - 1139| 1| " (%zu != %zu)", __func__, left, - 1140| 1| sizeof(msg->msg_parent->msg_group)); - 1141| 1| return (-1); - 1142| 1| } - 1143| 10| memcpy(&msg->msg_parent->msg_group, buf, left); - 1144| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_INVALID_KE; + 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; ------------------ - | | 696| 10|#define IKED_MSG_FLAGS_INVALID_KE 0x0040 + | | 696| 131|#define IKED_MSG_FLAGS_INVALID_KE 0x0040 ------------------ - 1145| 10| break; - 1146| 10| case IKEV2_N_NO_ADDITIONAL_SAS: + 1145| 131| break; + 1146| 233| case IKEV2_N_NO_ADDITIONAL_SAS: ------------------ - | | 316| 10|#define IKEV2_N_NO_ADDITIONAL_SAS 35 /* RFC7296 */ + | | 316| 233|#define IKEV2_N_NO_ADDITIONAL_SAS 35 /* RFC7296 */ ------------------ - | Branch (1146:2): [True: 10, False: 309] + | Branch (1146:2): [True: 233, False: 19.8k] ------------------ - 1147| 10| if (!msg->msg_e) { + 1147| 233| if (!msg->msg_e) { ------------------ - | Branch (1147:7): [True: 0, False: 10] + | Branch (1147:7): [True: 0, False: 233] ------------------ 1148| 0| log_debug("%s: NO_ADDITIONAL_SAS not encrypted", 1149| 0| __func__); 1150| 0| return (-1); 1151| 0| } - 1152| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS; + 1152| 233| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_ADDITIONAL_SAS; ------------------ - | | 694| 10|#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS 0x0010 + | | 694| 233|#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS 0x0010 ------------------ - 1153| 10| break; - 1154| 17| case IKEV2_N_REKEY_SA: + 1153| 233| break; + 1154| 64| case IKEV2_N_REKEY_SA: ------------------ - | | 335| 17|#define IKEV2_N_REKEY_SA 16393 /* RFC7296 */ + | | 335| 64|#define IKEV2_N_REKEY_SA 16393 /* RFC7296 */ ------------------ - | Branch (1154:2): [True: 17, False: 302] + | Branch (1154:2): [True: 64, False: 19.9k] ------------------ - 1155| 17| if (!msg->msg_e) { + 1155| 64| if (!msg->msg_e) { ------------------ - | Branch (1155:7): [True: 0, False: 17] + | Branch (1155:7): [True: 0, False: 64] ------------------ 1156| 0| log_debug("%s: N_REKEY_SA not encrypted", __func__); 1157| 0| return (-1); 1158| 0| } - 1159| 17| if (left != n.n_spisize) { + 1159| 64| if (left != n.n_spisize) { ------------------ - | Branch (1159:7): [True: 1, False: 16] + | Branch (1159:7): [True: 5, False: 59] ------------------ - 1160| 1| log_debug("%s: malformed notification", __func__); - 1161| 1| return (-1); - 1162| 1| } - 1163| 16| rekey = &msg->msg_parent->msg_rekey; - 1164| 16| if (rekey->spi != 0) { + 1160| 5| log_debug("%s: malformed notification", __func__); + 1161| 5| return (-1); + 1162| 5| } + 1163| 59| rekey = &msg->msg_parent->msg_rekey; + 1164| 59| if (rekey->spi != 0) { ------------------ - | Branch (1164:7): [True: 1, False: 15] + | Branch (1164:7): [True: 5, False: 54] ------------------ - 1165| 1| log_debug("%s: rekeying of multiple SAs not supported", - 1166| 1| __func__); - 1167| 1| return (-1); - 1168| 1| } - 1169| 15| switch (n.n_spisize) { - 1170| 13| case 4: + 1165| 5| log_debug("%s: rekeying of multiple SAs not supported", + 1166| 5| __func__); + 1167| 5| return (-1); + 1168| 5| } + 1169| 54| switch (n.n_spisize) { + 1170| 48| case 4: ------------------ - | Branch (1170:3): [True: 13, False: 2] + | Branch (1170:3): [True: 48, False: 6] ------------------ - 1171| 13| memcpy(&spi32, buf, left); - 1172| 13| rekey->spi = betoh32(spi32); - 1173| 13| break; - 1174| 1| case 8: + 1171| 48| memcpy(&spi32, buf, left); + 1172| 48| rekey->spi = betoh32(spi32); + 1173| 48| break; + 1174| 3| case 8: ------------------ - | Branch (1174:3): [True: 1, False: 14] + | Branch (1174:3): [True: 3, False: 51] ------------------ - 1175| 1| memcpy(&spi64, buf, left); - 1176| 1| rekey->spi = betoh64(spi64); - 1177| 1| break; - 1178| 1| default: + 1175| 3| memcpy(&spi64, buf, left); + 1176| 3| rekey->spi = betoh64(spi64); + 1177| 3| break; + 1178| 3| default: ------------------ - | Branch (1178:3): [True: 1, False: 14] + | Branch (1178:3): [True: 3, False: 51] ------------------ - 1179| 1| log_debug("%s: invalid spi size %d", __func__, - 1180| 1| n.n_spisize); - 1181| 1| return (-1); - 1182| 15| } - 1183| 14| rekey->spi_size = n.n_spisize; - 1184| 14| rekey->spi_protoid = n.n_protoid; + 1179| 3| log_debug("%s: invalid spi size %d", __func__, + 1180| 3| n.n_spisize); + 1181| 3| return (-1); + 1182| 54| } + 1183| 51| rekey->spi_size = n.n_spisize; + 1184| 51| rekey->spi_protoid = n.n_protoid; 1185| | - 1186| 14| log_debug("%s: rekey %s spi %s", __func__, - 1187| 14| print_map(n.n_protoid, ikev2_saproto_map), - 1188| 14| print_spi(rekey->spi, n.n_spisize)); - 1189| 14| break; - 1190| 12| case IKEV2_N_TEMPORARY_FAILURE: + 1186| 51| log_debug("%s: rekey %s spi %s", __func__, + 1187| 51| print_map(n.n_protoid, ikev2_saproto_map), + 1188| 51| print_spi(rekey->spi, n.n_spisize)); + 1189| 51| break; + 1190| 341| case IKEV2_N_TEMPORARY_FAILURE: ------------------ - | | 324| 12|#define IKEV2_N_TEMPORARY_FAILURE 43 /* RFC7296 */ + | | 324| 341|#define IKEV2_N_TEMPORARY_FAILURE 43 /* RFC7296 */ ------------------ - | Branch (1190:2): [True: 12, False: 307] + | Branch (1190:2): [True: 341, False: 19.7k] ------------------ - 1191| 12| if (!msg->msg_e) { + 1191| 341| if (!msg->msg_e) { ------------------ - | Branch (1191:7): [True: 0, False: 12] + | Branch (1191:7): [True: 0, False: 341] ------------------ 1192| 0| log_debug("%s: IKEV2_N_TEMPORARY_FAILURE not encrypted", 1193| 0| __func__); 1194| 0| return (-1); 1195| 0| } - 1196| 12| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE; + 1196| 341| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_TEMPORARY_FAILURE; ------------------ - | | 699| 12|#define IKED_MSG_FLAGS_TEMPORARY_FAILURE 0x0200 + | | 699| 341|#define IKED_MSG_FLAGS_TEMPORARY_FAILURE 0x0200 ------------------ - 1197| 12| break; - 1198| 20| case IKEV2_N_IPCOMP_SUPPORTED: + 1197| 341| break; + 1198| 249| case IKEV2_N_IPCOMP_SUPPORTED: ------------------ - | | 329| 20|#define IKEV2_N_IPCOMP_SUPPORTED 16387 /* RFC7296 */ + | | 329| 249|#define IKEV2_N_IPCOMP_SUPPORTED 16387 /* RFC7296 */ ------------------ - | Branch (1198:2): [True: 20, False: 299] + | Branch (1198:2): [True: 249, False: 19.7k] ------------------ - 1199| 20| if (!msg->msg_e) { + 1199| 249| if (!msg->msg_e) { ------------------ - | Branch (1199:7): [True: 0, False: 20] + | Branch (1199:7): [True: 0, False: 249] ------------------ 1200| 0| log_debug("%s: N_IPCOMP_SUPPORTED not encrypted", 1201| 0| __func__); 1202| 0| return (-1); 1203| 0| } - 1204| 20| if (left < sizeof(msg->msg_parent->msg_cpi) + - ------------------ - | Branch (1204:7): [True: 10, False: 10] - ------------------ - 1205| 20| sizeof(msg->msg_parent->msg_transform)) { - 1206| 10| log_debug("%s: ignoring malformed ipcomp notification", - 1207| 10| __func__); - 1208| 10| return (0); - 1209| 10| } - 1210| 10| memcpy(&msg->msg_parent->msg_cpi, buf, - 1211| 10| sizeof(msg->msg_parent->msg_cpi)); - 1212| 10| memcpy(&msg->msg_parent->msg_transform, - 1213| 10| buf + sizeof(msg->msg_parent->msg_cpi), - 1214| 10| sizeof(msg->msg_parent->msg_transform)); + 1204| 249| if (left < sizeof(msg->msg_parent->msg_cpi) + + ------------------ + | Branch (1204:7): [True: 121, False: 128] + ------------------ + 1205| 249| sizeof(msg->msg_parent->msg_transform)) { + 1206| 121| log_debug("%s: ignoring malformed ipcomp notification", + 1207| 121| __func__); + 1208| 121| return (0); + 1209| 121| } + 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| 10| log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__, - 1217| 10| msg->msg_parent->msg_response ? "res" : "req", + 1216| 128| log_debug("%s: %s cpi 0x%x, transform %s, length %zu", __func__, + 1217| 128| msg->msg_parent->msg_response ? "res" : "req", ------------------ - | Branch (1217:7): [True: 0, False: 10] + | Branch (1217:7): [True: 0, False: 128] ------------------ - 1218| 10| betoh16(msg->msg_parent->msg_cpi), - 1219| 10| print_map(msg->msg_parent->msg_transform, - 1220| 10| ikev2_ipcomp_map), left); + 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| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED; + 1222| 128| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_IPCOMP_SUPPORTED; ------------------ - | | 697| 10|#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED 0x0080 + | | 697| 128|#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED 0x0080 ------------------ - 1223| 10| break; - 1224| 10| case IKEV2_N_CHILD_SA_NOT_FOUND: + 1223| 128| break; + 1224| 73| case IKEV2_N_CHILD_SA_NOT_FOUND: ------------------ - | | 325| 10|#define IKEV2_N_CHILD_SA_NOT_FOUND 44 /* RFC7296 */ + | | 325| 73|#define IKEV2_N_CHILD_SA_NOT_FOUND 44 /* RFC7296 */ ------------------ - | Branch (1224:2): [True: 10, False: 309] + | Branch (1224:2): [True: 73, False: 19.9k] ------------------ - 1225| 10| if (!msg->msg_e) { + 1225| 73| if (!msg->msg_e) { ------------------ - | Branch (1225:7): [True: 0, False: 10] + | Branch (1225:7): [True: 0, False: 73] ------------------ 1226| 0| log_debug("%s: N_CHILD_SA_NOT_FOUND not encrypted", 1227| 0| __func__); 1228| 0| return (-1); 1229| 0| } - 1230| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND; + 1230| 73| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND; ------------------ - | | 693| 10|#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND 0x0008 + | | 693| 73|#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND 0x0008 ------------------ - 1231| 10| break; - 1232| 10| case IKEV2_N_NO_PROPOSAL_CHOSEN: + 1231| 73| break; + 1232| 36| case IKEV2_N_NO_PROPOSAL_CHOSEN: ------------------ - | | 312| 10|#define IKEV2_N_NO_PROPOSAL_CHOSEN 14 /* RFC7296 */ + | | 312| 36|#define IKEV2_N_NO_PROPOSAL_CHOSEN 14 /* RFC7296 */ ------------------ - | Branch (1232:2): [True: 10, False: 309] + | Branch (1232:2): [True: 36, False: 20.0k] ------------------ - 1233| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN; + 1233| 36| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN; ------------------ - | | 700| 10|#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN 0x0400 + | | 700| 36|#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN 0x0400 ------------------ - 1234| 10| break; - 1235| 28| case IKEV2_N_MOBIKE_SUPPORTED: + 1234| 36| break; + 1235| 263| case IKEV2_N_MOBIKE_SUPPORTED: ------------------ - | | 338| 28|#define IKEV2_N_MOBIKE_SUPPORTED 16396 /* RFC4555 */ + | | 338| 263|#define IKEV2_N_MOBIKE_SUPPORTED 16396 /* RFC4555 */ ------------------ - | Branch (1235:2): [True: 28, False: 291] + | Branch (1235:2): [True: 263, False: 19.7k] ------------------ - 1236| 28| if (!msg->msg_e) { + 1236| 263| if (!msg->msg_e) { ------------------ - | Branch (1236:7): [True: 0, False: 28] + | Branch (1236:7): [True: 0, False: 263] ------------------ 1237| 0| log_debug("%s: N_MOBIKE_SUPPORTED not encrypted", 1238| 0| __func__); 1239| 0| return (-1); 1240| 0| } - 1241| 28| if (left != 0) { + 1241| 263| if (left != 0) { ------------------ - | Branch (1241:7): [True: 18, False: 10] + | Branch (1241:7): [True: 130, False: 133] ------------------ - 1242| 18| log_debug("%s: ignoring malformed mobike" - 1243| 18| " notification: %zu", __func__, left); - 1244| 18| return (0); - 1245| 18| } - 1246| 10| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE; + 1242| 130| log_debug("%s: ignoring malformed mobike" + 1243| 130| " notification: %zu", __func__, left); + 1244| 130| return (0); + 1245| 130| } + 1246| 133| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE; ------------------ - | | 691| 10|#define IKED_MSG_FLAGS_MOBIKE 0x0002 + | | 691| 133|#define IKED_MSG_FLAGS_MOBIKE 0x0002 ------------------ - 1247| 10| break; - 1248| 28| case IKEV2_N_USE_TRANSPORT_MODE: + 1247| 133| break; + 1248| 301| case IKEV2_N_USE_TRANSPORT_MODE: ------------------ - | | 333| 28|#define IKEV2_N_USE_TRANSPORT_MODE 16391 /* RFC7296 */ + | | 333| 301|#define IKEV2_N_USE_TRANSPORT_MODE 16391 /* RFC7296 */ ------------------ - | Branch (1248:2): [True: 28, False: 291] + | Branch (1248:2): [True: 301, False: 19.7k] ------------------ - 1249| 28| if (!msg->msg_e) { + 1249| 301| if (!msg->msg_e) { ------------------ - | Branch (1249:7): [True: 0, False: 28] + | Branch (1249:7): [True: 0, False: 301] ------------------ 1250| 0| log_debug("%s: N_USE_TRANSPORT_MODE not encrypted", 1251| 0| __func__); 1252| 0| return (-1); 1253| 0| } - 1254| 28| if (left != 0) { + 1254| 301| if (left != 0) { ------------------ - | Branch (1254:7): [True: 10, False: 18] + | Branch (1254:7): [True: 77, False: 224] ------------------ - 1255| 10| log_debug("%s: ignoring malformed transport mode" - 1256| 10| " notification: %zu", __func__, left); - 1257| 10| return (0); - 1258| 10| } - 1259| 18| if (msg->msg_parent->msg_response) { + 1255| 77| log_debug("%s: ignoring malformed transport mode" + 1256| 77| " notification: %zu", __func__, left); + 1257| 77| return (0); + 1258| 77| } + 1259| 224| if (msg->msg_parent->msg_response) { ------------------ - | Branch (1259:7): [True: 0, False: 18] + | Branch (1259:7): [True: 0, False: 224] ------------------ 1260| 0| if (!(msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT)) { ------------------ @@ -1985,33 +1985,33 @@ ikev2_pld_notify: 1263| 0| return (0); 1264| 0| } 1265| 0| } - 1266| 18| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT; + 1266| 224| msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_USE_TRANSPORT; ------------------ - | | 698| 18|#define IKED_MSG_FLAGS_USE_TRANSPORT 0x0100 + | | 698| 224|#define IKED_MSG_FLAGS_USE_TRANSPORT 0x0100 ------------------ - 1267| 18| break; - 1268| 18| case IKEV2_N_UPDATE_SA_ADDRESSES: + 1267| 224| break; + 1268| 344| case IKEV2_N_UPDATE_SA_ADDRESSES: ------------------ - | | 342| 18|#define IKEV2_N_UPDATE_SA_ADDRESSES 16400 /* RFC4555 */ + | | 342| 344|#define IKEV2_N_UPDATE_SA_ADDRESSES 16400 /* RFC4555 */ ------------------ - | Branch (1268:2): [True: 18, False: 301] + | Branch (1268:2): [True: 344, False: 19.7k] ------------------ - 1269| 18| if (!msg->msg_e) { + 1269| 344| if (!msg->msg_e) { ------------------ - | Branch (1269:7): [True: 0, False: 18] + | Branch (1269:7): [True: 0, False: 344] ------------------ 1270| 0| log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted", 1271| 0| __func__); 1272| 0| return (-1); 1273| 0| } - 1274| 18| if (!sa->sa_mobike) { + 1274| 344| if (!sa->sa_mobike) { ------------------ - | Branch (1274:7): [True: 18, False: 0] + | Branch (1274:7): [True: 344, False: 0] ------------------ - 1275| 18| log_debug("%s: ignoring update sa addresses" - 1276| 18| " notification w/o mobike: %zu", __func__, left); - 1277| 18| return (0); - 1278| 18| } + 1275| 344| log_debug("%s: ignoring update sa addresses" + 1276| 344| " notification w/o mobike: %zu", __func__, left); + 1277| 344| return (0); + 1278| 344| } 1279| 0| if (left != 0) { ------------------ | Branch (1279:7): [True: 0, False: 0] @@ -2022,28 +2022,28 @@ ikev2_pld_notify: 1283| 0| } 1284| 0| msg->msg_parent->msg_update_sa_addresses = 1; 1285| 0| break; - 1286| 34| case IKEV2_N_COOKIE2: + 1286| 201| case IKEV2_N_COOKIE2: ------------------ - | | 343| 34|#define IKEV2_N_COOKIE2 16401 /* RFC4555 */ + | | 343| 201|#define IKEV2_N_COOKIE2 16401 /* RFC4555 */ ------------------ - | Branch (1286:2): [True: 34, False: 285] + | Branch (1286:2): [True: 201, False: 19.8k] ------------------ - 1287| 34| if (!msg->msg_e) { + 1287| 201| if (!msg->msg_e) { ------------------ - | Branch (1287:7): [True: 0, False: 34] + | Branch (1287:7): [True: 0, False: 201] ------------------ 1288| 0| log_debug("%s: N_COOKIE2 not encrypted", 1289| 0| __func__); 1290| 0| return (-1); 1291| 0| } - 1292| 34| if (!sa->sa_mobike) { + 1292| 201| if (!sa->sa_mobike) { ------------------ - | Branch (1292:7): [True: 34, False: 0] + | Branch (1292:7): [True: 201, False: 0] ------------------ - 1293| 34| log_debug("%s: ignoring cookie2 notification" - 1294| 34| " w/o mobike: %zu", __func__, left); - 1295| 34| return (0); - 1296| 34| } + 1293| 201| log_debug("%s: ignoring cookie2 notification" + 1294| 201| " w/o mobike: %zu", __func__, left); + 1295| 201| return (0); + 1296| 201| } 1297| 0| if (left < IKED_COOKIE2_MIN || left > IKED_COOKIE2_MAX) { ------------------ | | 61| 0|#define IKED_COOKIE2_MIN 8 /* min 8 bytes */ @@ -2069,20 +2069,20 @@ ikev2_pld_notify: 1306| 0| } 1307| 0| msg->msg_parent->msg_cookie2 = msg->msg_cookie2; 1308| 0| break; - 1309| 1| case IKEV2_N_COOKIE: + 1309| 2| case IKEV2_N_COOKIE: ------------------ - | | 332| 1|#define IKEV2_N_COOKIE 16390 /* RFC7296 */ + | | 332| 2|#define IKEV2_N_COOKIE 16390 /* RFC7296 */ ------------------ - | Branch (1309:2): [True: 1, False: 318] + | Branch (1309:2): [True: 2, False: 20.0k] ------------------ - 1310| 1| if (msg->msg_e) { + 1310| 2| if (msg->msg_e) { ------------------ - | Branch (1310:7): [True: 1, False: 0] + | Branch (1310:7): [True: 2, False: 0] ------------------ - 1311| 1| log_debug("%s: N_COOKIE encrypted", - 1312| 1| __func__); - 1313| 1| return (-1); - 1314| 1| } + 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) { ------------------ | | 58| 0|#define IKED_COOKIE_MIN 1 /* min 1 bytes */ @@ -2111,20 +2111,20 @@ ikev2_pld_notify: 1327| 0| } 1328| 0| msg->msg_parent->msg_cookie = msg->msg_cookie; 1329| 0| break; - 1330| 1| case IKEV2_N_FRAGMENTATION_SUPPORTED: + 1330| 14| case IKEV2_N_FRAGMENTATION_SUPPORTED: ------------------ - | | 371| 1|#define IKEV2_N_FRAGMENTATION_SUPPORTED 16430 /* RFC7383 */ + | | 371| 14|#define IKEV2_N_FRAGMENTATION_SUPPORTED 16430 /* RFC7383 */ ------------------ - | Branch (1330:2): [True: 1, False: 318] + | Branch (1330:2): [True: 14, False: 20.0k] ------------------ - 1331| 1| if (msg->msg_e) { + 1331| 14| if (msg->msg_e) { ------------------ - | Branch (1331:7): [True: 1, False: 0] + | Branch (1331:7): [True: 14, False: 0] ------------------ - 1332| 1| log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted", - 1333| 1| __func__); - 1334| 1| return (-1); - 1335| 1| } + 1332| 14| log_debug("%s: N_FRAGMENTATION_SUPPORTED encrypted", + 1333| 14| __func__); + 1334| 14| return (-1); + 1335| 14| } 1336| 0| if (left != 0) { ------------------ | Branch (1336:7): [True: 0, False: 0] @@ -2138,20 +2138,20 @@ ikev2_pld_notify: | | 690| 0|#define IKED_MSG_FLAGS_FRAGMENTATION 0x0001 ------------------ 1342| 0| break; - 1343| 1| case IKEV2_N_SIGNATURE_HASH_ALGORITHMS: + 1343| 7| case IKEV2_N_SIGNATURE_HASH_ALGORITHMS: ------------------ - | | 372| 1|#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431 /* RFC7427 */ + | | 372| 7|#define IKEV2_N_SIGNATURE_HASH_ALGORITHMS 16431 /* RFC7427 */ ------------------ - | Branch (1343:2): [True: 1, False: 318] + | Branch (1343:2): [True: 7, False: 20.0k] ------------------ - 1344| 1| if (msg->msg_e) { + 1344| 7| if (msg->msg_e) { ------------------ - | Branch (1344:7): [True: 1, False: 0] + | Branch (1344:7): [True: 7, False: 0] ------------------ - 1345| 1| log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted", - 1346| 1| __func__); - 1347| 1| return (-1); - 1348| 1| } + 1345| 7| log_debug("%s: SIGNATURE_HASH_ALGORITHMS: encrypted", + 1346| 7| __func__); + 1347| 7| return (-1); + 1348| 7| } 1349| 0| if (sa == NULL) { ------------------ | Branch (1349:7): [True: 0, False: 0] @@ -2204,718 +2204,718 @@ ikev2_pld_notify: ------------------ 1376| 0| } 1377| 0| break; - 1378| 319| } + 1378| 20.0k| } 1379| | - 1380| 219| return (0); - 1381| 319|} + 1380| 19.1k| return (0); + 1381| 20.0k|} ikev2_validate_delete: - 1386| 812|{ - 1387| 812| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1386| 6.99k|{ + 1387| 6.99k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1388| | - 1389| 812| if (left < sizeof(*del)) { + 1389| 6.99k| if (left < sizeof(*del)) { ------------------ - | Branch (1389:6): [True: 110, False: 702] + | Branch (1389:6): [True: 1.33k, False: 5.66k] ------------------ - 1390| 110| log_debug("%s: malformed payload: too short for header " - 1391| 110| "(%zu < %zu)", __func__, left, sizeof(*del)); - 1392| 110| return (-1); - 1393| 110| } - 1394| 702| memcpy(del, msgbuf + offset, sizeof(*del)); + 1390| 1.33k| log_debug("%s: malformed payload: too short for header " + 1391| 1.33k| "(%zu < %zu)", __func__, left, sizeof(*del)); + 1392| 1.33k| return (-1); + 1393| 1.33k| } + 1394| 5.66k| memcpy(del, msgbuf + offset, sizeof(*del)); 1395| | - 1396| 702| if (del->del_protoid == 0) { + 1396| 5.66k| if (del->del_protoid == 0) { ------------------ - | Branch (1396:6): [True: 22, False: 680] + | Branch (1396:6): [True: 84, False: 5.58k] ------------------ - 1397| 22| log_info("%s: malformed payload: invalid protoid", __func__); - 1398| 22| return (-1); - 1399| 22| } + 1397| 84| log_info("%s: malformed payload: invalid protoid", __func__); + 1398| 84| return (-1); + 1399| 84| } 1400| | - 1401| 680| return (0); - 1402| 702|} + 1401| 5.58k| return (0); + 1402| 5.66k|} ikev2_pld_delete: - 1407| 812|{ - 1408| 812| struct ikev2_delete del; - 1409| 812| uint8_t *buf, *msgbuf = ibuf_data(msg->msg_data); - 1410| 812| size_t cnt, sz, len; + 1407| 6.99k|{ + 1408| 6.99k| struct ikev2_delete del; + 1409| 6.99k| uint8_t *buf, *msgbuf = ibuf_data(msg->msg_data); + 1410| 6.99k| size_t cnt, sz, len; 1411| | - 1412| 812| if (ikev2_validate_delete(msg, offset, left, &del)) + 1412| 6.99k| if (ikev2_validate_delete(msg, offset, left, &del)) ------------------ - | Branch (1412:6): [True: 132, False: 680] + | Branch (1412:6): [True: 1.41k, False: 5.58k] ------------------ - 1413| 132| return (-1); + 1413| 1.41k| return (-1); 1414| | 1415| | /* Skip if it's a response, then we don't have to deal with it */ - 1416| 680| if (ikev2_msg_frompeer(msg) && + 1416| 5.58k| if (ikev2_msg_frompeer(msg) && ------------------ - | Branch (1416:6): [True: 44, False: 636] + | Branch (1416:6): [True: 168, False: 5.41k] ------------------ - 1417| 680| msg->msg_parent->msg_response) + 1417| 5.58k| msg->msg_parent->msg_response) ------------------ - | Branch (1417:6): [True: 0, False: 44] + | Branch (1417:6): [True: 0, False: 168] ------------------ 1418| 0| return (0); 1419| | - 1420| 680| cnt = betoh16(del.del_nspi); - 1421| 680| sz = del.del_spisize; + 1420| 5.58k| cnt = betoh16(del.del_nspi); + 1421| 5.58k| sz = del.del_spisize; 1422| | - 1423| 680| log_debug("%s: proto %s spisize %zu nspi %zu", - 1424| 680| __func__, print_map(del.del_protoid, ikev2_saproto_map), - 1425| 680| sz, cnt); + 1423| 5.58k| log_debug("%s: proto %s spisize %zu nspi %zu", + 1424| 5.58k| __func__, print_map(del.del_protoid, ikev2_saproto_map), + 1425| 5.58k| sz, cnt); 1426| | - 1427| 680| if (msg->msg_parent->msg_del_protoid) { + 1427| 5.58k| if (msg->msg_parent->msg_del_protoid) { ------------------ - | Branch (1427:6): [True: 638, False: 42] + | Branch (1427:6): [True: 5.28k, False: 303] ------------------ - 1428| 638| log_debug("%s: duplicate delete payload", __func__); - 1429| 638| return (0); - 1430| 638| } + 1428| 5.28k| log_debug("%s: duplicate delete payload", __func__); + 1429| 5.28k| return (0); + 1430| 5.28k| } 1431| | - 1432| 42| msg->msg_parent->msg_del_protoid = del.del_protoid; - 1433| 42| msg->msg_parent->msg_del_cnt = cnt; - 1434| 42| msg->msg_parent->msg_del_spisize = sz; + 1432| 303| msg->msg_parent->msg_del_protoid = del.del_protoid; + 1433| 303| msg->msg_parent->msg_del_cnt = cnt; + 1434| 303| msg->msg_parent->msg_del_spisize = sz; 1435| | - 1436| 42| buf = msgbuf + offset + sizeof(del); - 1437| 42| len = left - sizeof(del); - 1438| 42| if (len == 0 || sz == 0 || cnt == 0) + 1436| 303| buf = msgbuf + offset + sizeof(del); + 1437| 303| len = left - sizeof(del); + 1438| 303| if (len == 0 || sz == 0 || cnt == 0) ------------------ - | Branch (1438:6): [True: 5, False: 37] - | Branch (1438:18): [True: 23, False: 14] - | Branch (1438:29): [True: 6, False: 8] + | Branch (1438:6): [True: 13, False: 290] + | Branch (1438:18): [True: 222, False: 68] + | Branch (1438:29): [True: 45, False: 23] ------------------ - 1439| 34| return (0); + 1439| 280| return (0); 1440| | - 1441| 8| if ((len / sz) != cnt) { + 1441| 23| if ((len / sz) != cnt) { ------------------ - | Branch (1441:6): [True: 7, False: 1] + | Branch (1441:6): [True: 21, False: 2] ------------------ - 1442| 7| log_debug("%s: invalid payload length %zu/%zu != %zu", - 1443| 7| __func__, len, sz, cnt); - 1444| 7| return (-1); - 1445| 7| } + 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| 1| print_hex(buf, 0, len); + 1447| 2| print_hex(buf, 0, len); 1448| | - 1449| 1| msg->msg_parent->msg_del_buf = ibuf_new(buf, len); + 1449| 2| msg->msg_parent->msg_del_buf = ibuf_new(buf, len); 1450| | - 1451| 1| return (0); - 1452| 8|} + 1451| 2| return (0); + 1452| 23|} ikev2_validate_tss: - 1457| 1.27k|{ - 1458| 1.27k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1457| 16.3k|{ + 1458| 16.3k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1459| | - 1460| 1.27k| if (left < sizeof(*tsp)) { + 1460| 16.3k| if (left < sizeof(*tsp)) { ------------------ - | Branch (1460:6): [True: 146, False: 1.12k] + | Branch (1460:6): [True: 2.36k, False: 13.9k] ------------------ - 1461| 146| log_debug("%s: malformed payload: too short for header " - 1462| 146| "(%zu < %zu)", __func__, left, sizeof(*tsp)); - 1463| 146| return (-1); - 1464| 146| } - 1465| 1.12k| memcpy(tsp, msgbuf + offset, sizeof(*tsp)); + 1461| 2.36k| log_debug("%s: malformed payload: too short for header " + 1462| 2.36k| "(%zu < %zu)", __func__, left, sizeof(*tsp)); + 1463| 2.36k| return (-1); + 1464| 2.36k| } + 1465| 13.9k| memcpy(tsp, msgbuf + offset, sizeof(*tsp)); 1466| | - 1467| 1.12k| return (0); - 1468| 1.27k|} + 1467| 13.9k| return (0); + 1468| 16.3k|} ikev2_pld_tss: - 1473| 1.27k|{ - 1474| 1.27k| struct ikev2_tsp tsp; - 1475| 1.27k| struct ikev2_ts ts; - 1476| 1.27k| size_t ts_len, i; + 1473| 16.3k|{ + 1474| 16.3k| struct ikev2_tsp tsp; + 1475| 16.3k| struct ikev2_ts ts; + 1476| 16.3k| size_t ts_len, i; 1477| | - 1478| 1.27k| if (ikev2_validate_tss(msg, offset, left, &tsp)) + 1478| 16.3k| if (ikev2_validate_tss(msg, offset, left, &tsp)) ------------------ - | Branch (1478:6): [True: 146, False: 1.12k] + | Branch (1478:6): [True: 2.36k, False: 13.9k] ------------------ - 1479| 146| return (-1); + 1479| 2.36k| return (-1); 1480| | - 1481| 1.12k| offset += sizeof(tsp); - 1482| 1.12k| left -= sizeof(tsp); + 1481| 13.9k| offset += sizeof(tsp); + 1482| 13.9k| left -= sizeof(tsp); 1483| | - 1484| 1.12k| log_debug("%s: count %d length %zu", __func__, - 1485| 1.12k| tsp.tsp_count, left); + 1484| 13.9k| log_debug("%s: count %d length %zu", __func__, + 1485| 13.9k| tsp.tsp_count, left); 1486| | - 1487| 1.88k| for (i = 0; i < tsp.tsp_count; i++) { + 1487| 25.8k| for (i = 0; i < tsp.tsp_count; i++) { ------------------ - | Branch (1487:14): [True: 1.79k, False: 90] + | Branch (1487:14): [True: 24.2k, False: 1.59k] ------------------ - 1488| 1.79k| if (ikev2_validate_ts(msg, offset, left, &ts)) + 1488| 24.2k| if (ikev2_validate_ts(msg, offset, left, &ts)) ------------------ - | Branch (1488:7): [True: 898, False: 895] + | Branch (1488:7): [True: 10.9k, False: 13.3k] ------------------ - 1489| 898| return (-1); + 1489| 10.9k| return (-1); 1490| | - 1491| 895| log_debug("%s: type %s protoid %u length %d " - 1492| 895| "startport %u endport %u", __func__, - 1493| 895| print_map(ts.ts_type, ikev2_ts_map), - 1494| 895| ts.ts_protoid, betoh16(ts.ts_length), - 1495| 895| betoh16(ts.ts_startport), - 1496| 895| betoh16(ts.ts_endport)); + 1491| 13.3k| log_debug("%s: type %s protoid %u length %d " + 1492| 13.3k| "startport %u endport %u", __func__, + 1493| 13.3k| print_map(ts.ts_type, ikev2_ts_map), + 1494| 13.3k| ts.ts_protoid, betoh16(ts.ts_length), + 1495| 13.3k| betoh16(ts.ts_startport), + 1496| 13.3k| betoh16(ts.ts_endport)); 1497| | - 1498| 895| offset += sizeof(ts); - 1499| 895| left -= sizeof(ts); + 1498| 13.3k| offset += sizeof(ts); + 1499| 13.3k| left -= sizeof(ts); 1500| | - 1501| 895| ts_len = betoh16(ts.ts_length) - sizeof(ts); - 1502| 895| if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type)) + 1501| 13.3k| ts_len = betoh16(ts.ts_length) - sizeof(ts); + 1502| 13.3k| if (ikev2_pld_ts(env, pld, msg, offset, ts_len, ts.ts_type)) ------------------ - | Branch (1502:7): [True: 137, False: 758] + | Branch (1502:7): [True: 1.45k, False: 11.9k] ------------------ - 1503| 137| return (-1); + 1503| 1.45k| return (-1); 1504| | - 1505| 758| offset += ts_len; - 1506| 758| left -= ts_len; - 1507| 758| } + 1505| 11.9k| offset += ts_len; + 1506| 11.9k| left -= ts_len; + 1507| 11.9k| } 1508| | - 1509| 90| return (0); - 1510| 1.12k|} + 1509| 1.59k| return (0); + 1510| 13.9k|} ikev2_validate_ts: - 1515| 1.79k|{ - 1516| 1.79k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 1517| 1.79k| size_t ts_length; + 1515| 24.2k|{ + 1516| 24.2k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1517| 24.2k| size_t ts_length; 1518| | - 1519| 1.79k| if (left < sizeof(*ts)) { + 1519| 24.2k| if (left < sizeof(*ts)) { ------------------ - | Branch (1519:6): [True: 793, False: 1.00k] + | Branch (1519:6): [True: 9.93k, False: 14.3k] ------------------ - 1520| 793| log_debug("%s: malformed payload: too short for header " - 1521| 793| "(%zu < %zu)", __func__, left, sizeof(*ts)); - 1522| 793| return (-1); - 1523| 793| } - 1524| 1.00k| memcpy(ts, msgbuf + offset, sizeof(*ts)); + 1520| 9.93k| log_debug("%s: malformed payload: too short for header " + 1521| 9.93k| "(%zu < %zu)", __func__, left, sizeof(*ts)); + 1522| 9.93k| return (-1); + 1523| 9.93k| } + 1524| 14.3k| memcpy(ts, msgbuf + offset, sizeof(*ts)); 1525| | - 1526| 1.00k| ts_length = betoh16(ts->ts_length); - 1527| 1.00k| if (ts_length < sizeof(*ts)) { + 1526| 14.3k| ts_length = betoh16(ts->ts_length); + 1527| 14.3k| if (ts_length < sizeof(*ts)) { ------------------ - | Branch (1527:6): [True: 40, False: 960] + | Branch (1527:6): [True: 289, False: 14.0k] ------------------ - 1528| 40| log_debug("%s: malformed payload: shorter than minimum header " - 1529| 40| "size (%zu < %zu)", __func__, ts_length, sizeof(*ts)); - 1530| 40| return (-1); - 1531| 40| } - 1532| 960| if (left < ts_length) { + 1528| 289| log_debug("%s: malformed payload: shorter than minimum header " + 1529| 289| "size (%zu < %zu)", __func__, ts_length, sizeof(*ts)); + 1530| 289| return (-1); + 1531| 289| } + 1532| 14.0k| if (left < ts_length) { ------------------ - | Branch (1532:6): [True: 65, False: 895] + | Branch (1532:6): [True: 692, False: 13.3k] ------------------ - 1533| 65| log_debug("%s: malformed payload: too long for payload size " - 1534| 65| "(%zu < %zu)", __func__, left, ts_length); - 1535| 65| return (-1); - 1536| 65| } + 1533| 692| log_debug("%s: malformed payload: too long for payload size " + 1534| 692| "(%zu < %zu)", __func__, left, ts_length); + 1535| 692| return (-1); + 1536| 692| } 1537| | - 1538| 895| return (0); - 1539| 960|} + 1538| 13.3k| return (0); + 1539| 14.0k|} ikev2_pld_ts: - 1544| 895|{ - 1545| 895| struct sockaddr_in start4, end4; - 1546| 895| struct sockaddr_in6 start6, end6; - 1547| 895| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 1548| 895| uint8_t *ptr; + 1544| 13.3k|{ + 1545| 13.3k| struct sockaddr_in start4, end4; + 1546| 13.3k| struct sockaddr_in6 start6, end6; + 1547| 13.3k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1548| 13.3k| uint8_t *ptr; 1549| | - 1550| 895| ptr = msgbuf + offset; + 1550| 13.3k| ptr = msgbuf + offset; 1551| | - 1552| 895| switch (type) { - 1553| 242| case IKEV2_TS_IPV4_ADDR_RANGE: + 1552| 13.3k| switch (type) { + 1553| 4.72k| case IKEV2_TS_IPV4_ADDR_RANGE: ------------------ - | | 460| 242|#define IKEV2_TS_IPV4_ADDR_RANGE 7 /* RFC7296 */ + | | 460| 4.72k|#define IKEV2_TS_IPV4_ADDR_RANGE 7 /* RFC7296 */ ------------------ - | Branch (1553:2): [True: 242, False: 653] + | Branch (1553:2): [True: 4.72k, False: 8.63k] ------------------ - 1554| 242| if (left < 2 * 4) { + 1554| 4.72k| if (left < 2 * 4) { ------------------ - | Branch (1554:7): [True: 34, False: 208] + | Branch (1554:7): [True: 307, False: 4.42k] ------------------ - 1555| 34| log_debug("%s: malformed payload: too short " - 1556| 34| "for ipv4 addr range (%zu < %u)", - 1557| 34| __func__, left, 2 * 4); - 1558| 34| return (-1); - 1559| 34| } + 1555| 307| log_debug("%s: malformed payload: too short " + 1556| 307| "for ipv4 addr range (%zu < %u)", + 1557| 307| __func__, left, 2 * 4); + 1558| 307| return (-1); + 1559| 307| } 1560| | - 1561| 208| bzero(&start4, sizeof(start4)); - 1562| 208| start4.sin_family = AF_INET; + 1561| 4.42k| bzero(&start4, sizeof(start4)); + 1562| 4.42k| start4.sin_family = AF_INET; 1563| |#ifdef HAVE_SOCKADDR_SA_LEN 1564| | start4.sin_len = sizeof(start4); 1565| |#endif - 1566| 208| memcpy(&start4.sin_addr.s_addr, ptr, 4); - 1567| 208| ptr += 4; - 1568| 208| left -= 4; + 1566| 4.42k| memcpy(&start4.sin_addr.s_addr, ptr, 4); + 1567| 4.42k| ptr += 4; + 1568| 4.42k| left -= 4; 1569| | - 1570| 208| bzero(&end4, sizeof(end4)); - 1571| 208| end4.sin_family = AF_INET; + 1570| 4.42k| bzero(&end4, sizeof(end4)); + 1571| 4.42k| end4.sin_family = AF_INET; 1572| |#ifdef HAVE_SOCKADDR_SA_LEN 1573| | end4.sin_len = sizeof(end4); 1574| |#endif - 1575| 208| memcpy(&end4.sin_addr.s_addr, ptr, 4); - 1576| 208| left -= 4; + 1575| 4.42k| memcpy(&end4.sin_addr.s_addr, ptr, 4); + 1576| 4.42k| left -= 4; 1577| | - 1578| 208| log_debug("%s: start %s end %s", __func__, - 1579| 208| print_addr(&start4), print_addr(&end4)); - 1580| 208| break; - 1581| 93| case IKEV2_TS_IPV6_ADDR_RANGE: + 1578| 4.42k| log_debug("%s: start %s end %s", __func__, + 1579| 4.42k| print_addr(&start4), print_addr(&end4)); + 1580| 4.42k| break; + 1581| 1.14k| case IKEV2_TS_IPV6_ADDR_RANGE: ------------------ - | | 461| 93|#define IKEV2_TS_IPV6_ADDR_RANGE 8 /* RFC7296 */ + | | 461| 1.14k|#define IKEV2_TS_IPV6_ADDR_RANGE 8 /* RFC7296 */ ------------------ - | Branch (1581:2): [True: 93, False: 802] + | Branch (1581:2): [True: 1.14k, False: 12.2k] ------------------ - 1582| 93| if (left < 2 * 16) { + 1582| 1.14k| if (left < 2 * 16) { ------------------ - | Branch (1582:7): [True: 34, False: 59] + | Branch (1582:7): [True: 252, False: 890] ------------------ - 1583| 34| log_debug("%s: malformed payload: too short " - 1584| 34| "for ipv6 addr range (%zu < %u)", - 1585| 34| __func__, left, 2 * 16); - 1586| 34| return (-1); - 1587| 34| } - 1588| 59| bzero(&start6, sizeof(start6)); - 1589| 59| start6.sin6_family = AF_INET6; + 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| 890| bzero(&start6, sizeof(start6)); + 1589| 890| start6.sin6_family = AF_INET6; 1590| |#ifdef HAVE_SOCKADDR_SA_LEN 1591| | start6.sin6_len = sizeof(start6); 1592| |#endif - 1593| 59| memcpy(&start6.sin6_addr, ptr, 16); - 1594| 59| ptr += 16; - 1595| 59| left -= 16; + 1593| 890| memcpy(&start6.sin6_addr, ptr, 16); + 1594| 890| ptr += 16; + 1595| 890| left -= 16; 1596| | - 1597| 59| bzero(&end6, sizeof(end6)); - 1598| 59| end6.sin6_family = AF_INET6; + 1597| 890| bzero(&end6, sizeof(end6)); + 1598| 890| end6.sin6_family = AF_INET6; 1599| |#ifdef HAVE_SOCKADDR_SA_LEN 1600| | end6.sin6_len = sizeof(end6); 1601| |#endif - 1602| 59| memcpy(&end6.sin6_addr, ptr, 16); - 1603| 59| left -= 16; + 1602| 890| memcpy(&end6.sin6_addr, ptr, 16); + 1603| 890| left -= 16; 1604| | - 1605| 59| log_debug("%s: start %s end %s", __func__, - 1606| 59| print_addr(&start6), print_addr(&end6)); - 1607| 59| break; - 1608| 560| default: + 1605| 890| log_debug("%s: start %s end %s", __func__, + 1606| 890| print_addr(&start6), print_addr(&end6)); + 1607| 890| break; + 1608| 7.49k| default: ------------------ - | Branch (1608:2): [True: 560, False: 335] + | Branch (1608:2): [True: 7.49k, False: 5.87k] ------------------ - 1609| 560| log_debug("%s: ignoring unknown TS type %u", __func__, type); - 1610| 560| return (0); - 1611| 895| } + 1609| 7.49k| log_debug("%s: ignoring unknown TS type %u", __func__, type); + 1610| 7.49k| return (0); + 1611| 13.3k| } 1612| | - 1613| 267| if (left > 0) { + 1613| 5.31k| if (left > 0) { ------------------ - | Branch (1613:6): [True: 69, False: 198] + | Branch (1613:6): [True: 900, False: 4.41k] ------------------ - 1614| 69| log_debug("%s: malformed payload: left (%zu) > 0", - 1615| 69| __func__, left); - 1616| 69| return (-1); - 1617| 69| } + 1614| 900| log_debug("%s: malformed payload: left (%zu) > 0", + 1615| 900| __func__, left); + 1616| 900| return (-1); + 1617| 900| } 1618| | - 1619| 198| return (0); - 1620| 267|} + 1619| 4.41k| return (0); + 1620| 5.31k|} ikev2_validate_cp: - 1875| 1.30k|{ - 1876| 1.30k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1875| 8.50k|{ + 1876| 8.50k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 1877| | - 1878| 1.30k| if (left < sizeof(*cp)) { + 1878| 8.50k| if (left < sizeof(*cp)) { ------------------ - | Branch (1878:6): [True: 236, False: 1.06k] + | Branch (1878:6): [True: 2.70k, False: 5.79k] ------------------ - 1879| 236| log_debug("%s: malformed payload: too short for header " - 1880| 236| "(%zu < %zu)", __func__, left, sizeof(*cp)); - 1881| 236| return (-1); - 1882| 236| } - 1883| 1.06k| memcpy(cp, msgbuf + offset, sizeof(*cp)); + 1879| 2.70k| log_debug("%s: malformed payload: too short for header " + 1880| 2.70k| "(%zu < %zu)", __func__, left, sizeof(*cp)); + 1881| 2.70k| return (-1); + 1882| 2.70k| } + 1883| 5.79k| memcpy(cp, msgbuf + offset, sizeof(*cp)); 1884| | - 1885| 1.06k| return (0); - 1886| 1.30k|} + 1885| 5.79k| return (0); + 1886| 8.50k|} ikev2_pld_cp: - 1891| 1.30k|{ - 1892| 1.30k| struct ikev2_cp cp; - 1893| 1.30k| struct ikev2_cfg *cfg; - 1894| 1.30k| struct iked_addr *addr; - 1895| 1.30k| struct sockaddr_in *in4; - 1896| 1.30k| struct sockaddr_in6 *in6; - 1897| 1.30k| uint8_t *msgbuf = ibuf_data(msg->msg_data); - 1898| 1.30k| uint8_t *ptr; - 1899| 1.30k| size_t len; - 1900| 1.30k| int cfg_type; + 1891| 8.50k|{ + 1892| 8.50k| struct ikev2_cp cp; + 1893| 8.50k| struct ikev2_cfg *cfg; + 1894| 8.50k| struct iked_addr *addr; + 1895| 8.50k| struct sockaddr_in *in4; + 1896| 8.50k| struct sockaddr_in6 *in6; + 1897| 8.50k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 1898| 8.50k| uint8_t *ptr; + 1899| 8.50k| size_t len; + 1900| 8.50k| int cfg_type; 1901| | - 1902| 1.30k| if (ikev2_validate_cp(msg, offset, left, &cp)) + 1902| 8.50k| if (ikev2_validate_cp(msg, offset, left, &cp)) ------------------ - | Branch (1902:6): [True: 236, False: 1.06k] + | Branch (1902:6): [True: 2.70k, False: 5.79k] ------------------ - 1903| 236| return (-1); + 1903| 2.70k| return (-1); 1904| | - 1905| 1.06k| ptr = msgbuf + offset + sizeof(cp); - 1906| 1.06k| len = left - sizeof(cp); + 1905| 5.79k| ptr = msgbuf + offset + sizeof(cp); + 1906| 5.79k| len = left - sizeof(cp); 1907| | - 1908| 1.06k| log_debug("%s: type %s length %zu", - 1909| 1.06k| __func__, print_map(cp.cp_type, ikev2_cp_map), len); - 1910| 1.06k| print_hex(ptr, 0, len); + 1908| 5.79k| log_debug("%s: type %s length %zu", + 1909| 5.79k| __func__, print_map(cp.cp_type, ikev2_cp_map), len); + 1910| 5.79k| print_hex(ptr, 0, len); 1911| | - 1912| 2.18k| while (len > 0) { + 1912| 13.1k| while (len > 0) { ------------------ - | Branch (1912:9): [True: 1.34k, False: 842] + | Branch (1912:9): [True: 8.63k, False: 4.52k] ------------------ - 1913| 1.34k| if (len < sizeof(*cfg)) { + 1913| 8.63k| if (len < sizeof(*cfg)) { ------------------ - | Branch (1913:7): [True: 102, False: 1.23k] + | Branch (1913:7): [True: 339, False: 8.29k] ------------------ - 1914| 102| log_debug("%s: malformed payload: too short for cfg " - 1915| 102| "(%zu < %zu)", __func__, len, sizeof(*cfg)); - 1916| 102| return (-1); - 1917| 102| } - 1918| 1.23k| cfg = (struct ikev2_cfg *)ptr; + 1914| 339| log_debug("%s: malformed payload: too short for cfg " + 1915| 339| "(%zu < %zu)", __func__, len, sizeof(*cfg)); + 1916| 339| return (-1); + 1917| 339| } + 1918| 8.29k| cfg = (struct ikev2_cfg *)ptr; 1919| | - 1920| 1.23k| log_debug("%s: %s 0x%04x length %d", __func__, - 1921| 1.23k| print_map(betoh16(cfg->cfg_type), ikev2_cfg_map), - 1922| 1.23k| betoh16(cfg->cfg_type), - 1923| 1.23k| betoh16(cfg->cfg_length)); + 1920| 8.29k| log_debug("%s: %s 0x%04x length %d", __func__, + 1921| 8.29k| print_map(betoh16(cfg->cfg_type), ikev2_cfg_map), + 1922| 8.29k| betoh16(cfg->cfg_type), + 1923| 8.29k| betoh16(cfg->cfg_length)); 1924| | - 1925| 1.23k| ptr += sizeof(*cfg); - 1926| 1.23k| len -= sizeof(*cfg); + 1925| 8.29k| ptr += sizeof(*cfg); + 1926| 8.29k| len -= sizeof(*cfg); 1927| | - 1928| 1.23k| if (len < betoh16(cfg->cfg_length)) { + 1928| 8.29k| if (len < betoh16(cfg->cfg_length)) { ------------------ - | Branch (1928:7): [True: 121, False: 1.11k] + | Branch (1928:7): [True: 932, False: 7.36k] ------------------ - 1929| 121| log_debug("%s: malformed payload: too short for " - 1930| 121| "cfg_length (%zu < %u)", __func__, len, - 1931| 121| betoh16(cfg->cfg_length)); - 1932| 121| return (-1); - 1933| 121| } + 1929| 932| log_debug("%s: malformed payload: too short for " + 1930| 932| "cfg_length (%zu < %u)", __func__, len, + 1931| 932| betoh16(cfg->cfg_length)); + 1932| 932| return (-1); + 1933| 932| } 1934| | - 1935| 1.11k| print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length)); + 1935| 7.36k| print_hex(ptr, sizeof(*cfg), betoh16(cfg->cfg_length)); 1936| | - 1937| 1.11k| cfg_type = betoh16(cfg->cfg_type); - 1938| 1.11k| switch (cfg_type) { + 1937| 7.36k| cfg_type = betoh16(cfg->cfg_type); + 1938| 7.36k| switch (cfg_type) { ------------------ - | Branch (1938:11): [True: 575, False: 542] + | Branch (1938:11): [True: 3.07k, False: 4.29k] ------------------ - 1939| 149| case IKEV2_CFG_INTERNAL_IP4_ADDRESS: + 1939| 833| case IKEV2_CFG_INTERNAL_IP4_ADDRESS: ------------------ - | | 528| 149|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ + | | 528| 833|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ ------------------ - | Branch (1939:3): [True: 149, False: 968] + | Branch (1939:3): [True: 833, False: 6.52k] ------------------ - 1940| 253| case IKEV2_CFG_INTERNAL_IP4_DNS: + 1940| 1.43k| case IKEV2_CFG_INTERNAL_IP4_DNS: ------------------ - | | 530| 253|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ + | | 530| 1.43k|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ ------------------ - | Branch (1940:3): [True: 104, False: 1.01k] + | Branch (1940:3): [True: 602, False: 6.76k] ------------------ - 1941| 253| if (!ikev2_msg_frompeer(msg)) + 1941| 1.43k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (1941:8): [True: 121, False: 132] + | Branch (1941:8): [True: 668, False: 767] ------------------ - 1942| 121| break; - 1943| 132| if (betoh16(cfg->cfg_length) == 0) + 1942| 668| break; + 1943| 767| if (betoh16(cfg->cfg_length) == 0) ------------------ - | Branch (1943:8): [True: 78, False: 54] + | Branch (1943:8): [True: 307, False: 460] ------------------ - 1944| 78| break; + 1944| 307| break; 1945| | /* XXX multiple-valued */ - 1946| 54| if (betoh16(cfg->cfg_length) < 4) { + 1946| 460| if (betoh16(cfg->cfg_length) < 4) { ------------------ - | Branch (1946:8): [True: 1, False: 53] + | Branch (1946:8): [True: 6, False: 454] ------------------ - 1947| 1| log_debug("%s: malformed payload: too short " - 1948| 1| "for ipv4 addr (%u < %u)", - 1949| 1| __func__, betoh16(cfg->cfg_length), 4); - 1950| 1| return (-1); - 1951| 1| } - 1952| 53| switch(cfg_type) { - 1953| 34| case IKEV2_CFG_INTERNAL_IP4_ADDRESS: + 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: ------------------ - | | 528| 34|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ + | | 528| 355|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ ------------------ - | Branch (1953:4): [True: 34, False: 19] + | Branch (1953:4): [True: 355, False: 99] ------------------ - 1954| 34| if (msg->msg_parent->msg_cp_addr != NULL) { + 1954| 355| if (msg->msg_parent->msg_cp_addr != NULL) { ------------------ - | Branch (1954:9): [True: 21, False: 13] + | Branch (1954:9): [True: 238, False: 117] ------------------ - 1955| 21| log_debug("%s: address already set", __func__); - 1956| 21| goto skip; - 1957| 21| } - 1958| 13| break; - 1959| 19| case IKEV2_CFG_INTERNAL_IP4_DNS: + 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: ------------------ - | | 530| 19|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ + | | 530| 99|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ ------------------ - | Branch (1959:4): [True: 19, False: 34] + | Branch (1959:4): [True: 99, False: 355] ------------------ - 1960| 19| if (msg->msg_parent->msg_cp_dns != NULL) { + 1960| 99| if (msg->msg_parent->msg_cp_dns != NULL) { ------------------ - | Branch (1960:9): [True: 10, False: 9] + | Branch (1960:9): [True: 51, False: 48] ------------------ - 1961| 10| log_debug("%s: dns already set", __func__); - 1962| 10| goto skip; - 1963| 10| } - 1964| 9| break; - 1965| 9| default: + 1961| 51| log_debug("%s: dns already set", __func__); + 1962| 51| goto skip; + 1963| 51| } + 1964| 48| break; + 1965| 48| default: ------------------ - | Branch (1965:4): [True: 0, False: 53] + | Branch (1965:4): [True: 0, False: 454] ------------------ 1966| 0| break; - 1967| 53| } - 1968| 22| if ((addr = calloc(1, sizeof(*addr))) == NULL) { + 1967| 454| } + 1968| 165| if ((addr = calloc(1, sizeof(*addr))) == NULL) { ------------------ - | Branch (1968:8): [True: 0, False: 22] + | Branch (1968:8): [True: 0, False: 165] ------------------ 1969| 0| log_debug("%s: malloc failed", __func__); 1970| 0| break; 1971| 0| } - 1972| 22| addr->addr_af = AF_INET; - 1973| 22| in4 = (struct sockaddr_in *)&addr->addr; - 1974| 22| in4->sin_family = AF_INET; + 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| 22| memcpy(&in4->sin_addr.s_addr, ptr, 4); - 1979| 22| switch(cfg_type) { - 1980| 13| case IKEV2_CFG_INTERNAL_IP4_ADDRESS: + 1978| 165| memcpy(&in4->sin_addr.s_addr, ptr, 4); + 1979| 165| switch(cfg_type) { + 1980| 117| case IKEV2_CFG_INTERNAL_IP4_ADDRESS: ------------------ - | | 528| 13|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ + | | 528| 117|#define IKEV2_CFG_INTERNAL_IP4_ADDRESS 1 /* RFC7296 */ ------------------ - | Branch (1980:4): [True: 13, False: 9] + | Branch (1980:4): [True: 117, False: 48] ------------------ - 1981| 13| msg->msg_parent->msg_cp_addr = addr; - 1982| 13| log_debug("%s: IP4_ADDRESS %s", __func__, - 1983| 13| print_addr(&addr->addr)); - 1984| 13| break; - 1985| 9| case IKEV2_CFG_INTERNAL_IP4_DNS: + 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: ------------------ - | | 530| 9|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ + | | 530| 48|#define IKEV2_CFG_INTERNAL_IP4_DNS 3 /* RFC7296 */ ------------------ - | Branch (1985:4): [True: 9, False: 13] + | Branch (1985:4): [True: 48, False: 117] ------------------ - 1986| 9| msg->msg_parent->msg_cp_dns = addr; - 1987| 9| log_debug("%s: IP4_DNS %s", __func__, - 1988| 9| print_addr(&addr->addr)); - 1989| 9| break; + 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: ------------------ - | Branch (1990:4): [True: 0, False: 22] + | Branch (1990:4): [True: 0, False: 165] ------------------ 1991| 0| log_debug("%s: cfg %s", __func__, 1992| 0| print_addr(&addr->addr)); 1993| 0| break; - 1994| 22| } - 1995| 22| break; - 1996| 196| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: + 1994| 165| } + 1995| 165| break; + 1996| 2.05k| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: ------------------ - | | 535| 196|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ + | | 535| 2.05k|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ ------------------ - | Branch (1996:3): [True: 196, False: 921] + | Branch (1996:3): [True: 2.05k, False: 5.30k] ------------------ - 1997| 289| case IKEV2_CFG_INTERNAL_IP6_DNS: + 1997| 2.85k| case IKEV2_CFG_INTERNAL_IP6_DNS: ------------------ - | | 536| 289|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ + | | 536| 2.85k|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ ------------------ - | Branch (1997:3): [True: 93, False: 1.02k] + | Branch (1997:3): [True: 797, False: 6.56k] ------------------ - 1998| 289| if (!ikev2_msg_frompeer(msg)) + 1998| 2.85k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (1998:8): [True: 233, False: 56] + | Branch (1998:8): [True: 2.67k, False: 185] ------------------ - 1999| 233| break; - 2000| 56| if (betoh16(cfg->cfg_length) == 0) + 1999| 2.67k| break; + 2000| 185| if (betoh16(cfg->cfg_length) == 0) ------------------ - | Branch (2000:8): [True: 29, False: 27] + | Branch (2000:8): [True: 58, False: 127] ------------------ - 2001| 29| break; + 2001| 58| break; 2002| | /* XXX multiple-valued */ - 2003| 27| if (betoh16(cfg->cfg_length) < 16) { + 2003| 127| if (betoh16(cfg->cfg_length) < 16) { ------------------ - | Branch (2003:8): [True: 1, False: 26] + | Branch (2003:8): [True: 1, False: 126] ------------------ 2004| 1| log_debug("%s: malformed payload: too short " 2005| 1| "for ipv6 addr w/prefixlen (%u < %u)", 2006| 1| __func__, betoh16(cfg->cfg_length), 16); 2007| 1| return (-1); 2008| 1| } - 2009| 26| switch(cfg_type) { + 2009| 126| switch(cfg_type) { ------------------ - | Branch (2009:11): [True: 0, False: 26] + | Branch (2009:11): [True: 0, False: 126] ------------------ - 2010| 15| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: + 2010| 86| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: ------------------ - | | 535| 15|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ + | | 535| 86|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ ------------------ - | Branch (2010:4): [True: 15, False: 11] + | Branch (2010:4): [True: 86, False: 40] ------------------ - 2011| 15| if (msg->msg_parent->msg_cp_addr6 != NULL) { + 2011| 86| if (msg->msg_parent->msg_cp_addr6 != NULL) { ------------------ - | Branch (2011:9): [True: 10, False: 5] + | Branch (2011:9): [True: 47, False: 39] ------------------ - 2012| 10| log_debug("%s: address6 already set", __func__); - 2013| 10| goto skip; - 2014| 10| } - 2015| 5| break; - 2016| 11| case IKEV2_CFG_INTERNAL_IP6_DNS: + 2012| 47| log_debug("%s: address6 already set", __func__); + 2013| 47| goto skip; + 2014| 47| } + 2015| 39| break; + 2016| 40| case IKEV2_CFG_INTERNAL_IP6_DNS: ------------------ - | | 536| 11|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ + | | 536| 40|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ ------------------ - | Branch (2016:4): [True: 11, False: 15] + | Branch (2016:4): [True: 40, False: 86] ------------------ - 2017| 11| if (msg->msg_parent->msg_cp_dns != NULL) { + 2017| 40| if (msg->msg_parent->msg_cp_dns != NULL) { ------------------ - | Branch (2017:9): [True: 10, False: 1] + | Branch (2017:9): [True: 36, False: 4] ------------------ - 2018| 10| log_debug("%s: dns already set", __func__); - 2019| 10| goto skip; - 2020| 10| } - 2021| 1| break; - 2022| 26| } - 2023| 6| if ((addr = calloc(1, sizeof(*addr))) == NULL) { + 2018| 36| log_debug("%s: dns already set", __func__); + 2019| 36| goto skip; + 2020| 36| } + 2021| 4| break; + 2022| 126| } + 2023| 43| if ((addr = calloc(1, sizeof(*addr))) == NULL) { ------------------ - | Branch (2023:8): [True: 0, False: 6] + | Branch (2023:8): [True: 0, False: 43] ------------------ 2024| 0| log_debug("%s: malloc failed", __func__); 2025| 0| break; 2026| 0| } - 2027| 6| addr->addr_af = AF_INET6; - 2028| 6| in6 = (struct sockaddr_in6 *)&addr->addr; - 2029| 6| in6->sin6_family = AF_INET6; + 2027| 43| addr->addr_af = AF_INET6; + 2028| 43| in6 = (struct sockaddr_in6 *)&addr->addr; + 2029| 43| in6->sin6_family = AF_INET6; 2030| |#ifdef HAVE_SOCKADDR_SA_LEN 2031| | in6->sin6_len = sizeof(*in6); 2032| |#endif - 2033| 6| memcpy(&in6->sin6_addr, ptr, 16); - 2034| 6| switch(cfg_type) { - 2035| 5| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: + 2033| 43| memcpy(&in6->sin6_addr, ptr, 16); + 2034| 43| switch(cfg_type) { + 2035| 39| case IKEV2_CFG_INTERNAL_IP6_ADDRESS: ------------------ - | | 535| 5|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ + | | 535| 39|#define IKEV2_CFG_INTERNAL_IP6_ADDRESS 8 /* RFC7296 */ ------------------ - | Branch (2035:4): [True: 5, False: 1] + | Branch (2035:4): [True: 39, False: 4] ------------------ - 2036| 5| msg->msg_parent->msg_cp_addr6 = addr; - 2037| 5| log_debug("%s: IP6_ADDRESS %s", __func__, - 2038| 5| print_addr(&addr->addr)); - 2039| 5| break; - 2040| 1| case IKEV2_CFG_INTERNAL_IP6_DNS: + 2036| 39| msg->msg_parent->msg_cp_addr6 = addr; + 2037| 39| log_debug("%s: IP6_ADDRESS %s", __func__, + 2038| 39| print_addr(&addr->addr)); + 2039| 39| break; + 2040| 4| case IKEV2_CFG_INTERNAL_IP6_DNS: ------------------ - | | 536| 1|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ + | | 536| 4|#define IKEV2_CFG_INTERNAL_IP6_DNS 10 /* RFC7296 */ ------------------ - | Branch (2040:4): [True: 1, False: 5] + | Branch (2040:4): [True: 4, False: 39] ------------------ - 2041| 1| msg->msg_parent->msg_cp_dns = addr; - 2042| 1| log_debug("%s: IP6_DNS %s", __func__, - 2043| 1| print_addr(&addr->addr)); - 2044| 1| break; + 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: ------------------ - | Branch (2045:4): [True: 0, False: 6] + | Branch (2045:4): [True: 0, False: 43] ------------------ 2046| 0| log_debug("%s: cfg %s/%d", __func__, 2047| 0| print_addr(&addr->addr), ptr[16]); 2048| 0| break; - 2049| 6| } - 2050| 6| break; - 2051| 1.11k| } + 2049| 43| } + 2050| 43| break; + 2051| 7.36k| } 2052| | - 2053| 1.11k| skip: - 2054| 1.11k| ptr += betoh16(cfg->cfg_length); - 2055| 1.11k| len -= betoh16(cfg->cfg_length); - 2056| 1.11k| } + 2053| 7.35k| skip: + 2054| 7.35k| ptr += betoh16(cfg->cfg_length); + 2055| 7.35k| len -= betoh16(cfg->cfg_length); + 2056| 7.35k| } 2057| | - 2058| 842| if (!ikev2_msg_frompeer(msg)) + 2058| 4.52k| if (!ikev2_msg_frompeer(msg)) ------------------ - | Branch (2058:6): [True: 792, False: 50] + | Branch (2058:6): [True: 4.33k, False: 189] ------------------ - 2059| 792| return (0); + 2059| 4.33k| return (0); 2060| | - 2061| 50| msg->msg_parent->msg_cp = cp.cp_type; + 2061| 189| msg->msg_parent->msg_cp = cp.cp_type; 2062| | - 2063| 50| return (0); - 2064| 842|} + 2063| 189| return (0); + 2064| 4.52k|} ikev2_validate_eap: - 2069| 3.33k|{ - 2070| 3.33k| uint8_t *msgbuf = ibuf_data(msg->msg_data); + 2069| 16.1k|{ + 2070| 16.1k| uint8_t *msgbuf = ibuf_data(msg->msg_data); 2071| | - 2072| 3.33k| if (left < sizeof(*hdr)) { + 2072| 16.1k| if (left < sizeof(*hdr)) { ------------------ - | Branch (2072:6): [True: 1.26k, False: 2.07k] + | Branch (2072:6): [True: 6.77k, False: 9.33k] ------------------ - 2073| 1.26k| log_debug("%s: malformed payload: too short for header " - 2074| 1.26k| "(%zu < %zu)", __func__, left, sizeof(*hdr)); - 2075| 1.26k| return (-1); - 2076| 1.26k| } - 2077| 2.07k| memcpy(hdr, msgbuf + offset, sizeof(*hdr)); + 2073| 6.77k| log_debug("%s: malformed payload: too short for header " + 2074| 6.77k| "(%zu < %zu)", __func__, left, sizeof(*hdr)); + 2075| 6.77k| return (-1); + 2076| 6.77k| } + 2077| 9.33k| memcpy(hdr, msgbuf + offset, sizeof(*hdr)); 2078| | - 2079| 2.07k| return (0); - 2080| 3.33k|} + 2079| 9.33k| return (0); + 2080| 16.1k|} ikev2_pld_eap: - 2085| 3.33k|{ - 2086| 3.33k| struct eap_header hdr; - 2087| 3.33k| struct eap_message *eap = NULL; - 2088| 3.33k| const struct iked_sa *sa = msg->msg_sa; - 2089| 3.33k| size_t len; + 2085| 16.1k|{ + 2086| 16.1k| struct eap_header hdr; + 2087| 16.1k| struct eap_message *eap = NULL; + 2088| 16.1k| const struct iked_sa *sa = msg->msg_sa; + 2089| 16.1k| size_t len; 2090| | - 2091| 3.33k| if (ikev2_validate_eap(msg, offset, left, &hdr)) + 2091| 16.1k| if (ikev2_validate_eap(msg, offset, left, &hdr)) ------------------ - | Branch (2091:6): [True: 1.26k, False: 2.07k] + | Branch (2091:6): [True: 6.77k, False: 9.33k] ------------------ - 2092| 1.26k| return (-1); - 2093| 2.07k| len = betoh16(hdr.eap_length); + 2092| 6.77k| return (-1); + 2093| 9.33k| len = betoh16(hdr.eap_length); 2094| | - 2095| 2.07k| if (len < sizeof(*eap)) { + 2095| 9.33k| if (len < sizeof(*eap)) { ------------------ - | Branch (2095:6): [True: 861, False: 1.21k] + | Branch (2095:6): [True: 3.37k, False: 5.96k] ------------------ - 2096| 861| log_info("%s: %s id %d length %d", SPI_SA(sa, __func__), + 2096| 3.37k| log_info("%s: %s id %d length %d", SPI_SA(sa, __func__), ------------------ - | | 1105| 861|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) + | | 1105| 3.37k|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) | | ------------------ - | | | | 1104| 861|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) + | | | | 1104| 3.37k|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) | | ------------------ ------------------ - 2097| 861| print_map(hdr.eap_code, eap_code_map), - 2098| 861| hdr.eap_id, betoh16(hdr.eap_length)); - 2099| 1.21k| } else { + 2097| 3.37k| print_map(hdr.eap_code, eap_code_map), + 2098| 3.37k| hdr.eap_id, betoh16(hdr.eap_length)); + 2099| 5.96k| } else { 2100| | /* Now try to get the indicated length */ - 2101| 1.21k| if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) { + 2101| 5.96k| if ((eap = ibuf_seek(msg->msg_data, offset, len)) == NULL) { ------------------ - | Branch (2101:7): [True: 477, False: 737] + | Branch (2101:7): [True: 2.86k, False: 3.10k] ------------------ - 2102| 477| log_debug("%s: invalid EAP length", __func__); - 2103| 477| return (-1); - 2104| 477| } + 2102| 2.86k| log_debug("%s: invalid EAP length", __func__); + 2103| 2.86k| return (-1); + 2104| 2.86k| } 2105| | - 2106| 737| log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__), + 2106| 3.10k| log_info("%s: %s id %d length %d EAP-%s", SPI_SA(sa, __func__), ------------------ - | | 1105| 737|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) + | | 1105| 3.10k|#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f)) | | ------------------ - | | | | 1104| 737|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) + | | | | 1104| 3.10k|#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f)) | | ------------------ ------------------ - 2107| 737| print_map(eap->eap_code, eap_code_map), - 2108| 737| eap->eap_id, betoh16(eap->eap_length), - 2109| 737| print_map(eap->eap_type, eap_type_map)); + 2107| 3.10k| print_map(eap->eap_code, eap_code_map), + 2108| 3.10k| eap->eap_id, betoh16(eap->eap_length), + 2109| 3.10k| print_map(eap->eap_type, eap_type_map)); 2110| | - 2111| 737| if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1) + 2111| 3.10k| if (eap_parse(env, sa, msg, eap, msg->msg_response) == -1) ------------------ - | Branch (2111:7): [True: 0, False: 737] + | Branch (2111:7): [True: 0, False: 3.10k] ------------------ 2112| 0| return (-1); - 2113| 737| msg->msg_parent->msg_eap.eam_found = 1; - 2114| 737| } + 2113| 3.10k| msg->msg_parent->msg_eap.eam_found = 1; + 2114| 3.10k| } 2115| | - 2116| 1.59k| return (0); - 2117| 2.07k|} + 2116| 6.47k| return (0); + 2117| 9.33k|} ibuf_new: - 41| 1.51k|{ - 42| 1.51k| struct ibuf *buf; + 41| 16.2k|{ + 42| 16.2k| struct ibuf *buf; 43| | - 44| 1.51k| if ((buf = ibuf_dynamic(len, + 44| 16.2k| if ((buf = ibuf_dynamic(len, ------------------ - | Branch (44:6): [True: 0, False: 1.51k] + | Branch (44:6): [True: 0, False: 16.2k] ------------------ - 45| 1.51k| IKED_MSGBUF_MAX)) == NULL) + 45| 16.2k| IKED_MSGBUF_MAX)) == NULL) ------------------ - | | 66| 1.51k|#define IKED_MSGBUF_MAX 8192 + | | 66| 16.2k|#define IKED_MSGBUF_MAX 8192 ------------------ 46| 0| return (NULL); 47| | - 48| 1.51k| if (len == 0) + 48| 16.2k| if (len == 0) ------------------ - | Branch (48:6): [True: 113, False: 1.40k] + | Branch (48:6): [True: 988, False: 15.2k] ------------------ - 49| 113| return (buf); + 49| 988| return (buf); 50| | - 51| 1.40k| if (data == NULL) { + 51| 15.2k| if (data == NULL) { ------------------ - | Branch (51:6): [True: 0, False: 1.40k] + | Branch (51:6): [True: 0, False: 15.2k] ------------------ 52| 0| if (ibuf_add_zero(buf, len) != 0) { ------------------ @@ -2924,31 +2924,31 @@ ibuf_new: 53| 0| ibuf_free(buf); 54| 0| return (NULL); 55| 0| } - 56| 1.40k| } else { - 57| 1.40k| if (ibuf_add(buf, data, len) != 0) { + 56| 15.2k| } else { + 57| 15.2k| if (ibuf_add(buf, data, len) != 0) { ------------------ - | Branch (57:7): [True: 0, False: 1.40k] + | Branch (57:7): [True: 0, False: 15.2k] ------------------ 58| 0| ibuf_free(buf); 59| 0| return (NULL); 60| 0| } - 61| 1.40k| } + 61| 15.2k| } 62| | - 63| 1.40k| return (buf); - 64| 1.40k|} + 63| 15.2k| return (buf); + 64| 15.2k|} log_getverbose: - 82| 9.34k|{ - 83| 9.34k| return (verbose); - 84| 9.34k|} + 82| 119k|{ + 83| 119k| return (verbose); + 84| 119k|} vlog: - 98| 1.97k|{ - 99| 1.97k| char *nfmt; - 100| 1.97k| int saved_errno = errno; + 98| 10.2k|{ + 99| 10.2k| char *nfmt; + 100| 10.2k| int saved_errno = errno; 101| | - 102| 1.97k| if (debug) { + 102| 10.2k| if (debug) { ------------------ - | Branch (102:6): [True: 0, False: 1.97k] + | Branch (102:6): [True: 0, False: 10.2k] ------------------ 103| | /* best effort in out of mem situations */ 104| 0| if (asprintf(&nfmt, "%s\n", fmt) == -1) { @@ -2963,147 +2963,147 @@ vlog: 110| 0| } 111| 0| fflush(stderr); 112| 0| } else - 113| 1.97k| vsyslog(pri, fmt, ap); + 113| 10.2k| vsyslog(pri, fmt, ap); 114| | - 115| 1.97k| errno = saved_errno; - 116| 1.97k|} + 115| 10.2k| errno = saved_errno; + 116| 10.2k|} log_info: - 158| 1.97k|{ - 159| 1.97k| va_list ap; + 158| 10.2k|{ + 159| 10.2k| va_list ap; 160| | - 161| 1.97k| va_start(ap, emsg); - 162| 1.97k| vlog(LOG_INFO, emsg, ap); - 163| 1.97k| va_end(ap); - 164| 1.97k|} + 161| 10.2k| va_start(ap, emsg); + 162| 10.2k| vlog(LOG_INFO, emsg, ap); + 163| 10.2k| va_end(ap); + 164| 10.2k|} log_debug: - 168| 50.0k|{ - 169| 50.0k| va_list ap; + 168| 468k|{ + 169| 468k| va_list ap; 170| | - 171| 50.0k| if (verbose > 1) { + 171| 468k| if (verbose > 1) { ------------------ - | Branch (171:6): [True: 0, False: 50.0k] + | Branch (171:6): [True: 0, False: 468k] ------------------ 172| 0| va_start(ap, emsg); 173| 0| vlog(LOG_DEBUG, emsg, ap); 174| 0| va_end(ap); 175| 0| } - 176| 50.0k|} + 176| 468k|} socket_getport: - 71| 562|{ - 72| 562| switch (sa->sa_family) { - 73| 438| case AF_INET: + 71| 10.8k|{ + 72| 10.8k| switch (sa->sa_family) { + 73| 9.00k| case AF_INET: ------------------ - | Branch (73:2): [True: 438, False: 124] + | Branch (73:2): [True: 9.00k, False: 1.82k] ------------------ - 74| 438| return (ntohs(((struct sockaddr_in *)sa)->sin_port)); - 75| 124| case AF_INET6: + 74| 9.00k| return (ntohs(((struct sockaddr_in *)sa)->sin_port)); + 75| 1.82k| case AF_INET6: ------------------ - | Branch (75:2): [True: 124, False: 438] + | Branch (75:2): [True: 1.82k, False: 9.00k] ------------------ - 76| 124| return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); + 76| 1.82k| return (ntohs(((struct sockaddr_in6 *)sa)->sin6_port)); 77| 0| default: ------------------ - | Branch (77:2): [True: 0, False: 562] + | Branch (77:2): [True: 0, False: 10.8k] ------------------ 78| 0| return (0); - 79| 562| } + 79| 10.8k| } 80| | 81| | /* NOTREACHED */ 82| 0| return (0); - 83| 562|} + 83| 10.8k|} print_spi: - 499| 3.79k|{ - 500| 3.79k| static char buf[IKED_CYCLE_BUFFERS][32]; - 501| 3.79k| static int i = 0; - 502| 3.79k| char *ptr; + 499| 29.3k|{ + 500| 29.3k| static char buf[IKED_CYCLE_BUFFERS][32]; + 501| 29.3k| static int i = 0; + 502| 29.3k| char *ptr; 503| | - 504| 3.79k| ptr = buf[i]; + 504| 29.3k| ptr = buf[i]; 505| | - 506| 3.79k| switch (size) { + 506| 29.3k| switch (size) { 507| 0| case 2: ------------------ - | Branch (507:2): [True: 0, False: 3.79k] + | Branch (507:2): [True: 0, False: 29.3k] ------------------ 508| 0| snprintf(ptr, 32, "0x%04x", (uint16_t)spi); 509| 0| break; - 510| 93| case 4: + 510| 334| case 4: ------------------ - | Branch (510:2): [True: 93, False: 3.70k] + | Branch (510:2): [True: 334, False: 29.0k] ------------------ - 511| 93| snprintf(ptr, 32, "0x%08x", (uint32_t)spi); - 512| 93| break; - 513| 1.53k| case 8: + 511| 334| snprintf(ptr, 32, "0x%08x", (uint32_t)spi); + 512| 334| break; + 513| 20.3k| case 8: ------------------ - | Branch (513:2): [True: 1.53k, False: 2.26k] + | Branch (513:2): [True: 20.3k, False: 9.03k] ------------------ - 514| 1.53k| snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi); - 515| 1.53k| break; - 516| 2.16k| default: + 514| 20.3k| snprintf(ptr, 32, "0x%016llx", (long long unsigned)spi); + 515| 20.3k| break; + 516| 8.69k| default: ------------------ - | Branch (516:2): [True: 2.16k, False: 1.62k] + | Branch (516:2): [True: 8.69k, False: 20.6k] ------------------ - 517| 2.16k| snprintf(ptr, 32, "%llu", (long long unsigned)spi); - 518| 2.16k| break; - 519| 3.79k| } + 517| 8.69k| snprintf(ptr, 32, "%llu", (long long unsigned)spi); + 518| 8.69k| break; + 519| 29.3k| } 520| | - 521| 3.79k| if (++i >= IKED_CYCLE_BUFFERS) + 521| 29.3k| if (++i >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 3.79k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 29.3k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (521:6): [True: 474, False: 3.32k] + | Branch (521:6): [True: 3.66k, False: 25.6k] ------------------ - 522| 474| i = 0; + 522| 3.66k| i = 0; 523| | - 524| 3.79k| return (ptr); - 525| 3.79k|} + 524| 29.3k| return (ptr); + 525| 29.3k|} print_map: - 529| 61.0k|{ - 530| 61.0k| unsigned int i; - 531| 61.0k| static char buf[IKED_CYCLE_BUFFERS][32]; - 532| 61.0k| static int idx = 0; - 533| 61.0k| const char *name = NULL; + 529| 574k|{ + 530| 574k| unsigned int i; + 531| 574k| static char buf[IKED_CYCLE_BUFFERS][32]; + 532| 574k| static int idx = 0; + 533| 574k| const char *name = NULL; 534| | - 535| 61.0k| if (idx >= IKED_CYCLE_BUFFERS) + 535| 574k| if (idx >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 61.0k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 574k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (535:6): [True: 7.63k, False: 53.4k] + | Branch (535:6): [True: 71.7k, False: 502k] ------------------ - 536| 7.63k| idx = 0; - 537| 61.0k| bzero(buf[idx], sizeof(buf[idx])); + 536| 71.7k| idx = 0; + 537| 574k| bzero(buf[idx], sizeof(buf[idx])); 538| | - 539| 1.10M| for (i = 0; map[i].cm_name != NULL; i++) { + 539| 11.7M| for (i = 0; map[i].cm_name != NULL; i++) { ------------------ - | Branch (539:14): [True: 1.04M, False: 61.0k] + | Branch (539:14): [True: 11.2M, False: 574k] ------------------ - 540| 1.04M| if (map[i].cm_type == type) + 540| 11.2M| if (map[i].cm_type == type) ------------------ - | Branch (540:7): [True: 45.3k, False: 1.00M] + | Branch (540:7): [True: 401k, False: 10.7M] ------------------ - 541| 45.3k| name = map[i].cm_name; - 542| 1.04M| } + 541| 401k| name = map[i].cm_name; + 542| 11.2M| } 543| | - 544| 61.0k| if (name == NULL) + 544| 574k| if (name == NULL) ------------------ - | Branch (544:6): [True: 15.6k, False: 45.3k] + | Branch (544:6): [True: 172k, False: 401k] ------------------ - 545| 15.6k| snprintf(buf[idx], sizeof(buf[idx]), "", type); - 546| 45.3k| else - 547| 45.3k| strlcpy(buf[idx], name, sizeof(buf[idx])); + 545| 172k| snprintf(buf[idx], sizeof(buf[idx]), "", type); + 546| 401k| else + 547| 401k| strlcpy(buf[idx], name, sizeof(buf[idx])); 548| | - 549| 61.0k| return (buf[idx++]); - 550| 61.0k|} + 549| 574k| return (buf[idx++]); + 550| 574k|} print_hex: - 561| 9.34k|{ - 562| 9.34k| unsigned int i; + 561| 119k|{ + 562| 119k| unsigned int i; 563| | - 564| 9.34k| if (log_getverbose() < 3 || !length) + 564| 119k| if (log_getverbose() < 3 || !length) ------------------ - | Branch (564:6): [True: 9.34k, False: 0] + | Branch (564:6): [True: 119k, False: 0] | Branch (564:30): [True: 0, False: 0] ------------------ - 565| 9.34k| return; + 565| 119k| return; 566| | 567| 0| for (i = 0; i < length; i++) { ------------------ @@ -3127,100 +3127,100 @@ print_hex: 576| 0| print_debug("\n"); 577| 0|} print_addr: - 737| 562|{ - 738| 562| static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7]; - 739| 562| static int idx; - 740| 562| struct sockaddr *sa = addr; - 741| 562| char *buf; - 742| 562| size_t len; - 743| 562| char pbuf[7]; - 744| 562| in_port_t port; + 737| 10.8k|{ + 738| 10.8k| static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7]; + 739| 10.8k| static int idx; + 740| 10.8k| struct sockaddr *sa = addr; + 741| 10.8k| char *buf; + 742| 10.8k| size_t len; + 743| 10.8k| char pbuf[7]; + 744| 10.8k| in_port_t port; 745| | - 746| 562| buf = sbuf[idx]; - 747| 562| len = sizeof(sbuf[idx]); - 748| 562| if (++idx >= IKED_CYCLE_BUFFERS) + 746| 10.8k| buf = sbuf[idx]; + 747| 10.8k| len = sizeof(sbuf[idx]); + 748| 10.8k| if (++idx >= IKED_CYCLE_BUFFERS) ------------------ - | | 70| 562|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ + | | 70| 10.8k|#define IKED_CYCLE_BUFFERS 8 /* # of static buffers for mapping */ ------------------ - | Branch (748:6): [True: 70, False: 492] + | Branch (748:6): [True: 1.35k, False: 9.47k] ------------------ - 749| 70| idx = 0; + 749| 1.35k| idx = 0; 750| | - 751| 562| if (sa->sa_family == AF_UNSPEC) { + 751| 10.8k| if (sa->sa_family == AF_UNSPEC) { ------------------ - | Branch (751:6): [True: 0, False: 562] + | Branch (751:6): [True: 0, False: 10.8k] ------------------ 752| 0| strlcpy(buf, "any", len); 753| 0| return (buf); 754| 0| } 755| | - 756| 562| if (getnameinfo(sa, SA_LEN(sa), + 756| 10.8k| if (getnameinfo(sa, SA_LEN(sa), ------------------ - | | 113| 562| ((sa->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \ + | | 113| 10.8k| ((sa->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : \ | | ------------------ - | | | Branch (113:3): [True: 438, False: 124] + | | | Branch (113:3): [True: 9.00k, False: 1.82k] | | ------------------ - | | 114| 562| (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : \ + | | 114| 10.8k| (sa->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : \ | | ------------------ - | | | Branch (114:2): [True: 124, False: 0] + | | | Branch (114:2): [True: 1.82k, False: 0] | | ------------------ - | | 115| 124| sizeof(struct sockaddr)) + | | 115| 1.82k| sizeof(struct sockaddr)) ------------------ - | Branch (756:6): [True: 0, False: 562] + | Branch (756:6): [True: 0, False: 10.8k] ------------------ - 757| 562| buf, len, NULL, 0, NI_NUMERICHOST) != 0) { + 757| 10.8k| buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 758| 0| strlcpy(buf, "unknown", len); 759| 0| return (buf); 760| 0| } 761| | - 762| 562| if ((port = socket_getport(sa)) != 0) { + 762| 10.8k| if ((port = socket_getport(sa)) != 0) { ------------------ - | Branch (762:6): [True: 0, False: 562] + | Branch (762:6): [True: 0, False: 10.8k] ------------------ 763| 0| snprintf(pbuf, sizeof(pbuf), ":%d", port); 764| 0| (void)strlcat(buf, pbuf, len); 765| 0| } 766| | - 767| 562| return (buf); - 768| 562|} + 767| 10.8k| return (buf); + 768| 10.8k|} eap_parse: - 60| 737|{ - 61| 737| return (0); - 62| 737|} + 60| 3.10k|{ + 61| 3.10k| return (0); + 62| 3.10k|} ikev2_msg_frompeer: - 67| 19.5k|{ - 68| 19.5k| struct iked_sa *sa = msg->msg_sa; - 69| 19.5k| struct ike_header *hdr; + 67| 171k|{ + 68| 171k| struct iked_sa *sa = msg->msg_sa; + 69| 171k| struct ike_header *hdr; 70| | - 71| 19.5k| msg = msg->msg_parent; + 71| 171k| msg = msg->msg_parent; 72| | - 73| 19.5k| if (sa == NULL || + 73| 171k| if (sa == NULL || ------------------ - | Branch (73:6): [True: 0, False: 19.5k] + | Branch (73:6): [True: 0, False: 171k] ------------------ - 74| 19.5k| (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL) + 74| 171k| (hdr = ibuf_seek(msg->msg_data, 0, sizeof(*hdr))) == NULL) ------------------ - | Branch (74:6): [True: 0, False: 19.5k] + | Branch (74:6): [True: 0, False: 171k] ------------------ 75| 0| return (0); 76| | - 77| 19.5k| if (!sa->sa_hdr.sh_initiator && + 77| 171k| if (!sa->sa_hdr.sh_initiator && ------------------ - | Branch (77:6): [True: 19.5k, False: 0] + | Branch (77:6): [True: 171k, False: 0] ------------------ - 78| 19.5k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR)) + 78| 171k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR)) ------------------ - | | 19| 19.5k|#define IKEV2_FLAG_INITIATOR 0x08 /* Sent by the initiator */ + | | 19| 171k|#define IKEV2_FLAG_INITIATOR 0x08 /* Sent by the initiator */ ------------------ - | Branch (78:6): [True: 999, False: 18.5k] + | Branch (78:6): [True: 40.9k, False: 130k] ------------------ - 79| 999| return (1); - 80| 18.5k| else if (sa->sa_hdr.sh_initiator && + 79| 40.9k| return (1); + 80| 130k| else if (sa->sa_hdr.sh_initiator && ------------------ - | Branch (80:11): [True: 0, False: 18.5k] + | Branch (80:11): [True: 0, False: 130k] ------------------ - 81| 18.5k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0) + 81| 130k| (hdr->ike_flags & IKEV2_FLAG_INITIATOR) == 0) ------------------ | | 19| 0|#define IKEV2_FLAG_INITIATOR 0x08 /* Sent by the initiator */ ------------------ @@ -3228,84 +3228,84 @@ ikev2_msg_frompeer: ------------------ 82| 0| return (1); 83| | - 84| 18.5k| return (0); - 85| 19.5k|} + 84| 130k| return (0); + 85| 171k|} ikev2_ikesa_info: - 101| 1.70k|{ - 102| 1.70k| return ""; - 103| 1.70k|} + 101| 7.42k|{ + 102| 7.42k| return ""; + 103| 7.42k|} sa_stateok: - 120| 12|{ - 121| 12| return (0); - 122| 12|} + 120| 141|{ + 121| 141| return (0); + 122| 141|} ikev2_nat_detection: - 164| 48|{ - 165| 48| return (0); - 166| 48|} + 164| 15.9k|{ + 165| 15.9k| return (0); + 166| 15.9k|} ikev2_print_id: - 178| 658|{ - 179| 658| return (0); - 180| 658|} + 178| 4.75k|{ + 179| 4.75k| return (0); + 180| 4.75k|} config_add_proposal: - 191| 3|{ - 192| 3| return (NULL); - 193| 3|} + 191| 69|{ + 192| 69| return (NULL); + 193| 69|} ikev2_send_informational: - 208| 70|{ - 209| 70| return (0); - 210| 70|} + 208| 706|{ + 209| 706| return (0); + 210| 706|} ikev2_msg_cleanup: - 250| 717|{ - 251| 717| struct iked_certreq *cr; - 252| 717| struct iked_proposal *prop, *proptmp; - 253| 717| int i; + 250| 10.0k|{ + 251| 10.0k| struct iked_certreq *cr; + 252| 10.0k| struct iked_proposal *prop, *proptmp; + 253| 10.0k| int i; 254| | - 255| 717| if (msg == msg->msg_parent) { - ------------------ - | Branch (255:6): [True: 717, False: 0] - ------------------ - 256| 717| ibuf_free(msg->msg_nonce); - 257| 717| ibuf_free(msg->msg_ke); - 258| 717| ibuf_free(msg->msg_auth.id_buf); - 259| 717| ibuf_free(msg->msg_peerid.id_buf); - 260| 717| ibuf_free(msg->msg_localid.id_buf); - 261| 717| ibuf_free(msg->msg_cert.id_buf); - 262| 2.86k| for (i = 0; i < IKED_SCERT_MAX; i++) - ------------------ - | | 477| 2.86k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ - ------------------ - | Branch (262:15): [True: 2.15k, False: 717] - ------------------ - 263| 2.15k| ibuf_free(msg->msg_scert[i].id_buf); - 264| 717| ibuf_free(msg->msg_cookie); - 265| 717| ibuf_free(msg->msg_cookie2); - 266| 717| ibuf_free(msg->msg_del_buf); - 267| 717| free(msg->msg_eap.eam_user); - 268| 717| free(msg->msg_cp_addr); - 269| 717| free(msg->msg_cp_addr6); - 270| 717| free(msg->msg_cp_dns); + 255| 10.0k| if (msg == msg->msg_parent) { + ------------------ + | Branch (255:6): [True: 10.0k, False: 0] + ------------------ + 256| 10.0k| ibuf_free(msg->msg_nonce); + 257| 10.0k| ibuf_free(msg->msg_ke); + 258| 10.0k| ibuf_free(msg->msg_auth.id_buf); + 259| 10.0k| ibuf_free(msg->msg_peerid.id_buf); + 260| 10.0k| ibuf_free(msg->msg_localid.id_buf); + 261| 10.0k| ibuf_free(msg->msg_cert.id_buf); + 262| 40.2k| for (i = 0; i < IKED_SCERT_MAX; i++) + ------------------ + | | 477| 40.2k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ + ------------------ + | Branch (262:15): [True: 30.1k, False: 10.0k] + ------------------ + 263| 30.1k| ibuf_free(msg->msg_scert[i].id_buf); + 264| 10.0k| ibuf_free(msg->msg_cookie); + 265| 10.0k| ibuf_free(msg->msg_cookie2); + 266| 10.0k| ibuf_free(msg->msg_del_buf); + 267| 10.0k| free(msg->msg_eap.eam_user); + 268| 10.0k| free(msg->msg_cp_addr); + 269| 10.0k| free(msg->msg_cp_addr6); + 270| 10.0k| free(msg->msg_cp_dns); 271| | - 272| 717| TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry, + 272| 10.0k| TAILQ_FOREACH_SAFE(prop, &msg->msg_proposals, prop_entry, ------------------ - | | 445| 717| for ((var) = TAILQ_FIRST(head); \ + | | 445| 10.0k| for ((var) = TAILQ_FIRST(head); \ | | ------------------ - | | | | 428| 717|#define TAILQ_FIRST(head) ((head)->tqh_first) + | | | | 428| 10.0k|#define TAILQ_FIRST(head) ((head)->tqh_first) | | ------------------ - | | 446| 717| (var) != TAILQ_END(head) && \ + | | 446| 10.0k| (var) != TAILQ_END(head) && \ | | ------------------ - | | | | 429| 1.43k|#define TAILQ_END(head) NULL + | | | | 429| 20.1k|#define TAILQ_END(head) NULL | | ------------------ - | | | Branch (446:6): [True: 0, False: 717] + | | | Branch (446:6): [True: 0, False: 10.0k] | | ------------------ - | | 447| 717| ((tvar) = TAILQ_NEXT(var, field), 1); \ + | | 447| 10.0k| ((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| 717| (var) = (tvar)) + | | 448| 10.0k| (var) = (tvar)) ------------------ - 273| 717| proptmp) { + 273| 10.0k| proptmp) { 274| 0| TAILQ_REMOVE(&msg->msg_proposals, prop, prop_entry); ------------------ | | 504| 0|#define TAILQ_REMOVE(head, elm, field) do { \ @@ -3333,73 +3333,73 @@ ikev2_msg_cleanup: 277| 0| free(prop); 278| 0| } 279| | - 280| 717| msg->msg_nonce = NULL; - 281| 717| msg->msg_ke = NULL; - 282| 717| msg->msg_auth.id_buf = NULL; - 283| 717| msg->msg_peerid.id_buf = NULL; - 284| 717| msg->msg_localid.id_buf = NULL; - 285| 717| msg->msg_cert.id_buf = NULL; - 286| 2.86k| for (i = 0; i < IKED_SCERT_MAX; i++) - ------------------ - | | 477| 2.86k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ - ------------------ - | Branch (286:15): [True: 2.15k, False: 717] - ------------------ - 287| 2.15k| msg->msg_scert[i].id_buf = NULL; - 288| 717| msg->msg_cookie = NULL; - 289| 717| msg->msg_cookie2 = NULL; - 290| 717| msg->msg_del_buf = NULL; - 291| 717| msg->msg_eap.eam_user = NULL; - 292| 717| msg->msg_cp_addr = NULL; - 293| 717| msg->msg_cp_addr6 = NULL; - 294| 717| msg->msg_cp_dns = NULL; + 280| 10.0k| msg->msg_nonce = NULL; + 281| 10.0k| msg->msg_ke = NULL; + 282| 10.0k| msg->msg_auth.id_buf = NULL; + 283| 10.0k| msg->msg_peerid.id_buf = NULL; + 284| 10.0k| msg->msg_localid.id_buf = NULL; + 285| 10.0k| msg->msg_cert.id_buf = NULL; + 286| 40.2k| for (i = 0; i < IKED_SCERT_MAX; i++) + ------------------ + | | 477| 40.2k|#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */ + ------------------ + | Branch (286:15): [True: 30.1k, False: 10.0k] + ------------------ + 287| 30.1k| msg->msg_scert[i].id_buf = NULL; + 288| 10.0k| msg->msg_cookie = NULL; + 289| 10.0k| msg->msg_cookie2 = NULL; + 290| 10.0k| msg->msg_del_buf = NULL; + 291| 10.0k| msg->msg_eap.eam_user = NULL; + 292| 10.0k| msg->msg_cp_addr = NULL; + 293| 10.0k| msg->msg_cp_addr6 = NULL; + 294| 10.0k| msg->msg_cp_dns = NULL; 295| | - 296| 802| while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) { + 296| 10.5k| while ((cr = SIMPLEQ_FIRST(&msg->msg_certreqs))) { ------------------ - | | 267| 802|#define SIMPLEQ_FIRST(head) ((head)->sqh_first) + | | 267| 10.5k|#define SIMPLEQ_FIRST(head) ((head)->sqh_first) ------------------ - | Branch (296:10): [True: 85, False: 717] + | Branch (296:10): [True: 526, False: 10.0k] ------------------ - 297| 85| ibuf_free(cr->cr_data); - 298| 85| SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry); + 297| 526| ibuf_free(cr->cr_data); + 298| 526| SIMPLEQ_REMOVE_HEAD(&msg->msg_certreqs, cr_entry); ------------------ - | | 308| 85|#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - | | 309| 85| if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + | | 308| 526|#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + | | 309| 526| if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ | | ------------------ - | | | Branch (309:6): [True: 14, False: 71] + | | | Branch (309:6): [True: 92, False: 434] | | ------------------ - | | 310| 85| (head)->sqh_last = &(head)->sqh_first; \ - | | 311| 85|} while (0) + | | 310| 526| (head)->sqh_last = &(head)->sqh_first; \ + | | 311| 526|} while (0) | | ------------------ | | | Branch (311:10): [Folded - Ignored] | | ------------------ ------------------ - 299| 85| free(cr); - 300| 85| } - 301| 717| } + 299| 526| free(cr); + 300| 526| } + 301| 10.0k| } 302| | - 303| 717| if (msg->msg_data != NULL) { + 303| 10.0k| if (msg->msg_data != NULL) { ------------------ - | Branch (303:6): [True: 717, False: 0] + | Branch (303:6): [True: 10.0k, False: 0] ------------------ - 304| 717| ibuf_free(msg->msg_data); - 305| 717| msg->msg_data = NULL; - 306| 717| } - 307| 717|} + 304| 10.0k| ibuf_free(msg->msg_data); + 305| 10.0k| msg->msg_data = NULL; + 306| 10.0k| } + 307| 10.0k|} LLVMFuzzerTestOneInput: - 107| 718|{ - 108| 718| struct ibuf *fuzzed; - 109| 718| struct ike_header hdr; - 110| 718| struct iked_message msg; + 107| 10.0k|{ + 108| 10.0k| struct ibuf *fuzzed; + 109| 10.0k| struct ike_header hdr; + 110| 10.0k| struct iked_message msg; 111| | - 112| 718| bzero(&hdr, sizeof(hdr)); - 113| 718| bzero(&msg, sizeof(msg)); + 112| 10.0k| bzero(&hdr, sizeof(hdr)); + 113| 10.0k| bzero(&msg, sizeof(msg)); 114| | - 115| 718| fuzzed = ibuf_new(data, size); - 116| 718| if (fuzzed == NULL){ + 115| 10.0k| fuzzed = ibuf_new(data, size); + 116| 10.0k| if (fuzzed == NULL){ ------------------ - | Branch (116:6): [True: 0, False: 718] + | Branch (116:6): [True: 0, False: 10.0k] ------------------ 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| 718| if (size < sizeof(cookies) + sizeof(genhdr)){ + 123| 10.0k| if (size < sizeof(cookies) + sizeof(genhdr)){ ------------------ - | Branch (123:6): [True: 1, False: 717] + | Branch (123:6): [True: 1, False: 10.0k] ------------------ 124| 1| ibuf_free(fuzzed); 125| 1| return 0; 126| 1| } 127| | - 128| 717| prepare_header(&hdr, fuzzed); - 129| 717| prepare_message(&msg, fuzzed); + 128| 10.0k| prepare_header(&hdr, fuzzed); + 129| 10.0k| prepare_message(&msg, fuzzed); 130| | - 131| 717| ikev2_pld_parse(NULL, &hdr, &msg, 0); + 131| 10.0k| ikev2_pld_parse(NULL, &hdr, &msg, 0); 132| | - 133| 717| ikev2_msg_cleanup(NULL, &msg); + 133| 10.0k| ikev2_msg_cleanup(NULL, &msg); 134| | - 135| 717| return 0; - 136| 718|} + 135| 10.0k| return 0; + 136| 10.0k|} test_parser_fuzz.c:prepare_header: - 75| 717|{ - 76| 717| bzero(hdr, sizeof(*hdr)); - 77| 717| bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi, - 78| 717| sizeof(hdr->ike_ispi)); - 79| 717| bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi, - 80| 717| sizeof(hdr->ike_rspi)); - 81| 717| hdr->ike_nextpayload = get_nextpayload(ibuf_data(data)); - 82| 717| hdr->ike_version = get_version(ibuf_data(data)); - 83| 717| hdr->ike_exchange = get_exchange(ibuf_data(data)); - 84| 717| hdr->ike_length = get_length(ibuf_data(data)); - 85| 717|} + 75| 10.0k|{ + 76| 10.0k| bzero(hdr, sizeof(*hdr)); + 77| 10.0k| bcopy(get_icookie(ibuf_data(data)), &hdr->ike_ispi, + 78| 10.0k| sizeof(hdr->ike_ispi)); + 79| 10.0k| bcopy(get_rcookie(ibuf_data(data)), &hdr->ike_rspi, + 80| 10.0k| sizeof(hdr->ike_rspi)); + 81| 10.0k| hdr->ike_nextpayload = get_nextpayload(ibuf_data(data)); + 82| 10.0k| hdr->ike_version = get_version(ibuf_data(data)); + 83| 10.0k| hdr->ike_exchange = get_exchange(ibuf_data(data)); + 84| 10.0k| hdr->ike_length = get_length(ibuf_data(data)); + 85| 10.0k|} test_parser_fuzz.c:get_icookie: - 39| 717|{ - 40| 717| return &data[OFFSET_ICOOKIE]; + 39| 10.0k|{ + 40| 10.0k| return &data[OFFSET_ICOOKIE]; ------------------ - | | 30| 717|#define OFFSET_ICOOKIE 0 + | | 30| 10.0k|#define OFFSET_ICOOKIE 0 ------------------ - 41| 717|} + 41| 10.0k|} test_parser_fuzz.c:get_rcookie: - 45| 717|{ - 46| 717| return &data[OFFSET_RCOOKIE]; + 45| 10.0k|{ + 46| 10.0k| return &data[OFFSET_RCOOKIE]; ------------------ - | | 31| 717|#define OFFSET_RCOOKIE 8 + | | 31| 10.0k|#define OFFSET_RCOOKIE 8 ------------------ - 47| 717|} + 47| 10.0k|} test_parser_fuzz.c:get_nextpayload: - 51| 717|{ - 52| 717| return data[OFFSET_NEXTPAYLOAD]; + 51| 10.0k|{ + 52| 10.0k| return data[OFFSET_NEXTPAYLOAD]; ------------------ - | | 32| 717|#define OFFSET_NEXTPAYLOAD (0 + sizeof(cookies)) + | | 32| 10.0k|#define OFFSET_NEXTPAYLOAD (0 + sizeof(cookies)) ------------------ - 53| 717|} + 53| 10.0k|} test_parser_fuzz.c:get_version: - 57| 717|{ - 58| 717| return data[OFFSET_VERSION]; + 57| 10.0k|{ + 58| 10.0k| return data[OFFSET_VERSION]; ------------------ - | | 33| 717|#define OFFSET_VERSION (1 + sizeof(cookies)) + | | 33| 10.0k|#define OFFSET_VERSION (1 + sizeof(cookies)) ------------------ - 59| 717|} + 59| 10.0k|} test_parser_fuzz.c:get_exchange: - 63| 717|{ - 64| 717| return data[OFFSET_EXCHANGE]; + 63| 10.0k|{ + 64| 10.0k| return data[OFFSET_EXCHANGE]; ------------------ - | | 34| 717|#define OFFSET_EXCHANGE (2 + sizeof(cookies)) + | | 34| 10.0k|#define OFFSET_EXCHANGE (2 + sizeof(cookies)) ------------------ - 65| 717|} + 65| 10.0k|} test_parser_fuzz.c:get_length: - 69| 717|{ - 70| 717| return *(u_int32_t *)&data[OFFSET_LENGTH]; + 69| 10.0k|{ + 70| 10.0k| return *(u_int32_t *)&data[OFFSET_LENGTH]; ------------------ - | | 35| 717|#define OFFSET_LENGTH (8 + sizeof(cookies)) + | | 35| 10.0k|#define OFFSET_LENGTH (8 + sizeof(cookies)) ------------------ - 71| 717|} + 71| 10.0k|} test_parser_fuzz.c:prepare_message: - 89| 717|{ - 90| 717| static struct iked_sa sa; + 89| 10.0k|{ + 90| 10.0k| static struct iked_sa sa; 91| | - 92| 717| bzero(&sa, sizeof(sa)); - 93| 717| bzero(msg, sizeof(*msg)); + 92| 10.0k| bzero(&sa, sizeof(sa)); + 93| 10.0k| bzero(msg, sizeof(*msg)); 94| | - 95| 717| msg->msg_sa = &sa; - 96| 717| msg->msg_data = data; - 97| 717| msg->msg_e = 1; - 98| 717| msg->msg_parent = msg; + 95| 10.0k| msg->msg_sa = &sa; + 96| 10.0k| msg->msg_data = data; + 97| 10.0k| msg->msg_e = 1; + 98| 10.0k| msg->msg_parent = msg; 99| | - 100| 717| TAILQ_INIT(&msg->msg_proposals); + 100| 10.0k| TAILQ_INIT(&msg->msg_proposals); ------------------ - | | 465| 717|#define TAILQ_INIT(head) do { \ - | | 466| 717| (head)->tqh_first = NULL; \ - | | 467| 717| (head)->tqh_last = &(head)->tqh_first; \ - | | 468| 717|} while (0) + | | 465| 10.0k|#define TAILQ_INIT(head) do { \ + | | 466| 10.0k| (head)->tqh_first = NULL; \ + | | 467| 10.0k| (head)->tqh_last = &(head)->tqh_first; \ + | | 468| 10.0k|} while (0) | | ------------------ | | | Branch (468:10): [Folded - Ignored] | | ------------------ ------------------ - 101| 717| SIMPLEQ_INIT(&msg->msg_certreqs); + 101| 10.0k| SIMPLEQ_INIT(&msg->msg_certreqs); ------------------ - | | 285| 717|#define SIMPLEQ_INIT(head) do { \ - | | 286| 717| (head)->sqh_first = NULL; \ - | | 287| 717| (head)->sqh_last = &(head)->sqh_first; \ - | | 288| 717|} while (0) + | | 285| 10.0k|#define SIMPLEQ_INIT(head) do { \ + | | 286| 10.0k| (head)->sqh_first = NULL; \ + | | 287| 10.0k| (head)->sqh_last = &(head)->sqh_first; \ + | | 288| 10.0k|} while (0) | | ------------------ | | | Branch (288:10): [Folded - Ignored] | | ------------------ ------------------ - 102| 717|} + 102| 10.0k|}