示例#1
0
/**
 * mnl_nlmsg_fprintf - print netlink message to file
 * \param fd pointer to file type
 * \param data pointer to the buffer that contains messages to be printed
 * \param datalen length of data stored in the buffer
 * \param extra_header_size size of the extra header (if any)
 *
 * This function prints the netlink header to a file handle.
 * It may be useful for debugging purposes. One example of the output
 * is the following:
 *
 *\verbatim
----------------        ------------------
|  0000000040  |        | message length |
| 00016 | R-A- |        |  type | flags  |
|  1289148991  |        | sequence number|
|  0000000000  |        |     port ID    |
----------------        ------------------
| 00 00 00 00  |        |  extra header  |
| 00 00 00 00  |        |  extra header  |
| 01 00 00 00  |        |  extra header  |
| 01 00 00 00  |        |  extra header  |
|00008|--|00003|        |len |flags| type|
| 65 74 68 30  |        |      data      |       e t h 0
----------------        ------------------
\endverbatim
 *
 * This example above shows the netlink message that is send to kernel-space
 * to set up the link interface eth0. The netlink and attribute header data
 * are displayed in base 10 whereas the extra header and the attribute payload
 * are expressed in base 16. The possible flags in the netlink header are:
 *
 * - R, that indicates that NLM_F_REQUEST is set.
 * - M, that indicates that NLM_F_MULTI is set.
 * - A, that indicates that NLM_F_ACK is set.
 * - E, that indicates that NLM_F_ECHO is set.
 *
 * The lack of one flag is displayed with '-'. On the other hand, the possible
 * attribute flags available are:
 *
 * - N, that indicates that NLA_F_NESTED is set.
 * - B, that indicates that NLA_F_NET_BYTEORDER is set.
 */
void
mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen,
		  size_t extra_header_size)
{
	const struct nlmsghdr *nlh = data;
	int len = datalen;

	while (mnl_nlmsg_ok(nlh, len)) {
		mnl_nlmsg_fprintf_header(fd, nlh);
		mnl_nlmsg_fprintf_payload(fd, nlh, extra_header_size);
		nlh = mnl_nlmsg_next(nlh, &len);
	}
}
示例#2
0
//libuv dgram socket callback. Only checks if message is of right type and then
//call function for parsing message
static void neat_linux_nl_recv(uv_udp_t *handle, ssize_t nread,
        const uv_buf_t *buf, const struct sockaddr *addr, unsigned int flags)
{
    struct neat_ctx *nc = (struct neat_ctx*) handle->data;
    struct nlmsghdr *nl_hdr = (struct nlmsghdr*) buf->base;
    //We don't need any check here, we don't read more than 8192 bytes in one go
    int numbytes = (int) nread;

    while (mnl_nlmsg_ok(nl_hdr, numbytes)) {
        if (nl_hdr->nlmsg_type == RTM_NEWADDR ||
            nl_hdr->nlmsg_type == RTM_DELADDR)
            neat_linux_handle_addr(nc, nl_hdr);  
       
        nl_hdr = mnl_nlmsg_next(nl_hdr, &numbytes);
    }
}
示例#3
0
static inline int
__mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
	     unsigned int portid, mnl_cb_t cb_data, void *data,
	     mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
{
	int ret = MNL_CB_OK, len = numbytes;
	const struct nlmsghdr *nlh = buf;

	while (mnl_nlmsg_ok(nlh, len)) {
		/* check message source */
		if (!mnl_nlmsg_portid_ok(nlh, portid)) {
			errno = ESRCH;
			return -1;
		}
		/* perform sequence tracking */
		if (!mnl_nlmsg_seq_ok(nlh, seq)) {
			errno = EPROTO;
			return -1;
		}

		/* netlink data message handling */
		if (nlh->nlmsg_type >= NLMSG_MIN_TYPE) { 
			if (cb_data){
				ret = cb_data(nlh, data);
				if (ret <= MNL_CB_STOP)
					goto out;
			}
		} else if (nlh->nlmsg_type < cb_ctl_array_len) {
			if (cb_ctl_array && cb_ctl_array[nlh->nlmsg_type]) {
				ret = cb_ctl_array[nlh->nlmsg_type](nlh, data);
				if (ret <= MNL_CB_STOP)
					goto out;
			}
		} else if (default_cb_array[nlh->nlmsg_type]) {
			ret = default_cb_array[nlh->nlmsg_type](nlh, data);
			if (ret <= MNL_CB_STOP)
				goto out;
		}
		nlh = mnl_nlmsg_next(nlh, &len);
	}
out:
	return ret;
}