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>
28 #include <linux/netlink.h>
29 #include <linux/rtnetlink.h>
31 #include <arpa/inet.h>
40 #include <linux/connector.h>
43 #define NETLINK_CONNECTOR 11
46 #define ulog(f, a...) fprintf(stdout, f, ##a)
48 #define ulog(f, a...) do {} while (0)
54 static int netlink_send(int s
, struct cn_msg
*msg
)
62 size
= NLMSG_SPACE(sizeof(struct cn_msg
) + msg
->len
);
64 nlh
= (struct nlmsghdr
*)buf
;
65 nlh
->nlmsg_seq
= seq
++;
66 nlh
->nlmsg_pid
= getpid();
67 nlh
->nlmsg_type
= NLMSG_DONE
;
68 nlh
->nlmsg_len
= NLMSG_LENGTH(size
- sizeof(*nlh
));
73 ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
74 __func__
, msg
->id
.idx
, msg
->id
.val
, msg
->len
, msg
->seq
, msg
->ack
);
76 memcpy(m
, msg
, sizeof(*m
) + msg
->len
);
78 err
= send(s
, nlh
, size
, 0);
80 ulog("Failed to send: %s [%d].\n",
81 strerror(errno
), errno
);
86 int main(int argc
, char *argv
[])
91 struct nlmsghdr
*reply
;
92 struct sockaddr_nl l_local
;
101 out
= fopen(argv
[1], "a+");
103 ulog("Unable to open %s for writing: %s\n",
104 argv
[1], strerror(errno
));
109 memset(buf
, 0, sizeof(buf
));
111 s
= socket(PF_NETLINK
, SOCK_DGRAM
, NETLINK_CONNECTOR
);
117 l_local
.nl_family
= AF_NETLINK
;
118 l_local
.nl_groups
= 0x123; /* bitmask of requested groups */
121 if (bind(s
, (struct sockaddr
*)&l_local
, sizeof(struct sockaddr_nl
)) == -1) {
129 int on
= 0x57; /* Additional group number */
130 setsockopt(s
, SOL_NETLINK
, NETLINK_ADD_MEMBERSHIP
, &on
, sizeof(on
));
136 memset(buf
, 0, sizeof(buf
));
138 data
= (struct cn_msg
*)buf
;
140 data
->id
.idx
= 0x123;
141 data
->id
.val
= 0x456;
146 for (j
=0; j
<10; ++j
) {
147 for (i
=0; i
<1000; ++i
) {
148 len
= netlink_send(s
, data
);
151 ulog("%d messages have been sent to %08x.%08x.\n", i
, data
->id
.idx
, data
->id
.val
);
163 switch (poll(&pfd
, 1, -1)) {
168 if (errno
!= EINTR
) {
177 memset(buf
, 0, sizeof(buf
));
178 len
= recv(s
, buf
, sizeof(buf
), 0);
184 reply
= (struct nlmsghdr
*)buf
;
186 switch (reply
->nlmsg_type
) {
188 fprintf(out
, "Error message received.\n");
192 data
= (struct cn_msg
*)NLMSG_DATA(reply
);
195 fprintf(out
, "%.24s : [%x.%x] [%08u.%08u].\n",
196 ctime(&tm
), data
->id
.idx
, data
->id
.val
, data
->seq
, data
->ack
);