/* * cn_user_recv.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void process_msg(int s, struct cn_msg *msg) { fprintf(stdout, "Message: %08x.%08x, len=%u, seq=%u, ack=%u, len=%u %s\n", msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack, msg->len, (void *)msg->data); } int main(int argc, char *argv[]) { int s; unsigned char buf[1024]; int len, need_exit; struct sockaddr_nl l_local; struct cn_msg *msg; struct pollfd pfd; struct nlmsghdr *reply; memset(buf, 0, sizeof(buf)); s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); if (s == -1) { perror("socket"); return -1; } l_local.nl_family = AF_NETLINK; l_local.nl_groups = 0x3; l_local.nl_pid = getpid(); if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) { perror("bind"); close(s); return -1; } int on = l_local.nl_groups; if (setsockopt(s, 270, 1, &on, sizeof(on))) { perror("setsockopt"); close(s); return -1; } pfd.fd = s; need_exit = 0; while (!need_exit) { pfd.events = POLLIN; pfd.revents = 0; switch (poll(&pfd, 1, -1)) { case 0: need_exit = 1; break; case -1: if (errno != EINTR) { need_exit = 1; break; } continue; default: break; } if (need_exit) break; len = recv(s, buf, sizeof(buf), 0); if (len == -1) { perror("recv buf"); close(s); return -1; } reply = (struct nlmsghdr *)buf; switch (reply->nlmsg_type) { case NLMSG_ERROR: fprintf(stdout, "Error message received.\n"); fflush(stdout); break; case NLMSG_DONE: msg = (struct cn_msg *)NLMSG_DATA(reply); process_msg(s, msg); break; default: break; } } close(s); return 0; }