tools/testing/selftests/nci/nci_dev.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/nci/nci_dev.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/nci/nci_dev.c
Extension
.c
Size
22226 bytes
Lines
905
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct msgtemplate {
	struct nlmsghdr n;
	struct genlmsghdr g;
	char buf[MAX_MSG_SIZE];
};

static int create_nl_socket(void)
{
	int fd;
	struct sockaddr_nl local;

	fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (fd < 0)
		return -1;

	memset(&local, 0, sizeof(local));
	local.nl_family = AF_NETLINK;

	if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0)
		goto error;

	return fd;
error:
	close(fd);
	return -1;
}

static int send_cmd_mt_nla(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
			   __u8 genl_cmd, int nla_num, __u16 nla_type[],
			   void *nla_data[], int nla_len[], __u16 flags)
{
	struct sockaddr_nl nladdr;
	struct msgtemplate msg;
	struct nlattr *na;
	int cnt, prv_len;
	int r, buflen;
	char *buf;

	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	msg.n.nlmsg_type = nlmsg_type;
	msg.n.nlmsg_flags = flags;
	msg.n.nlmsg_seq = 0;
	msg.n.nlmsg_pid = nlmsg_pid;
	msg.g.cmd = genl_cmd;
	msg.g.version = 0x1;

	prv_len = 0;
	for (cnt = 0; cnt < nla_num; cnt++) {
		na = (struct nlattr *)(GENLMSG_DATA(&msg) + prv_len);
		na->nla_type = nla_type[cnt];
		na->nla_len = nla_len[cnt] + NLA_HDRLEN;

		if (nla_len[cnt] > 0)
			memcpy(NLA_DATA(na), nla_data[cnt], nla_len[cnt]);

		prv_len = NLA_ALIGN(nla_len[cnt]) + NLA_HDRLEN;
		msg.n.nlmsg_len += prv_len;
	}

	buf = (char *)&msg;
	buflen = msg.n.nlmsg_len;
	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;

	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *)&nladdr,
			   sizeof(nladdr))) < buflen) {
		if (r > 0) {
			buf += r;
			buflen -= r;
		} else if (errno != EAGAIN) {
			return -1;
		}
	}
	return 0;
}

static int send_get_nfc_family(int sd, __u32 pid)
{
	__u16 nla_get_family_type = CTRL_ATTR_FAMILY_NAME;
	void *nla_get_family_data;
	int nla_get_family_len;
	char family_name[100];

	nla_get_family_len = strlen(NFC_GENL_NAME) + 1;
	strcpy(family_name, NFC_GENL_NAME);
	nla_get_family_data = family_name;

	return send_cmd_mt_nla(sd, GENL_ID_CTRL, pid, CTRL_CMD_GETFAMILY,
				1, &nla_get_family_type, &nla_get_family_data,
				&nla_get_family_len, NLM_F_REQUEST);

Annotation

Implementation Notes