1 /*
2 * Copyright (c) 2018 Richard Palethorpe <rpalethorpe@suse.com>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /**
18 * @file tst_netlink.h
19 *
20 * Library for communicating with the kernel over the netlink interface.
21 */
22
23 #ifndef TST_NETLINK_H
24 #define TST_NETLINK_H
25
26 #include <linux/netlink.h>
27
28 #ifndef NETLINK_CRYPTO
29 /**
30 * The netlink-crypto socket protocol.
31 */
32 #define NETLINK_CRYPTO 21
33 #endif
34
35 /** @private */
safe_netlink_send(const char * file,const int lineno,int fd,const struct nlmsghdr * nh,const void * payload)36 static inline ssize_t safe_netlink_send(const char *file, const int lineno,
37 int fd, const struct nlmsghdr *nh,
38 const void *payload)
39 {
40 struct sockaddr_nl sa = { .nl_family = AF_NETLINK };
41 struct iovec iov[2] = {
42 {(struct nlmsghdr *)nh, sizeof(*nh)},
43 {(void *)payload, nh->nlmsg_len - sizeof(*nh)}
44 };
45 struct msghdr msg = {
46 .msg_name = &sa,
47 .msg_namelen = sizeof(sa),
48 .msg_iov = iov,
49 .msg_iovlen = 2
50 };
51
52 return safe_sendmsg(file, lineno, nh->nlmsg_len, fd, &msg, 0);
53 }
54
55 /**
56 * Sends a netlink message using safe_sendmsg().
57 *
58 * @param fd netlink socket file descriptor.
59 * @param nl_header netlink header structure describing the message.
60 * @param payload an opaque object containing the message data.
61 *
62 * You should set the message length, type and flags to appropriate values
63 * within the nl_header object. See lib/tst_crypto.c for an example.
64 *
65 * @return The number of bytes sent.
66 */
67 #define SAFE_NETLINK_SEND(fd, nl_header, payload) \
68 safe_netlink_send(__FILE__, __LINE__, fd, nl_header, payload)
69
70 /** @private */
safe_netlink_recv(const char * file,const int lineno,int fd,char * nl_headers_buf,size_t buf_len)71 static inline ssize_t safe_netlink_recv(const char *file, const int lineno,
72 int fd, char *nl_headers_buf,
73 size_t buf_len)
74 {
75 struct iovec iov = { nl_headers_buf, buf_len };
76 struct sockaddr_nl sa;
77 struct msghdr msg = {
78 .msg_name = &sa,
79 .msg_namelen = sizeof(sa),
80 .msg_iov = &iov,
81 .msg_iovlen = 1
82 };
83
84 return safe_recvmsg(file, lineno, 0, fd, &msg, 0);
85 }
86
87 /**
88 * Receives a netlink message using safe_recvmsg().
89 *
90 * @param fd netlink socket file descriptor.
91 * @param nl_header_buf buffer to contain the received netlink header structure.
92 * @param buf_len The length of the header buffer. Must be greater than the page
93 * size.
94 *
95 * @return The number of bytes received.
96 */
97 #define SAFE_NETLINK_RECV(fd, nl_header_buf, buf_len) \
98 safe_netlink_recv(__FILE__, __LINE__, fd, nl_header_buf, buf_len)
99
100 #endif /* TST_NETLINK_H */
101