static gboolean event_connection_setup (NMNetlinkMonitor *self, GError **error) { NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); GError *channel_error = NULL; GIOFlags channel_flags; int fd; g_return_val_if_fail (priv->io_channel == NULL, FALSE); /* Set up the event listener connection */ priv->nlh_event = nl_socket_alloc (); if (!priv->nlh_event) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), nl_geterror (ENOMEM)); goto error; } if (!nlh_setup (priv->nlh_event, event_msg_ready, self, error)) goto error; nl_socket_disable_seq_check (priv->nlh_event); /* Subscribe to the LINK group for internal carrier signals */ if (!nm_netlink_monitor_subscribe (self, RTNLGRP_LINK, error)) goto error; fd = nl_socket_get_fd (priv->nlh_event); priv->io_channel = g_io_channel_unix_new (fd); g_io_channel_set_encoding (priv->io_channel, NULL, &channel_error); /* Encoding is NULL, so no conversion error can possibly occur */ g_assert (channel_error == NULL); g_io_channel_set_close_on_unref (priv->io_channel, TRUE); channel_flags = g_io_channel_get_flags (priv->io_channel); channel_error = NULL; g_io_channel_set_flags (priv->io_channel, channel_flags | G_IO_FLAG_NONBLOCK, &channel_error); if (channel_error != NULL) { g_propagate_error (error, channel_error); goto error; } return TRUE; error: if (priv->io_channel) nm_netlink_monitor_close_connection (self); if (priv->nlh_event) { nl_socket_free (priv->nlh_event); priv->nlh_event = NULL; } return FALSE; }
/** * Allocate new cache manager * @arg sk Netlink socket or NULL to auto allocate * @arg protocol Netlink protocol this manager is used for * @arg flags Flags (\c NL_AUTO_PROVIDE) * @arg result Result pointer * * Allocates a new cache manager for the specified netlink protocol. * * 1. If sk is not specified (\c NULL) a netlink socket matching the * specified protocol will be automatically allocated. * * 2. The socket will be put in non-blocking mode and sequence checking * will be disabled regardless of whether the socket was provided by * the caller or automatically allocated. * * 3. The socket will be connected. * * If the flag \c NL_AUTO_PROVIDE is specified, any cache added to the * manager will automatically be made available to other users using * nl_cache_mngt_provide(). * * @note If the socket is provided by the caller, it is NOT recommended * to use the socket for anything else besides receiving netlink * notifications. * * @return 0 on success or a negative error code. */ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags, struct nl_cache_mngr **result) { struct nl_cache_mngr *mngr; int err = -NLE_NOMEM; /* Catch abuse of flags */ if (flags & NL_ALLOCATED_SOCK) BUG(); mngr = calloc(1, sizeof(*mngr)); if (!mngr) return -NLE_NOMEM; if (!sk) { if (!(sk = nl_socket_alloc())) goto errout; flags |= NL_ALLOCATED_SOCK; } mngr->cm_sock = sk; mngr->cm_nassocs = NASSOC_INIT; mngr->cm_protocol = protocol; mngr->cm_flags = flags; mngr->cm_assocs = calloc(mngr->cm_nassocs, sizeof(struct nl_cache_assoc)); if (!mngr->cm_assocs) goto errout; /* Required to receive async event notifications */ nl_socket_disable_seq_check(mngr->cm_sock); if ((err = nl_connect(mngr->cm_sock, protocol)) < 0) goto errout; if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0) goto errout; /* Create and allocate socket for sync cache fills */ mngr->cm_sync_sock = nl_socket_alloc(); if (!mngr->cm_sync_sock) { err = -NLE_NOMEM; goto errout; } if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0) goto errout_free_sync_sock; NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n", mngr, protocol, mngr->cm_nassocs); *result = mngr; return 0; errout_free_sync_sock: nl_socket_free(mngr->cm_sync_sock); errout: nl_cache_mngr_free(mngr); return err; }
int iface_mon_start(iface_mon_cb cb) { int err; iface_mon_sock = nl_socket_alloc(); if (!iface_mon_sock) { fprintf(stderr, "Failed to allocate netlink socket.\n"); return -ENOMEM; } nl_socket_disable_seq_check(iface_mon_sock); nl_socket_modify_cb(iface_mon_sock, NL_CB_VALID, NL_CB_CUSTOM, iface_mon_handler, cb); if (nl_connect(iface_mon_sock, NETLINK_ROUTE)) { fprintf(stderr, "Failed to connect to generic netlink.\n"); err = -ENOLINK; goto out_handle_destroy; } nl_socket_add_membership(iface_mon_sock, RTNLGRP_LINK); return 0; out_handle_destroy: nl_socket_free(iface_mon_sock); return err; }
static bool nl_new(struct dionaea *d) { g_debug("%s", __PRETTY_FUNCTION__); nl_runtime.sock = nl_socket_alloc(); struct nl_sock *sock = nl_runtime.sock; nl_socket_disable_seq_check(sock); nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, nl_event_input, NULL); nl_join_groups(sock, RTMGRP_LINK); int err; if ( (err = nl_connect(sock, NETLINK_ROUTE)) < 0) { g_error("Could not connect netlink (%s)", nl_geterror(err)); } nl_socket_add_membership(sock, RTNLGRP_LINK); nl_socket_add_membership(sock, RTNLGRP_NEIGH); nl_socket_add_membership(sock, RTNLGRP_IPV4_IFADDR); nl_socket_add_membership(sock, RTNLGRP_IPV6_IFADDR); if( (err=rtnl_neigh_alloc_cache(sock, &nl_runtime.neigh_cache)) != 0 ) { g_error("Could not allocate neigh cache! (%s)", nl_geterror(err)); } #if LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 3 if( (err=rtnl_link_alloc_cache(sock, AF_UNSPEC, &nl_runtime.link_cache)) != 0 ) #elif LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 2 if( (err=rtnl_link_alloc_cache(sock, &nl_runtime.link_cache)) != 0 ) #endif { g_error("Could not allocate link cache! (%s)", nl_geterror(err)); } if( (err=rtnl_addr_alloc_cache(sock, &nl_runtime.addr_cache)) != 0 ) { g_error("Could not allocate addr cache! (%s)", nl_geterror(err)); } nl_cache_mngt_provide(nl_runtime.neigh_cache); nl_cache_mngt_provide(nl_runtime.link_cache); nl_cache_mngt_provide(nl_runtime.addr_cache); nl_runtime.ihandler = ihandler_new("dionaea.connection.*.accept", nl_ihandler_cb, NULL); ev_io_init(&nl_runtime.io_in, nl_io_in_cb, nl_socket_get_fd(sock), EV_READ); ev_io_start(g_dionaea->loop, &nl_runtime.io_in); nl_runtime.link_addr_cache = g_hash_table_new(g_int_hash, g_int_equal); nl_cache_foreach(nl_runtime.link_cache, nl_obj_input, NULL); nl_cache_foreach(nl_runtime.addr_cache, nl_obj_input, NULL); return true; }
int main() { struct nl_sock * sk; int cbarg; // nl_debug = 4; // setup netlink socket sk = nl_socket_alloc(); nl_socket_disable_seq_check(sk); // disable sequence number check genl_connect(sk); int id = genl_ctrl_resolve(sk, DEMO_FAMILY_NAME); struct nl_msg * msg; // create a messgae msg = nlmsg_alloc(); genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, id, 0, // hdrlen 0, // flags DEMO_CMD, // numeric command identifier DEMO_VERSION // interface version ); nla_put_string(msg, DEMO_ATTR1_STRING, "hola"); nla_put_u16(msg, DEMO_ATTR2_UINT16, 0xf1); // send it nl_send_auto(sk, msg); // handle reply struct nl_cb * cb = NULL; cb = nl_cb_alloc(NL_CB_CUSTOM); //nl_cb_set_all(cb, NL_CB_DEBUG, NULL, NULL); nl_cb_set_all(cb, NL_CB_CUSTOM, cb_handler, &cbarg); nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL); int nrecv = nl_recvmsgs_report(sk, cb); printf("cbarg %d nrecv %d\n", cbarg, nrecv); // cleanup nlmsg_free(msg); nl_close(sk); nl_socket_free(sk); return 0; }
int setup_socket(struct nl_sock *sk, struct options *opt) { int ret; nl_socket_disable_seq_check(sk); if((ret = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, netlink_msg_handler, opt)) < 0) return ret; if((ret = nl_connect(sk, NETLINK_ROUTE)) < 0) return ret; if((ret = nl_socket_add_memberships(sk, RTNLGRP_TC_STATS, 0)) < 0) return ret; return 0; }
/** * Allocate new cache manager * @arg sk Netlink socket. * @arg protocol Netlink Protocol this manager is used for * @arg flags Flags * @arg result Result pointer * * @return 0 on success or a negative error code. */ int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags, struct nl_cache_mngr **result) { struct nl_cache_mngr *mngr; int err = -NLE_NOMEM; if (sk == NULL) BUG(); mngr = calloc(1, sizeof(*mngr)); if (!mngr) goto errout; mngr->cm_handle = sk; mngr->cm_nassocs = 32; mngr->cm_protocol = protocol; mngr->cm_flags = flags; mngr->cm_assocs = calloc(mngr->cm_nassocs, sizeof(struct nl_cache_assoc)); if (!mngr->cm_assocs) goto errout; nl_socket_modify_cb(mngr->cm_handle, NL_CB_VALID, NL_CB_CUSTOM, event_input, mngr); /* Required to receive async event notifications */ nl_socket_disable_seq_check(mngr->cm_handle); if ((err = nl_connect(mngr->cm_handle, protocol) < 0)) goto errout; if ((err = nl_socket_set_nonblocking(mngr->cm_handle) < 0)) goto errout; NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n", mngr, protocol, mngr->cm_nassocs); *result = mngr; return 0; errout: nl_cache_mngr_free(mngr); return err; }
int ompi_btl_usnic_rtnl_sk_alloc(struct usnic_rtnl_sk **p_sk) { struct usnic_rtnl_sk *unlsk; struct nl_sock *sock; int err; unlsk = calloc(1, sizeof(*unlsk)); if (!unlsk) { usnic_err("Failed to allocate usnic_rtnl_sk struct\n"); return -ENOMEM; } sock = nl_socket_alloc(); if (!sock) { usnic_err("Failed to allocate nl socket\n"); err = -ENOMEM; goto err_free_unlsk; } err = nl_connect(sock, NETLINK_ROUTE); if (err < 0) { usnic_err("Failed to connnect netlink route socket\n"); goto err_free_sk; } nl_socket_disable_seq_check(sock); err = nl_set_recv_timeout(sock); if (err < 0) goto err_close_nlsk; unlsk->sock = sock; unlsk->seq = time(NULL); *p_sk = unlsk; return 0; err_close_nlsk: nl_close(sock); err_free_sk: nl_socket_free(sock); err_free_unlsk: free(unlsk); return err; }
static ni_socket_t * __ni_rtevent_sock_open(void) { unsigned int recv_buff_len = __ni_rtevent_config_recv_buff_len(); unsigned int mesg_buff_len = __ni_rtevent_config_mesg_buff_len(); ni_rtevent_handle_t *handle; ni_socket_t *sock; int fd, ret; if (!(handle = __ni_rtevent_handle_new())) { ni_error("Unable to allocate rtnetlink event handle: %m"); return NULL; } if (!(handle->nlsock = nl_socket_alloc())) { ni_error("Cannot allocate rtnetlink event socket: %m"); __ni_rtevent_handle_free(handle); return NULL; } /* * Modify the callback for processing valid messages... * We may pass some kind of data (event filter?) too... */ nl_socket_modify_cb(handle->nlsock, NL_CB_VALID, NL_CB_CUSTOM, __ni_rtevent_process_cb, NULL); /* Required to receive async event notifications */ nl_socket_disable_seq_check(handle->nlsock); if ((ret = nl_connect(handle->nlsock, NETLINK_ROUTE)) < 0) { ni_error("Cannot open rtnetlink: %s", nl_geterror(ret)); __ni_rtevent_handle_free(handle); return NULL; } /* Enable non-blocking processing */ nl_socket_set_nonblocking(handle->nlsock); fd = nl_socket_get_fd(handle->nlsock); if (!(sock = ni_socket_wrap(fd, SOCK_DGRAM))) { ni_error("Cannot wrap rtnetlink event socket: %m"); __ni_rtevent_handle_free(handle); return NULL; } if (recv_buff_len) { if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, (char *)&recv_buff_len, sizeof(recv_buff_len)) && setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buff_len, sizeof(recv_buff_len))) { ni_warn("Unable to set netlink event receive buffer to %u bytes: %m", recv_buff_len); } else { ni_info("Using netlink event receive buffer of %u bytes", recv_buff_len); } } if (mesg_buff_len) { if (nl_socket_set_msg_buf_size(handle->nlsock, mesg_buff_len)) { ni_warn("Unable to set netlink event message buffer to %u bytes", mesg_buff_len); } else { ni_info("Using netlink event message buffer of %u bytes", mesg_buff_len); } } sock->user_data = handle; sock->receive = __ni_rtevent_receive; sock->close = __ni_rtevent_close; sock->handle_error = __ni_rtevent_sock_error_handler; sock->release_user_data = __ni_rtevent_sock_release_data; return sock; }
static struct nl_addr *process_get_neigh_mac( struct get_neigh_handler *neigh_handler) { int err; struct nl_addr *ll_addr = get_neigh_mac(neigh_handler); struct rtnl_neigh *neigh_filter; fd_set fdset; int sock_fd; int fd; int nfds; int timer_fd; int ret; struct skt addr_dst; char buff[sizeof(SEND_PAYLOAD)] = SEND_PAYLOAD; int retries = 0; if (NULL != ll_addr) return ll_addr; err = nl_socket_add_membership(neigh_handler->sock, RTNLGRP_NEIGH); if (err < 0) return NULL; neigh_filter = create_filter_neigh_for_dst(neigh_handler->dst, neigh_handler->oif); if (neigh_filter == NULL) return NULL; set_neigh_filter(neigh_handler, neigh_filter); nl_socket_disable_seq_check(neigh_handler->sock); nl_socket_modify_cb(neigh_handler->sock, NL_CB_VALID, NL_CB_CUSTOM, &get_neigh_cb, neigh_handler); fd = nl_socket_get_fd(neigh_handler->sock); err = create_socket(neigh_handler, &addr_dst, &sock_fd); if (err) return NULL; err = try_send_to(sock_fd, buff, sizeof(buff), &addr_dst); if (err) goto close_socket; timer_fd = create_timer(neigh_handler); if (timer_fd < 0) goto close_socket; nfds = MAX(fd, timer_fd) + 1; while (1) { FD_ZERO(&fdset); FD_SET(fd, &fdset); FD_SET(timer_fd, &fdset); /* wait for an incoming message on the netlink socket */ ret = select(nfds, &fdset, NULL, NULL, NULL); if (ret == -1) { goto select_err; } else if (ret) { if (FD_ISSET(fd, &fdset)) { nl_recvmsgs_default(neigh_handler->sock); if (neigh_handler->found_ll_addr) break; } else { nl_cache_refill(neigh_handler->sock, neigh_handler->neigh_cache); ll_addr = get_neigh_mac(neigh_handler); if (NULL != ll_addr) { break; } else if (FD_ISSET(timer_fd, &fdset) && retries < NUM_OF_RETRIES) { try_send_to(sock_fd, buff, sizeof(buff), &addr_dst); } } if (FD_ISSET(timer_fd, &fdset)) { uint64_t read_val; ssize_t rc; rc = read(timer_fd, &read_val, sizeof(read_val)); assert(rc == sizeof(read_val)); if (++retries >= NUM_OF_TRIES) { if (!errno) errno = EDESTADDRREQ; break; } } } } select_err: close(timer_fd); close_socket: close(sock_fd); return ll_addr ? ll_addr : neigh_handler->found_ll_addr; }
static void obj_input(struct nl_object *obj, void *arg) { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nl_object_dump(obj, &dp); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<<EVENT>> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *nf_sock; struct nl_sock *rt_sock; struct nl_cache *link_cache; struct nfnl_log *log; enum nfnl_log_copy_mode copy_mode; uint32_t copy_range; int err; int family; nf_sock = nl_cli_alloc_socket(); nl_socket_disable_seq_check(nf_sock); nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) { printf("Usage: nf-log family group [ copy_mode ] " "[copy_range] \n"); return 2; } nl_cli_connect(nf_sock, NETLINK_NETFILTER); family = nl_str2af(argv[1]); if (family == AF_UNSPEC) nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\": %s", argv[1], nl_geterror(family)); nfnl_log_pf_unbind(nf_sock, family); if ((err = nfnl_log_pf_bind(nf_sock, family)) < 0) nl_cli_fatal(err, "Unable to bind logger: %s", nl_geterror(err)); log = alloc_log(); nfnl_log_set_group(log, atoi(argv[2])); copy_mode = NFNL_LOG_COPY_META; if (argc > 3) { copy_mode = nfnl_log_str2copy_mode(argv[3]); if (copy_mode < 0) nl_cli_fatal(copy_mode, "Unable to parse copy mode \"%s\": %s", argv[3], nl_geterror(copy_mode)); } nfnl_log_set_copy_mode(log, copy_mode); copy_range = 0xFFFF; if (argc > 4) copy_mode = atoi(argv[4]); nfnl_log_set_copy_range(log, copy_range); if ((err = nfnl_log_create(nf_sock, log)) < 0) nl_cli_fatal(err, "Unable to bind instance: %s", nl_geterror(err)); { struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; printf("log params: "); nl_object_dump((struct nl_object *) log, &dp); } rt_sock = nl_cli_alloc_socket(); nl_cli_connect(rt_sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(rt_sock); while (1) { fd_set rfds; int nffd, rtfd, maxfd, retval; FD_ZERO(&rfds); maxfd = nffd = nl_socket_get_fd(nf_sock); FD_SET(nffd, &rfds); rtfd = nl_socket_get_fd(rt_sock); FD_SET(rtfd, &rfds); if (maxfd < rtfd) maxfd = rtfd; /* wait for an incoming message on the netlink nf_socket */ retval = select(maxfd+1, &rfds, NULL, NULL, NULL); if (retval) { if (FD_ISSET(nffd, &rfds)) nl_recvmsgs_default(nf_sock); if (FD_ISSET(rtfd, &rfds)) nl_recvmsgs_default(rt_sock); } } return 0; }
static void obj_input(struct nl_object *obj, void *arg) { struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) obj; struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nfnl_queue_msg_set_verdict(msg, NF_ACCEPT); nl_object_dump(obj, &dp); nfnl_queue_msg_send_verdict(nf_sock, msg); } static int event_input(struct nl_msg *msg, void *arg) { if (nl_msg_parse(msg, &obj_input, NULL) < 0) fprintf(stderr, "<<EVENT>> Unknown message type\n"); /* Exit nl_recvmsgs_def() and return to the main select() */ return NL_STOP; } int main(int argc, char *argv[]) { struct nl_sock *rt_sock; struct nl_cache *link_cache; struct nfnl_queue *queue; enum nfnl_queue_copy_mode copy_mode; uint32_t copy_range; int err = 1; int family; nf_sock = nfnl_queue_socket_alloc(); if (nf_sock == NULL) nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket"); nl_socket_disable_seq_check(nf_sock); nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) { printf("Usage: nf-queue family group [ copy_mode ] " "[ copy_range ]\n"); printf("family: [ inet | inet6 | ... ] \n"); printf("group: the --queue-num arg that you gave to iptables\n"); printf("copy_mode: [ none | meta | packet ] \n"); return 2; } nl_cli_connect(nf_sock, NETLINK_NETFILTER); if ((family = nl_str2af(argv[1])) == AF_UNSPEC) nl_cli_fatal(NLE_INVAL, "Unknown family \"%s\"", argv[1]); nfnl_queue_pf_unbind(nf_sock, family); if ((err = nfnl_queue_pf_bind(nf_sock, family)) < 0) nl_cli_fatal(err, "Unable to bind logger: %s", nl_geterror(err)); queue = alloc_queue(); nfnl_queue_set_group(queue, atoi(argv[2])); copy_mode = NFNL_QUEUE_COPY_PACKET; if (argc > 3) { copy_mode = nfnl_queue_str2copy_mode(argv[3]); if (copy_mode < 0) nl_cli_fatal(copy_mode, "Unable to parse copy mode \"%s\": %s", argv[3], nl_geterror(copy_mode)); } nfnl_queue_set_copy_mode(queue, copy_mode); copy_range = 0xFFFF; if (argc > 4) copy_range = atoi(argv[4]); nfnl_queue_set_copy_range(queue, copy_range); if ((err = nfnl_queue_create(nf_sock, queue)) < 0) nl_cli_fatal(err, "Unable to bind queue: %s", nl_geterror(err)); rt_sock = nl_cli_alloc_socket(); nl_cli_connect(rt_sock, NETLINK_ROUTE); link_cache = nl_cli_link_alloc_cache(rt_sock); nl_socket_set_buffer_size(nf_sock, 1024*127, 1024*127); while (1) { fd_set rfds; int nffd, rtfd, maxfd, retval; FD_ZERO(&rfds); maxfd = nffd = nl_socket_get_fd(nf_sock); FD_SET(nffd, &rfds); rtfd = nl_socket_get_fd(rt_sock); FD_SET(rtfd, &rfds); if (maxfd < rtfd) maxfd = rtfd; /* wait for an incoming message on the netlink socket */ retval = select(maxfd+1, &rfds, NULL, NULL, NULL); if (retval) { if (FD_ISSET(nffd, &rfds)) nl_recvmsgs_default(nf_sock); if (FD_ISSET(rtfd, &rfds)) nl_recvmsgs_default(rt_sock); } } return 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_sock *sk; 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; sk = nl_socket_alloc(); nl_socket_set_buffer_size(sk, 15000000, 15000000); //nl_handle_set_peer_pid(hndl, 0); //nl_set_passcred(hndl, 1); nl_socket_disable_seq_check(sk); if ( (ret_val=nl_connect(sk, NETLINK_GENERIC)) ) goto init_return; if ( (ret_val=prepare_request_message(sk, 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(sk, msg, 0) ) != 0 ) goto init_return; if ( (ret_val = read_message(sk, &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; } printf("Initialization netlink family OK\n"); state.sk = sk; return 0; init_return: nlmsg_free(ans_msg); if ( state.sk == NULL ) { nl_close(sk); nl_socket_free(sk); } return -EINVAL; }