Coverage Report

Created: 2026-01-09 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/radvd/recv.c
Line
Count
Source
1
/*
2
 *
3
 *   Authors:
4
 *    Pedro Roque   <roque@di.fc.ul.pt>
5
 *    Lars Fenneberg    <lf@elemental.net>
6
 *
7
 *   This software is Copyright 1996,1997 by the above mentioned author(s),
8
 *   All Rights Reserved.
9
 *
10
 *   The license which is distributed with this software in the file COPYRIGHT
11
 *   applies to this software. If your distribution is missing this file, you
12
 *   may request it from <reubenhwk@gmail.com>.
13
 *
14
 */
15
16
#include "config.h"
17
#include "includes.h"
18
#include "radvd.h"
19
20
int recv_rs_ra(int sock, unsigned char *msg, struct sockaddr_in6 *addr, struct in6_pktinfo **pkt_info, int *hoplimit,
21
         unsigned char *chdr)
22
0
{
23
0
  struct iovec iov;
24
0
  iov.iov_len = MSG_SIZE_RECV;
25
0
  iov.iov_base = (caddr_t)msg;
26
27
0
  struct msghdr mhdr;
28
0
  memset(&mhdr, 0, sizeof(mhdr));
29
0
  mhdr.msg_name = (caddr_t)addr;
30
0
  mhdr.msg_namelen = sizeof(*addr);
31
0
  mhdr.msg_iov = &iov;
32
0
  mhdr.msg_iovlen = 1;
33
0
  mhdr.msg_control = (void *)chdr;
34
0
  mhdr.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int));
35
36
0
  int len = recvmsg(sock, &mhdr, 0);
37
38
0
  if (len < 0) {
39
0
    if (errno != EINTR)
40
0
      flog(LOG_ERR, "recvmsg: %s", strerror(errno));
41
42
0
    return len;
43
0
  }
44
45
0
  *hoplimit = 255;
46
47
0
  for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mhdr); cmsg != NULL; cmsg = CMSG_NXTHDR(&mhdr, cmsg)) {
48
0
    if (cmsg->cmsg_level != IPPROTO_IPV6)
49
0
      continue;
50
51
0
    switch (cmsg->cmsg_type) {
52
0
#ifdef IPV6_HOPLIMIT
53
0
    case IPV6_HOPLIMIT:
54
0
      if ((cmsg->cmsg_len == CMSG_LEN(sizeof(int))) && (*(int *)CMSG_DATA(cmsg) >= 0) &&
55
0
          (*(int *)CMSG_DATA(cmsg) < 256)) {
56
0
        *hoplimit = *(int *)CMSG_DATA(cmsg);
57
0
      } else {
58
0
        flog(LOG_ERR, "received a bogus IPV6_HOPLIMIT from the kernel! len=%d, data=%d",
59
0
             (int)cmsg->cmsg_len, *(int *)CMSG_DATA(cmsg));
60
0
        return -1;
61
0
      }
62
0
      break;
63
0
#endif /* IPV6_HOPLIMIT */
64
0
    case IPV6_PKTINFO:
65
0
      if ((cmsg->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) &&
66
0
          ((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_ifindex) {
67
0
        *pkt_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
68
0
      } else {
69
0
        flog(LOG_ERR, "received a bogus IPV6_PKTINFO from the kernel! len=%d, index=%d",
70
0
             (int)cmsg->cmsg_len, ((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_ifindex);
71
0
        return -1;
72
0
      }
73
0
      break;
74
0
    }
75
0
  }
76
77
0
  char if_namebuf[IF_NAMESIZE] = {""};
78
0
  char *if_name = 0;
79
0
  if (pkt_info && *pkt_info) {
80
0
    if_name = if_indextoname((*pkt_info)->ipi6_ifindex, if_namebuf);
81
0
  }
82
0
  if (!if_name) {
83
0
    if_name = "unknown interface";
84
0
  }
85
0
  dlog(LOG_DEBUG, 5, "%s recvmsg len=%d", if_name, len);
86
87
0
  return len;
88
0
}