1 /* Check recvmsg results for netlink sockets.
2 Copyright (C) 2015-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
22 #include <sys/socket.h>
24 #include "netlinkaccess.h"
27 get_address_family (int fd
)
29 struct sockaddr_storage sa
;
30 socklen_t sa_len
= sizeof (sa
);
31 if (__getsockname (fd
, (struct sockaddr
*) &sa
, &sa_len
) < 0)
33 /* Check that the socket family number is preserved despite in-band
35 _Static_assert (sizeof (sa
.ss_family
) < sizeof (int), "address family size");
36 _Static_assert (0 < (__typeof__ (sa
.ss_family
)) -1,
37 "address family unsigned");
43 __netlink_assert_response (int fd
, ssize_t result
)
47 /* Check if the error is unexpected. */
48 bool terminate
= false;
49 int error_code
= errno
;
50 int family
= get_address_family (fd
);
51 if (family
!= AF_NETLINK
)
52 /* If the address family does not match (or getsockname
53 failed), report the original error. */
55 else if (error_code
== EBADF
56 || error_code
== ENOTCONN
57 || error_code
== ENOTSOCK
58 || error_code
== ECONNREFUSED
)
59 /* These errors indicate that the descriptor is not a
62 else if (error_code
== EAGAIN
|| error_code
== EWOULDBLOCK
)
64 /* The kernel might return EAGAIN for other reasons than a
65 non-blocking socket. But if the socket is not blocking,
66 it is not ours, so report the error. */
67 int mode
= __fcntl (fd
, F_GETFL
, 0);
68 if (mode
< 0 || (mode
& O_NONBLOCK
) != 0)
75 __snprintf (message
, sizeof (message
),
76 "Unexpected error %d on netlink descriptor %d",
79 __snprintf (message
, sizeof (message
),
80 "Unexpected error %d on netlink descriptor %d"
81 " (address family %d)",
82 error_code
, fd
, family
);
83 __libc_fatal (message
);
86 /* Restore orignal errno value. */
87 __set_errno (error_code
);
89 else if (result
< sizeof (struct nlmsghdr
))
92 int family
= get_address_family (fd
);
94 __snprintf (message
, sizeof (message
),
95 "Unexpected netlink response of size %zd"
99 __snprintf (message
, sizeof (message
),
100 "Unexpected netlink response of size %zd"
101 " on descriptor %d (address family %d)",
103 __libc_fatal (message
);
106 libc_hidden_def (__netlink_assert_response
)