1 // SPDX-License-Identifier: GPL-2.0
12 #include <sys/socket.h>
14 #include <linux/audit.h>
15 #include <linux/netlink.h>
19 #define MAX_AUDIT_MESSAGE_LENGTH 8970
20 struct audit_message {
23 struct audit_status s;
24 char data[MAX_AUDIT_MESSAGE_LENGTH];
28 int audit_recv(int fd, struct audit_message *rep)
30 struct sockaddr_nl addr;
31 socklen_t addrlen = sizeof(addr);
35 ret = recvfrom(fd, rep, sizeof(*rep), 0,
36 (struct sockaddr *)&addr, &addrlen);
37 } while (ret < 0 && errno == EINTR);
40 addrlen != sizeof(addr) ||
42 rep->nlh.nlmsg_type == NLMSG_ERROR) /* short-cut for now */
48 int audit_send(int fd, uint16_t type, uint32_t key, uint32_t val)
51 struct audit_message msg = {
53 .nlmsg_len = NLMSG_SPACE(sizeof(msg.u.s)),
55 .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
60 .enabled = key == AUDIT_STATUS_ENABLED ? val : 0,
61 .pid = key == AUDIT_STATUS_PID ? val : 0,
64 struct sockaddr_nl addr = {
65 .nl_family = AF_NETLINK,
70 ret = sendto(fd, &msg, msg.nlh.nlmsg_len, 0,
71 (struct sockaddr *)&addr, sizeof(addr));
72 } while (ret < 0 && errno == EINTR);
74 if (ret != (int)msg.nlh.nlmsg_len)
79 int audit_set(int fd, uint32_t key, uint32_t val)
81 struct audit_message rep = { 0 };
84 ret = audit_send(fd, AUDIT_SET, key, val);
88 ret = audit_recv(fd, &rep);
96 struct audit_message rep = { 0 };
97 int ret = audit_recv(fd, &rep);
104 if (rep.nlh.nlmsg_type != AUDIT_NETFILTER_CFG)
107 /* skip the initial "audit(...): " part */
108 strtok(rep.u.data, " ");
110 while ((k = strtok(NULL, "="))) {
111 v = strtok(NULL, " ");
113 /* these vary and/or are uninteresting, ignore */
114 if (!strcmp(k, "pid") ||
115 !strcmp(k, "comm") ||
119 /* strip the varying sequence number */
120 if (!strcmp(k, "table"))
121 *strchrnul(v, ':') = '\0';
123 printf("%s%s=%s", sep, k, v);
133 void cleanup(int sig)
135 audit_set(fd, AUDIT_STATUS_ENABLED, 0);
141 int main(int argc, char **argv)
143 struct sigaction act = {
144 .sa_handler = cleanup,
147 fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
149 perror("Can't open netlink socket");
153 if (sigaction(SIGTERM, &act, NULL) < 0 ||
154 sigaction(SIGINT, &act, NULL) < 0) {
155 perror("Can't set signal handler");
160 audit_set(fd, AUDIT_STATUS_ENABLED, 1);
161 audit_set(fd, AUDIT_STATUS_PID, getpid());