user client

获取netlink 的family id

发送family id 请求消息:

首先向内核发一个family_id的请求消息,根据family name查询family id,在内核注册genl_family demo_family的时候分配一个family id 与family name对应
nlmsg_type = GENL_ID_CTRL
nlmsg_flags = NLM_F_REQUEST

genl_cmd = CTRL_CMD_GETFAMILY

na->nla_type = CTRL_ATTR_FAMILY_NAME

struct nlmsghdr struct genlmsghdr char buf(可以放多个struct nlattr )
  1. struct nlattr *na;
  2. struct sockaddr_nl nladdr;
  3. int r, buflen;
  4. char *buf;
  5. struct msgtemplate msg;
  6. /* 填充msg (本函数发送的msg只填充一个attr) */
  7. msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
  8. msg.n.nlmsg_type = GENL_ID_CTRL; //后面要是在发送其它消息到内核就用到这个消息的响应消息里面的family_id
  9. msg.n.nlmsg_flags = NLM_F_REQUEST;
  10. msg.n.nlmsg_seq = 0;
  11. msg.n.nlmsg_pid = nlmsg_pid;
  12. msg.g.cmd = CTRL_CMD_GETFAMILY; //
  13. msg.g.version = DEMO_GENL_VERSION;
  14. na = (struct nlattr *) GENLMSG_DATA(&msg);
  15. na->nla_type = CTRL_ATTR_FAMILY_NAME; //
  16. na->nla_len = nla_len + 1 + NLA_HDRLEN;
  17. memcpy(NLA_DATA(na), nla_data, nla_len);
  18. msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);
  19. buf = (char *) &msg;
  20. buflen = msg.n.nlmsg_len;
  21. memset(&nladdr, 0, sizeof(nladdr));
  22. nladdr.nl_family = AF_NETLINK;
  23. /* 循环发送直到发送完成 */
  24. while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
  25. sizeof(nladdr))) < buflen) {
  26. if (r > 0) {
  27. buf += r;
  28. buflen -= r;
  29. } else if (errno != EAGAIN)
  30. return -1;
  31. }

发送普通消息:

nlmsg_type = family_id
nlmsg_flags = NLM_F_REQUEST

genl_cmd = DEMO_CMD_ECHO

na->nla_type = DEMO_CMD_ATTR_MESG