2 * echo-test: sends a netlink message to the kernel and reads it back.
4 * This requires the netlink-echo kernel module. It reads a netlink
5 * message (a string) from user-space and sends it back.
7 * Luiz Fernando N. Capitulino
8 * <lcapitulino@gmail.com>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <linux/netlink.h>
18 #define NETLINK_ECHO 20 // from netlink-echo.c
20 static void usage(void)
22 printf("echo-test < string >\n");
25 /* create_socket(): Create a netlink socket and bind it.
26 * Return a file-descriptor on success, -1 otherwise. */
27 static int create_socket(void)
30 struct sockaddr_nl sa
;
32 fd
= socket(PF_NETLINK
, SOCK_RAW
, NETLINK_ECHO
);
36 memset(&sa
, 0, sizeof(sa
));
37 sa
.nl_family
= AF_NETLINK
;
38 sa
.nl_pid
= getpid(); // self pid
40 err
= bind(fd
, (struct sockaddr
*) &sa
, sizeof(sa
));
47 /* send_message(): Send a netlink message to the kernel.
48 * The argument 'message' must be a human readable string.
49 * Return the amount of bytes sent on success, -1 on failure. */
50 static ssize_t
send_message(int sock_fd
, const char *message
)
56 struct nlmsghdr
*nlhdr
;
57 struct sockaddr_nl nladdr
;
59 len
= sizeof(*nlhdr
) + strlen(message
) + 1;
64 memset(nlhdr
, 0, len
);
65 nlhdr
->nlmsg_len
= len
;
66 nlhdr
->nlmsg_pid
= getpid();
67 strcpy(NLMSG_DATA(nlhdr
), message
);
69 iov
.iov_base
= (void *) nlhdr
;
70 iov
.iov_len
= nlhdr
->nlmsg_len
;
72 memset(&nladdr
, 0, sizeof(nladdr
));
73 nladdr
.nl_family
= AF_NETLINK
;
75 memset(&msg
, 0, sizeof(msg
));
76 msg
.msg_name
= (void *) &(nladdr
);
77 msg
.msg_namelen
= sizeof(nladdr
);
81 bytes
= sendmsg(sock_fd
, &msg
, 0);
87 static struct nlmsghdr
*read_message(int sock_fd
, size_t len
)
92 struct nlmsghdr
*nlhdr
;
93 struct sockaddr_nl nladdr
;
95 len
+= sizeof(*nlhdr
);
100 memset(nlhdr
, 0, len
);
101 nlhdr
->nlmsg_len
= len
;
102 nlhdr
->nlmsg_pid
= getpid();
103 iov
.iov_base
= (void *) nlhdr
;
104 iov
.iov_len
= nlhdr
->nlmsg_len
;
106 memset(&nladdr
, 0, sizeof(nladdr
));
107 nladdr
.nl_family
= AF_NETLINK
;
109 memset(&msg
, 0, sizeof(msg
));
110 msg
.msg_name
= (void *) &(nladdr
);
111 msg
.msg_namelen
= sizeof(nladdr
);
115 bytes
= recvmsg(sock_fd
, &msg
, 0);
124 int main(int argc
, char *argv
[])
128 struct nlmsghdr
*msg
;
135 sock_fd
= create_socket();
137 perror("create_socket()");
141 bytes
= send_message(sock_fd
, argv
[1]);
143 perror("send_message()");
147 msg
= read_message(sock_fd
, strlen(argv
[1]) + 1);
149 perror("read_message()");
153 printf("%s\n", (char *) NLMSG_DATA(msg
));