10 int create_netlink_socket(int protocol, int groups, int pid)
14 struct sockaddr_nl local;
15 int buf_size = 1024*1024;
17 sock = socket(AF_NETLINK, SOCK_RAW, protocol);
20 _E("socket failed: %s", strerror(errno));
23 if ((flags = fcntl(sock, F_GETFL, 0)) < 0) {
30 if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) != 0) {
32 _E("fcntl failed: %s", strerror(errno));
36 if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)) < 0)
39 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)) < 0)
42 bzero(&local, sizeof(struct sockaddr_nl));
43 local.nl_family = AF_NETLINK;
44 local.nl_groups = groups;
47 if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0) {
49 _E("bind failed: %s", strerror(errno));
57 int send_cmd(int sock, unsigned short family_id, pid_t pid, __u8 cmd,
58 unsigned short nl_type, void *nl_data, int nl_len)
61 struct sockaddr_nl addr;
66 struct msgtemplate message;
69 message.g.version = 1;
70 message.n.nlmsg_flags = NLM_F_REQUEST;
71 message.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
72 message.n.nlmsg_pid = pid;
73 message.n.nlmsg_seq = 0;
74 message.n.nlmsg_type = family_id;
76 attr = (struct nlattr *) GENLMSG_DATA(&message);
77 attr->nla_type = nl_type;
78 attr->nla_len = nl_len + 1 + NLA_HDRLEN;
80 memcpy(NLA_DATA(attr), nl_data, nl_len);
81 message.n.nlmsg_len += NLMSG_ALIGN(attr->nla_len);
83 buffer = (char *) &message;
84 len = message.n.nlmsg_len;
85 memset(&addr, 0, sizeof(addr));
86 addr.nl_family = AF_NETLINK;
88 for (; ret < len; buffer += ret, len -= ret) {
89 ret = sendto(sock, buffer, len, 0, (struct sockaddr *) &addr,
91 if (ret < 0 && errno != EAGAIN)
98 int get_family_id(int sock, const char *name)
110 rc = send_cmd(sock, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
111 CTRL_ATTR_FAMILY_NAME, (void *)name, strlen(name) + 1);
113 _E("send_cmd error");
117 rep_len = recv(sock, &ans, sizeof(ans), 0);
118 if (rep_len < 0 || ans.n.nlmsg_type == NLMSG_ERROR ||
119 !NLMSG_OK((&ans.n), (unsigned int)rep_len)) {
124 na = (struct nlattr *) GENLMSG_DATA(&ans);
125 na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
127 if (na->nla_type == CTRL_ATTR_FAMILY_ID) {
128 id = *(__u16 *) NLA_DATA(na);