Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
Documentation
connector
ucon.c
Go to the documentation of this file.
1
/*
2
* ucon.c
3
*
4
* Copyright (c) 2004+ Evgeniy Polyakov <
[email protected]
>
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
}
Generated on Thu Jan 10 2013 13:23:17 for Linux Kernel by
1.8.2