~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/connector/ucon.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      ucon.c
  3  *
  4  * Copyright (c) 2004+ Evgeniy Polyakov <zbr@ioremap.net>
  5  *
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License as published by
  9  * the Free Software Foundation; either version 2 of the License, or
 10  * (at your option) any later version.
 11  *
 12  * This program is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  * GNU General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU General Public License
 18  * along with this program; if not, write to the Free Software
 19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 20  */
 21 
 22 #include <asm/types.h>
 23 
 24 #include <sys/types.h>
 25 #include <sys/socket.h>
 26 #include <sys/poll.h>
 27 
 28 #include <linux/netlink.h>
 29 #include <linux/rtnetlink.h>
 30 
 31 #include <arpa/inet.h>
 32 
 33 #include <stdbool.h>
 34 #include <stdio.h>
 35 #include <stdlib.h>
 36 #include <unistd.h>
 37 #include <string.h>
 38 #include <errno.h>
 39 #include <time.h>
 40 #include <getopt.h>
 41 
 42 #include <linux/connector.h>
 43 
 44 #define DEBUG
 45 #define NETLINK_CONNECTOR       11
 46 
 47 /* Hopefully your userspace connector.h matches this kernel */
 48 #define CN_TEST_IDX             CN_NETLINK_USERS + 3
 49 #define CN_TEST_VAL             0x456
 50 
 51 #ifdef DEBUG
 52 #define ulog(f, a...) fprintf(stdout, f, ##a)
 53 #else
 54 #define ulog(f, a...) do {} while (0)
 55 #endif
 56 
 57 static int need_exit;
 58 static __u32 seq;
 59 
 60 static int netlink_send(int s, struct cn_msg *msg)
 61 {
 62         struct nlmsghdr *nlh;
 63         unsigned int size;
 64         int err;
 65         char buf[128];
 66         struct cn_msg *m;
 67 
 68         size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
 69 
 70         nlh = (struct nlmsghdr *)buf;
 71         nlh->nlmsg_seq = seq++;
 72         nlh->nlmsg_pid = getpid();
 73         nlh->nlmsg_type = NLMSG_DONE;
 74         nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
 75         nlh->nlmsg_flags = 0;
 76 
 77         m = NLMSG_DATA(nlh);
 78 #if 0
 79         ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
 80                __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack);
 81 #endif
 82         memcpy(m, msg, sizeof(*m) + msg->len);
 83 
 84         err = send(s, nlh, size, 0);
 85         if (err == -1)
 86                 ulog("Failed to send: %s [%d].\n",
 87                         strerror(errno), errno);
 88 
 89         return err;
 90 }
 91 
 92 static void usage(void)
 93 {
 94         printf(
 95                 "Usage: ucon [options] [output file]\n"
 96                 "\n"
 97                 "\t-h\tthis help screen\n"
 98                 "\t-s\tsend buffers to the test module\n"
 99                 "\n"
100                 "The default behavior of ucon is to subscribe to the test module\n"
101                 "and wait for state messages.  Any ones received are dumped to the\n"
102                 "specified output file (or stdout).  The test module is assumed to\n"
103                 "have an id of {%u.%u}\n"
104                 "\n"
105                 "If you get no output, then verify the cn_test module id matches\n"
106                 "the expected id above.\n"
107                 , CN_TEST_IDX, CN_TEST_VAL
108         );
109 }
110 
111 int main(int argc, char *argv[])
112 {
113         int s;
114         char buf[1024];
115         int len;
116         struct nlmsghdr *reply;
117         struct sockaddr_nl l_local;
118         struct cn_msg *data;
119         FILE *out;
120         time_t tm;
121         struct pollfd pfd;
122         bool send_msgs = false;
123 
124         while ((s = getopt(argc, argv, "hs")) != -1) {
125                 switch (s) {
126                 case 's':
127                         send_msgs = true;
128                         break;
129 
130                 case 'h':
131                         usage();
132                         return 0;
133 
134                 default:
135                         /* getopt() outputs an error for us */
136                         usage();
137                         return 1;
138                 }
139         }
140 
141         if (argc != optind) {
142                 out = fopen(argv[optind], "a+");
143                 if (!out) {
144                         ulog("Unable to open %s for writing: %s\n",
145                                 argv[1], strerror(errno));
146                         out = stdout;
147                 }
148         } else
149                 out = stdout;
150 
151         memset(buf, 0, sizeof(buf));
152 
153         s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
154         if (s == -1) {
155                 perror("socket");
156                 return -1;
157         }
158 
159         l_local.nl_family = AF_NETLINK;
160         l_local.nl_groups = -1; /* bitmask of requested groups */
161         l_local.nl_pid = 0;
162 
163         ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
164 
165         if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
166                 perror("bind");
167                 close(s);
168                 return -1;
169         }
170 
171 #if 0
172         {
173                 int on = 0x57; /* Additional group number */
174                 setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
175         }
176 #endif
177         if (send_msgs) {
178                 int i, j;
179 
180                 memset(buf, 0, sizeof(buf));
181 
182                 data = (struct cn_msg *)buf;
183 
184                 data->id.idx = CN_TEST_IDX;
185                 data->id.val = CN_TEST_VAL;
186                 data->seq = seq++;
187                 data->ack = 0;
188                 data->len = 0;
189 
190                 for (j=0; j<10; ++j) {
191                         for (i=0; i<1000; ++i) {
192                                 len = netlink_send(s, data);
193                         }
194 
195                         ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
196                 }
197 
198                 return 0;
199         }
200 
201 
202         pfd.fd = s;
203 
204         while (!need_exit) {
205                 pfd.events = POLLIN;
206                 pfd.revents = 0;
207                 switch (poll(&pfd, 1, -1)) {
208                         case 0:
209                                 need_exit = 1;
210                                 break;
211                         case -1:
212                                 if (errno != EINTR) {
213                                         need_exit = 1;
214                                         break;
215                                 }
216                                 continue;
217                 }
218                 if (need_exit)
219                         break;
220 
221                 memset(buf, 0, sizeof(buf));
222                 len = recv(s, buf, sizeof(buf), 0);
223                 if (len == -1) {
224                         perror("recv buf");
225                         close(s);
226                         return -1;
227                 }
228                 reply = (struct nlmsghdr *)buf;
229 
230                 switch (reply->nlmsg_type) {
231                 case NLMSG_ERROR:
232                         fprintf(out, "Error message received.\n");
233                         fflush(out);
234                         break;
235                 case NLMSG_DONE:
236                         data = (struct cn_msg *)NLMSG_DATA(reply);
237 
238                         time(&tm);
239                         fprintf(out, "%.24s : [%x.%x] [%08u.%08u].\n",
240                                 ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
241                         fflush(out);
242                         break;
243                 default:
244                         break;
245                 }
246         }
247 
248         close(s);
249         return 0;
250 }
251 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp