Coverage Report

Created: 2024-05-20 01:00

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