Verify that netlink messages are coming from kernel.
[v86d.git] / v86.c
Commit [+]AuthorDateLineData
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +02001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <errno.h>
6#include <time.h>
7#include <fcntl.h>
8
e2a9ef71
MJ
Michał Januszewski2007-06-07 21:01:56 +02009#include <sys/socket.h>
10#include <sys/poll.h>
11
12#include <linux/netlink.h>
13#include <linux/rtnetlink.h>
14
15#include <arpa/inet.h>
16
b2bf1480 Michał Januszewski2007-05-20 23:29:03 +020017#include "v86.h"
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020018
19static int need_exit;
20static __u32 seq;
21
22static int netlink_send(int s, struct cn_msg *msg)
23{
24 struct nlmsghdr *nlh;
25 unsigned int size;
26 int err;
e2a9ef71 Michał Januszewski2007-06-07 21:01:56 +020027 char buf[CONNECTOR_MAX_MSG_SIZE];
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020028 struct cn_msg *m;
29
30 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
31
32 nlh = (struct nlmsghdr *)buf;
33 nlh->nlmsg_seq = seq++;
34 nlh->nlmsg_pid = getpid();
35 nlh->nlmsg_type = NLMSG_DONE;
36 nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
37 nlh->nlmsg_flags = 0;
38
39 m = NLMSG_DATA(nlh);
40 memcpy(m, msg, sizeof(*m) + msg->len);
41
42 err = send(s, nlh, size, 0);
43 if (err == -1)
b2f10ad9 Michał Januszewski2007-10-19 00:21:22 +020044 ulog(LOG_ERR, "Failed to send: %s [%d].\n", strerror(errno), errno);
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020045
46 return err;
47}
48
49int req_exec(int s, struct cn_msg *msg)
50{
51 struct uvesafb_task *tsk = (struct uvesafb_task*)(msg + 1);
b2bf1480 Michał Januszewski2007-05-20 23:29:03 +020052 u8 *buf = (u8*)tsk + sizeof(struct uvesafb_task);
59291f9d
MJ
Michał Januszewski2007-06-23 01:28:36 +020053
54 if (tsk->flags & TF_EXIT)
55 return 1;
858aa657 Michał Januszewski2007-05-14 08:38:25 +020056
80a78724
MJ
Michał Januszewski2008-04-19 22:43:39 +020057 if (v86_task(tsk, buf))
58 return 2;
59
b2bf1480 Michał Januszewski2007-05-20 23:29:03 +020060 netlink_send(s, msg);
858aa657 Michał Januszewski2007-05-14 08:38:25 +020061
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020062 return 0;
63}
64
65
66int main(int argc, char *argv[])
67{
e2a9ef71 Michał Januszewski2007-06-07 21:01:56 +020068 char buf[CONNECTOR_MAX_MSG_SIZE];
59291f9d Michał Januszewski2007-06-23 01:28:36 +020069 int len, i, err = 0, s;
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020070 struct nlmsghdr *reply;
71 struct sockaddr_nl l_local;
72 struct cn_msg *data;
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020073 struct pollfd pfd;
74
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020075 s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
76 if (s == -1) {
77 perror("socket");
78 return -1;
79 }
80
81 l_local.nl_family = AF_NETLINK;
59291f9d Michał Januszewski2007-06-23 01:28:36 +020082 l_local.nl_groups = 1 << (CN_IDX_V86D-1); /* bitmask of requested groups */
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +020083 l_local.nl_pid = 0;
84
85 if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
86 perror("bind");
87 close(s);
88 return -1;
89 }
90
91 i = fork();
92 if (i) {
93 exit(0);
94 }
95
96 setsid();
97 chdir("/");
98
e2a9ef71
MJ
Michał Januszewski2007-06-07 21:01:56 +020099 openlog("v86d", 0, LOG_KERN);
100
b2bf1480
MJ
Michał Januszewski2007-05-20 23:29:03 +0200101 if (v86_init())
102 return -1;
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200103
104 memset(buf, 0, sizeof(buf));
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200105 pfd.fd = s;
106
107 while (!need_exit) {
108 pfd.events = POLLIN;
109 pfd.revents = 0;
110 switch (poll(&pfd, 1, -1)) {
111 case 0:
112 need_exit = 1;
113 continue;
114 case -1:
115 if (errno != EINTR) {
116 need_exit = 1;
117 break;
118 }
119 continue;
120 }
121
122 memset(buf, 0, sizeof(buf));
123 len = recv(s, buf, sizeof(buf), 0);
124 if (len == -1) {
125 perror("recv buf");
59291f9d
MJ
Michał Januszewski2007-06-23 01:28:36 +0200126 err = -1;
127 goto out;
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200128 }
129
130 reply = (struct nlmsghdr *)buf;
131
f9abfd41
MJ
Michał Januszewski2011-02-25 22:24:46 +0100132 /* Ignore requests coming from outside the kernel. */
133 if (reply->nlmsg_pid != 0) {
134 continue;
135 }
136
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200137 switch (reply->nlmsg_type) {
138 case NLMSG_ERROR:
b2f10ad9 Michał Januszewski2007-10-19 00:21:22 +0200139 ulog(LOG_ERR, "Error message received.\n");
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200140 break;
141
142 case NLMSG_DONE:
143 data = (struct cn_msg *)NLMSG_DATA(reply);
59291f9d
MJ
Michał Januszewski2007-06-23 01:28:36 +0200144 if (req_exec(s, data))
145 goto out;
858aa657
MJ
Michał Januszewski2007-05-14 08:38:25 +0200146 break;
147 default:
148 break;
149 }
150 }
151
59291f9d Michał Januszewski2007-06-23 01:28:36 +0200152out:
bd26d8f6
MJ
Michał Januszewski2007-06-09 12:34:28 +0200153 v86_cleanup();
154
e2a9ef71 Michał Januszewski2007-06-07 21:01:56 +0200155 closelog();
858aa657 Michał Januszewski2007-05-14 08:38:25 +0200156 close(s);
59291f9d Michał Januszewski2007-06-23 01:28:36 +0200157 return err;
858aa657 Michał Januszewski2007-05-14 08:38:25 +0200158}