GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / Documentation / connector / ucon.c
blobbbd53283f1423662d7b6c7843cdc2fca7cfc1593
1 /*
2 * ucon.c
4 * Copyright (c) 2004+ Evgeniy Polyakov <zbr@ioremap.net>
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.
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.
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
22 #include <asm/types.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/poll.h>
28 #include <linux/netlink.h>
29 #include <linux/rtnetlink.h>
31 #include <arpa/inet.h>
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>
42 #include <linux/connector.h>
44 #define DEBUG
45 #define NETLINK_CONNECTOR 11
47 /* Hopefully your userspace connector.h matches this kernel */
48 #define CN_TEST_IDX CN_NETLINK_USERS + 3
49 #define CN_TEST_VAL 0x456
51 #ifdef DEBUG
52 #define ulog(f, a...) fprintf(stdout, f, ##a)
53 #else
54 #define ulog(f, a...) do {} while (0)
55 #endif
57 static int need_exit;
58 static __u32 seq;
60 static int netlink_send(int s, struct cn_msg *msg)
62 struct nlmsghdr *nlh;
63 unsigned int size;
64 int err;
65 char buf[128];
66 struct cn_msg *m;
68 size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
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;
77 m = NLMSG_DATA(nlh);
78 memcpy(m, msg, sizeof(*m) + msg->len);
80 err = send(s, nlh, size, 0);
81 if (err == -1)
82 ulog("Failed to send: %s [%d].\n",
83 strerror(errno), errno);
85 return err;
88 static void usage(void)
90 printf(
91 "Usage: ucon [options] [output file]\n"
92 "\n"
93 "\t-h\tthis help screen\n"
94 "\t-s\tsend buffers to the test module\n"
95 "\n"
96 "The default behavior of ucon is to subscribe to the test module\n"
97 "and wait for state messages. Any ones received are dumped to the\n"
98 "specified output file (or stdout). The test module is assumed to\n"
99 "have an id of {%u.%u}\n"
100 "\n"
101 "If you get no output, then verify the cn_test module id matches\n"
102 "the expected id above.\n"
103 , CN_TEST_IDX, CN_TEST_VAL
107 int main(int argc, char *argv[])
109 int s;
110 char buf[1024];
111 int len;
112 struct nlmsghdr *reply;
113 struct sockaddr_nl l_local;
114 struct cn_msg *data;
115 FILE *out;
116 time_t tm;
117 struct pollfd pfd;
118 bool send_msgs = false;
120 while ((s = getopt(argc, argv, "hs")) != -1) {
121 switch (s) {
122 case 's':
123 send_msgs = true;
124 break;
126 case 'h':
127 usage();
128 return 0;
130 default:
131 /* getopt() outputs an error for us */
132 usage();
133 return 1;
137 if (argc != optind) {
138 out = fopen(argv[optind], "a+");
139 if (!out) {
140 ulog("Unable to open %s for writing: %s\n",
141 argv[1], strerror(errno));
142 out = stdout;
144 } else
145 out = stdout;
147 memset(buf, 0, sizeof(buf));
149 s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
150 if (s == -1) {
151 perror("socket");
152 return -1;
155 l_local.nl_family = AF_NETLINK;
156 l_local.nl_groups = -1; /* bitmask of requested groups */
157 l_local.nl_pid = 0;
159 ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
161 if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
162 perror("bind");
163 close(s);
164 return -1;
167 if (send_msgs) {
168 int i, j;
170 memset(buf, 0, sizeof(buf));
172 data = (struct cn_msg *)buf;
174 data->id.idx = CN_TEST_IDX;
175 data->id.val = CN_TEST_VAL;
176 data->seq = seq++;
177 data->ack = 0;
178 data->len = 0;
180 for (j=0; j<10; ++j) {
181 for (i=0; i<1000; ++i) {
182 len = netlink_send(s, data);
185 ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
188 return 0;
192 pfd.fd = s;
194 while (!need_exit) {
195 pfd.events = POLLIN;
196 pfd.revents = 0;
197 switch (poll(&pfd, 1, -1)) {
198 case 0:
199 need_exit = 1;
200 break;
201 case -1:
202 if (errno != EINTR) {
203 need_exit = 1;
204 break;
206 continue;
208 if (need_exit)
209 break;
211 memset(buf, 0, sizeof(buf));
212 len = recv(s, buf, sizeof(buf), 0);
213 if (len == -1) {
214 perror("recv buf");
215 close(s);
216 return -1;
218 reply = (struct nlmsghdr *)buf;
220 switch (reply->nlmsg_type) {
221 case NLMSG_ERROR:
222 fprintf(out, "Error message received.\n");
223 fflush(out);
224 break;
225 case NLMSG_DONE:
226 data = (struct cn_msg *)NLMSG_DATA(reply);
228 time(&tm);
229 fprintf(out, "%.24s : [%x.%x] [%08u.%08u].\n",
230 ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
231 fflush(out);
232 break;
233 default:
234 break;
238 close(s);
239 return 0;