Esempio n. 1
0
File: nl.c Progetto: ebichu/dd-wrt
/**
 * Create a netlink socket and connect to it kernel.
 * @arg handle		netlink handle
 * @arg protocol	desired netlink protocol
 *
 * Creates a netlink socket of the desired \c protocol and connects it
 * to the kernel.
 *
 * @note nl_handle::local::nl_groups may contain a multicast group mask.
 * @exception EADDRNOTAVAIL Invalid address length
 * @exception EPFNOSUPPORT Address format not supported
 */
int nl_connect(struct nl_handle *handle, int protocol)
{
	int err;
	socklen_t addrlen;

	nl_init_handle(handle);

	if ((handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol)) < 0)
		return nl_error(1, "socket(AF_NETLINK, ...) failed");

	if ((err = nl_set_buffer_size(handle, 0, 0)) < 0)
		return err;

	err = bind(handle->h_fd, (struct sockaddr*) &handle->h_local,
			sizeof(handle->h_local));
	if (err < 0)
		return nl_error(1, "bind() failed");

	addrlen = sizeof(handle->h_local);

	err = getsockname(handle->h_fd, (struct sockaddr *) &handle->h_local,
			&addrlen);
	if (err < 0)
		return nl_error(1, "getsockname failed");

	if (addrlen != sizeof(handle->h_local))
		return nl_error(EADDRNOTAVAIL, "Invalid address length");

	if (handle->h_local.nl_family != AF_NETLINK)
		return nl_error(EPFNOSUPPORT, "Address format not supported");

	return 0;
}
Esempio n. 2
0
static inline int nl_socket_set_buffer_size(struct nl_sock *sk,
					    int rxbuf, int txbuf)
{
	return nl_set_buffer_size(sk, rxbuf, txbuf);
}
Esempio n. 3
0
/** 
 * Setups generic netlink connection with the kernel module and retrieves assocaited family id
 *
 * @return 0 on success
 */
static int initialize_netlink_family(void) {
	struct nl_handle* hndl;
	struct nl_msg* msg = NULL;
	struct nl_msg *ans_msg = NULL;
	struct nlmsghdr *nl_hdr;
	struct genlmsghdr* genl_hdr;
	struct nlattr *nla;
	int ret_val = 0;

	hndl = nl_handle_alloc();
	nl_set_buffer_size(hndl, 15000000, 15000000);
	
	//nl_handle_set_peer_pid(hndl, 0);
	//nl_set_passcred(hndl, 1);
	nl_disable_sequence_check(hndl);

	if ( (ret_val=nl_connect(hndl, NETLINK_GENERIC)) )
		goto init_return;
	
	nl_set_buffer_size(hndl, 15000000, 15000000);
  
	if ( (ret_val=prepare_request_message(hndl, CTRL_CMD_GETFAMILY, GENL_ID_CTRL, &msg) ) != 0 ) {
		goto init_return;
  	}
  
	ret_val = nla_put_string(msg,
		   CTRL_ATTR_FAMILY_NAME,
		   "DIRECTORCHNL");

  	if (ret_val != 0)
		goto init_return;

	if ( (ret_val = send_request_message(hndl, msg, 0) ) != 0 )
		goto init_return;
	if ( (ret_val = read_message(hndl, &ans_msg) ) != 0 )
		goto init_return;

	genl_hdr = nl_msg_genlhdr(ans_msg);
 	if (genl_hdr == NULL || genl_hdr->cmd != CTRL_CMD_NEWFAMILY) {
    		ret_val = -EBADMSG;
    		goto init_return;
  	}

	nla = nlmsg_find_attr(nlmsg_hdr(ans_msg), sizeof(struct genlmsghdr), CTRL_ATTR_FAMILY_ID);
  	if (nla == NULL) {
    		ret_val = -EBADMSG;
    		goto init_return;
  	}

  	state.gnl_fid = nla_get_u16(nla);  
  	if (state.gnl_fid == 0) {
    		ret_val = -EBADMSG;
    		goto init_return;
  	}
  	  	

  	state.handle = hndl;

	return 0;

init_return:
	nlmsg_free(ans_msg);
	
	if ( state.handle == NULL ) {
		nl_close(hndl);
		nl_handle_destroy(hndl);
  	}

	return -EINVAL;
}