int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "eno16777736"); if (!if_index) { fprintf(stderr, "Unable to lookup eno16777736"); return -1; } link = rtnl_link_sit_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "sit-tun"); rtnl_link_sit_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_sit_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_sit_set_remote(link, addr.s_addr); rtnl_link_sit_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in6_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "ens33"); if (!if_index) { fprintf(stderr, "Unable to lookup ens33"); return -1; } link = rtnl_link_ip6_tnl_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ip6tnl-tun"); rtnl_link_ip6_tnl_set_link(link, if_index); inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr); rtnl_link_ip6_tnl_set_local(link, &addr); inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr); rtnl_link_ip6_tnl_set_remote(link, &addr); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
int init_handle(struct nl_handle **handle) { *handle = nl_handle_alloc(); if (!*handle) return -1; if (nl_connect(*handle, NETLINK_ROUTE)) { nl_handle_destroy(*handle); return -1; } return 0; }
void NetLinkManager::run() { struct nl_handle *handle = nl_handle_alloc(); nl_connect(handle, NETLINK_ROUTE); // init route messages nl_socket_add_membership(handle, RTNLGRP_IPV4_IFADDR); // IPv6 requires further support in the parsing procedures! // nl_socket_add_membership(handle, RTNLGRP_IPV6_IFADDR); nl_socket_add_membership(handle, RTNLGRP_LINK); // add netlink fd to vsocket _sock->add(nl_socket_get_fd(handle)); try { while (_initialized) { std::list<int> fds; _sock->select(fds, NULL); int fd = fds.front(); // create a new event object NetLinkManagerEvent lme(fd); // ignore if the event is unknown if (lme.getType() == LinkManagerEvent::EVENT_UNKOWN) continue; // ignore if this is an wireless extension event if (lme.isWirelessExtension()) continue; // need to refresh the cache { ibrcommon::MutexLock l(_call_mutex); _refresh_cache = true; } // print out some debugging IBRCOMMON_LOGGER_DEBUG(10) << lme.toString() << IBRCOMMON_LOGGER_ENDL; // notify all subscribers about this event raiseEvent(lme); } } catch (const vsocket_exception&) { // stopped / interrupted IBRCOMMON_LOGGER(error) << "NetLink connection stopped" << IBRCOMMON_LOGGER_ENDL; } nl_close(handle); nl_handle_destroy(handle); }
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; }
/* * Return a libnl handle for NETLINK_ROUTE. */ static struct nl_handle *_iface_get_handle(void) { struct nl_handle *handle = NULL; if ((handle = nl_handle_alloc()) == NULL) { return NULL; } if (nl_connect(handle, NETLINK_ROUTE)) { nl_handle_destroy(handle); return NULL; } return handle; }
int vlan_rem(const char *if_name) { int ret = -1; struct nl_sock *handle = NULL; struct nl_cache *cache = NULL; struct rtnl_link *rlink = NULL; wpa_printf(MSG_DEBUG, "VLAN: vlan_rem(if_name=%s)", if_name); handle = nl_socket_alloc(); if (!handle) { wpa_printf(MSG_ERROR, "VLAN: failed to open netlink socket"); goto vlan_rem_error; } if (nl_connect(handle, NETLINK_ROUTE) < 0) { wpa_printf(MSG_ERROR, "VLAN: failed to connect to netlink"); goto vlan_rem_error; } if (rtnl_link_alloc_cache(handle, AF_UNSPEC, &cache) < 0) { cache = NULL; wpa_printf(MSG_ERROR, "VLAN: failed to alloc cache"); goto vlan_rem_error; } if (!(rlink = rtnl_link_get_by_name(cache, if_name))) { /* link does not exist */ wpa_printf(MSG_ERROR, "VLAN: interface %s does not exists", if_name); goto vlan_rem_error; } if (rtnl_link_delete(handle, rlink) < 0) { wpa_printf(MSG_ERROR, "VLAN: failed to remove link %s", if_name); goto vlan_rem_error; } ret = 0; vlan_rem_error: if (rlink) rtnl_link_put(rlink); if (cache) nl_cache_free(cache); if (handle) nl_socket_free(handle); return ret; }
struct nl_cache *link_cache_alloc(struct nl_sock **sock) { struct nl_cache *cache = NULL; assert(sock); *sock = nl_socket_alloc(); if (!sock || nl_connect(*sock, NETLINK_ROUTE) || rtnl_link_alloc_cache(*sock, AF_UNSPEC, &cache)) return NULL; return cache; }
/** * 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; 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 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; }
static int init_nl(void) { /* Allocate and initialize a new netlink handle */ if (!(nl_sock = nl_socket_alloc())) { syslog(LOG_ERR, "Failed to alloc netlink socket\n"); return -EOPNOTSUPP; } /* Bind and connect socket to protocol, NETLINK_ROUTE in our case. */ if (nl_connect(nl_sock, NETLINK_ROUTE) < 0) { syslog(LOG_ERR, "Failed to connect to kernel\n"); return -EOPNOTSUPP; } return 0; }
TError TNl::Connect() { int ret; TError error; Sock = nl_socket_alloc(); if (!Sock) return TError(EError::Unknown, "Cannot allocate netlink socket"); ret = nl_connect(Sock, NETLINK_ROUTE); if (ret < 0) { nl_socket_free(Sock); return Error(ret, "Cannot connect netlink socket"); } return TError::Success(); }
static int netlink3_reset_interface_parameters(const interface_t* ifp) { struct nl_sock *sk; struct nl_cache *cache; struct rtnl_link *link = NULL; struct rtnl_link *new_state = NULL; int res = 0; if (!(sk = nl_socket_alloc())) { log_message(LOG_INFO, "Unable to open netlink socket"); return -1; } if (nl_connect(sk, NETLINK_ROUTE) < 0) goto err; if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &cache)) goto err; if (!(link = rtnl_link_get(cache, ifp->ifindex))) goto err; if (!(new_state = rtnl_link_alloc())) goto err; if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, ifp->reset_arp_ignore_value) || rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARPFILTER, ifp->reset_arp_filter_value) || rtnl_link_change(sk, link, new_state, 0)) goto err; rtnl_link_put(link); link = NULL; rtnl_link_put(new_state); new_state = NULL; goto exit; err: res = -1; if (link) rtnl_link_put(link); if (new_state) rtnl_link_put(new_state); exit: nl_socket_free(sk); return res; }
static int usnic_nl_sk_alloc(struct usnic_nl_sk **p_sk, int protocol) { struct usnic_nl_sk *unlsk; NL_HANDLE *nlh; int err; unlsk = calloc(1, sizeof(*unlsk)); if (!unlsk) { usnic_err("Failed to allocate usnic_nl_sk struct\n"); return ENOMEM; } nlh = NL_HANDLE_ALLOC(); if (!nlh) { usnic_err("Failed to allocate nl handle\n"); err = ENOMEM; goto err_free_unlsk; } err = nl_connect(nlh, protocol); if (err < 0) { usnic_err("Failed to connnect netlink route socket error: %s\n", NL_GETERROR(err)); err = EINVAL; goto err_free_nlh; } NL_DISABLE_SEQ_CHECK(nlh); err = usnic_nl_set_rcvsk_timer(nlh); if (err < 0) goto err_close_nlh; unlsk->nlh = nlh; unlsk->seq = time(NULL); *p_sk = unlsk; return 0; err_close_nlh: nl_close(nlh); err_free_nlh: NL_HANDLE_FREE(nlh); err_free_unlsk: free(unlsk); return err; }
// Returns a netlink socket for communicating with the kernel. This // socket is needed for most of the operations. The default protocol // of the netlink socket is NETLINK_ROUTE, but you can optionally // provide a different one. // TODO(chzhcn): Consider renaming 'routing' to 'netlink'. inline Try<Netlink<struct nl_sock>> socket(int protocol = NETLINK_ROUTE) { struct nl_sock* s = nl_socket_alloc(); if (s == nullptr) { return Error("Failed to allocate netlink socket"); } Netlink<struct nl_sock> sock(s); int error = nl_connect(sock.get(), protocol); if (error != 0) { return Error( "Failed to connect to netlink protocol: " + std::string(nl_geterror(error))); } return sock; }
int init_subkind_nic(libxl__checkpoint_devices_state *cds) { int rc, ret; libxl__domain_save_state *dss = CONTAINER_OF(cds, *dss, cds); libxl__remus_state *rs = cds->concrete_data; STATE_AO_GC(cds->ao); rs->nlsock = nl_socket_alloc(); if (!rs->nlsock) { LOGD(ERROR, dss->domid, "cannot allocate nl socket"); rc = ERROR_FAIL; goto out; } ret = nl_connect(rs->nlsock, NETLINK_ROUTE); if (ret) { LOGD(ERROR, dss->domid, "failed to open netlink socket: %s", nl_geterror(ret)); rc = ERROR_FAIL; goto out; } /* get list of all qdiscs installed on network devs. */ ret = rtnl_qdisc_alloc_cache(rs->nlsock, &rs->qdisc_cache); if (ret) { LOGD(ERROR, dss->domid, "failed to allocate qdisc cache: %s", nl_geterror(ret)); rc = ERROR_FAIL; goto out; } if (dss->remus->netbufscript) { rs->netbufscript = libxl__strdup(gc, dss->remus->netbufscript); } else { rs->netbufscript = GCSPRINTF("%s/remus-netbuf-setup", libxl__xen_script_dir_path()); } rc = 0; out: return rc; }
int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; struct nl_addr* addr; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } link = rtnl_link_macvtap_alloc(); rtnl_link_set_link(link, master_index); addr = nl_addr_build(AF_LLC, ether_aton("00:11:22:33:44:55"), ETH_ALEN); rtnl_link_set_addr(link, addr); nl_addr_put(addr); rtnl_link_macvtap_set_mode(link, rtnl_link_macvtap_str2mode("bridge")); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); 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 usnic_rtnl_sk_alloc(struct usnic_rtnl_sk **p_sk) { struct usnic_rtnl_sk *unlsk; struct nl_handle *nlh; int err; unlsk = calloc(1, sizeof(*unlsk)); if (!unlsk) { usnic_err("Failed to allocate usnic_rtnl_sk struct\n"); return -ENOMEM; } nlh = nl_handle_alloc(); if (!nlh) { usnic_err("Failed to allocate nl handle\n"); err = -ENOMEM; goto err_free_unlsk; } err = nl_connect(nlh, NETLINK_ROUTE); if (err < 0) { usnic_err("Failed to connnect netlink route socket\n"); goto err_free_nlh; } nl_disable_sequence_check(nlh); err = nl_set_recv_timeout(nlh); if (err < 0) goto err_close_nlh; unlsk->nlh = nlh; unlsk->seq = time(NULL); *p_sk = unlsk; return 0; err_close_nlh: nl_close(nlh); err_free_nlh: nl_handle_destroy(nlh); err_free_unlsk: free(unlsk); return err; }
static nl_sock * wifi_create_nl_socket(int port, int protocol) { // ALOGI("Creating socket"); struct nl_sock *sock = nl_socket_alloc(); if (sock == NULL) { ALOGE("Failed to create NL socket"); return NULL; } wifi_socket_set_local_port(sock, port); if (nl_connect(sock, protocol)) { ALOGE("Could not connect handle"); nl_socket_free(sock); return NULL; } return sock; }
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 struct nl_sock * setup_socket (void) { struct nl_sock *sk; int err; sk = nl_socket_alloc (); g_return_val_if_fail (sk, NULL); /* Only ever accept messages from kernel */ err = nl_socket_modify_cb (sk, NL_CB_MSG_IN, NL_CB_CUSTOM, verify_source, NULL); g_assert (!err); err = nl_connect (sk, NETLINK_XFRM); g_assert (!err); err = nl_socket_set_passcred (sk, 1); g_assert (!err); return sk; }
/** * Connects to the NETLINK interface. This will be called * for each etherinfo object being generated, and it will * keep a separate file descriptor open for each object * * @param ethi PyEtherInfo structure (basically the "self" object) * * @return Returns 1 on success, otherwise 0. */ int open_netlink(PyEtherInfo *ethi) { if( !ethi ) { return 0; } /* Reuse already established NETLINK connection, if a connection exists */ if( nlconnection ) { /* If this object has not used NETLINK earlier, tag it as a user */ if( !ethi->nlc_active ) { pthread_mutex_lock(&nlc_counter_mtx); nlconnection_users++; pthread_mutex_unlock(&nlc_counter_mtx); } ethi->nlc_active = 1; return 1; } /* No earlier connections exists, establish a new one */ nlconnection = nl_socket_alloc(); if( nlconnection != NULL ) { if( nl_connect(nlconnection, NETLINK_ROUTE) < 0 ) { return 0; } /* Force O_CLOEXEC flag on the NETLINK socket */ if( fcntl(nl_socket_get_fd(nlconnection), F_SETFD, FD_CLOEXEC) == -1 ) { fprintf(stderr, "**WARNING** Failed to set O_CLOEXEC on NETLINK socket: %s\n", strerror(errno)); } /* Tag this object as an active user */ pthread_mutex_lock(&nlc_counter_mtx); nlconnection_users++; pthread_mutex_unlock(&nlc_counter_mtx); ethi->nlc_active = 1; return 1; } else { return 0; } }
int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err, master_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(master_index = rtnl_link_name2i(link_cache, "eth0"))) { fprintf(stderr, "Unable to lookup eth0"); return -1; } if (!(link = rtnl_link_ipvlan_alloc())) { fprintf(stderr, "Unable to allocate link"); return -1; } rtnl_link_set_link(link, master_index); rtnl_link_ipvlan_set_mode(link, rtnl_link_ipvlan_str2mode("l2")); if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
static int netlink_probe(void) { struct nl_sock *sock; struct nl_cache *lc; int ret = 0; if (!(sock = nl_socket_alloc())) return 0; if (nl_connect(sock, NETLINK_ROUTE) < 0) return 0; if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &lc) == 0) { nl_cache_free(lc); ret = 1; } nl_socket_free(sock); return ret; }
/** * Connects to the NETLINK interface. This will be called * for each etherinfo object being generated, and it will * keep a separate file descriptor open for each object * * @param data etherinfo_obj_data structure * * @return Returns 1 on success, otherwise 0. */ int open_netlink(struct etherinfo_obj_data *data) { if( !data ) { return 0; } /* Reuse already established NETLINK connection, if a connection exists */ if( *data->nlc ) { /* If this object has not used NETLINK earlier, tag it as a user */ if( !data->nlc_active ) { pthread_mutex_lock(&nlc_counter_mtx); (*data->nlc_users)++; pthread_mutex_unlock(&nlc_counter_mtx); } data->nlc_active = 1; return 1; } /* No earlier connections exists, establish a new one */ *data->nlc = nl_handle_alloc(); nl_connect(*data->nlc, NETLINK_ROUTE); if( (*data->nlc != NULL) ) { /* Force O_CLOEXEC flag on the NETLINK socket */ if( fcntl(nl_socket_get_fd(*data->nlc), F_SETFD, FD_CLOEXEC) == -1 ) { fprintf(stderr, "**WARNING** Failed to set O_CLOEXEC on NETLINK socket: %s\n", strerror(errno)); } /* Tag this object as an active user */ pthread_mutex_lock(&nlc_counter_mtx); (*data->nlc_users)++; pthread_mutex_unlock(&nlc_counter_mtx); data->nlc_active = 1; return 1; } else { return 0; } }
static int netlink_do_init(void) { int err; if (!(sock = nl_socket_alloc())) { fprintf(stderr, "Unable to allocate netlink socket\n"); goto disable; } if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0) { fprintf(stderr, "Unable to connect netlink socket: %s\n", nl_geterror(err)); goto disable; } if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) { fprintf(stderr, "Unable to allocate link cache: %s\n", nl_geterror(err)); goto disable; } if ((err = rtnl_qdisc_alloc_cache(sock, &qdisc_cache)) < 0) { fprintf(stderr, "Warning: Unable to allocate qdisc cache: %s\n", nl_geterror(err)); fprintf(stderr, "Disabling QoS statistics.\n"); qdisc_cache = NULL; } netlink_use_bit(link_attrs, ARRAY_SIZE(link_attrs)); netlink_use_bit(tc_attrs, ARRAY_SIZE(tc_attrs)); if (attr_map_load(link_attrs, ARRAY_SIZE(link_attrs)) || attr_map_load(tc_attrs, ARRAY_SIZE(tc_attrs))) BUG(); if (!(grp = group_lookup(DEFAULT_GROUP, GROUP_CREATE))) BUG(); return 0; disable: return -EOPNOTSUPP; }
GWaterNlSource * g_water_nl_source_new_sock(GMainContext *context, gint protocol) { struct nl_sock *sock; GWaterNlSource *self; sock = nl_socket_alloc(); if ( sock == NULL ) return NULL; if ( nl_connect(sock, protocol) < 0 ) { nl_socket_free(sock); return NULL; } self = g_water_nl_source_new_for_sock(context, sock); self->owned = TRUE; return self; }
int sysnet_interface_set_addr(VPNInterface *i) { int err; struct nl_cache *link_cache; struct nl_sock *sock; struct rtnl_addr *addr; struct rtnl_link *link; struct nl_addr *local_addr; sock = nl_socket_alloc(); nl_connect(sock, NETLINK_ROUTE); rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); addr = rtnl_addr_alloc(); link = rtnl_link_get_by_name(link_cache, i->name); local_addr = nl_addr_build(i->address.ip.family, &i->address.ip.ip4, sizeof(i->address.ip.ip4)); rtnl_addr_set_local(addr, local_addr); rtnl_addr_set_family(addr, i->address.ip.family); rtnl_addr_set_prefixlen(addr, i->address.prefix); rtnl_addr_set_link(addr, link); if ((err = rtnl_addr_add(sock, addr, 0)) < 0) { tox_trace(i->context->tox, "Unable to add address %s on %s: %s", ip_ntoa(&i->address.ip), rtnl_link_get_name(link), nl_geterror(err)); } else { tox_trace(i->context->tox, "Added address %s on \"%s\"", ip_ntoa(&i->address.ip), i->name); } rtnl_link_put(link); rtnl_addr_put(addr); nl_cache_free(link_cache); nl_addr_put(local_addr); nl_socket_free(sock); return err; }
/* function: send_netlink_msg * sends a netlink message, reads a response, and hands the response(s) to the callbacks * msg - netlink message to send * callbacks - callbacks to use on responses */ void send_netlink_msg(struct nl_msg *msg, struct nl_cb *callbacks) { struct nl_sock *nl_sk; nl_sk = nl_socket_alloc(); if(!nl_sk) goto cleanup; if(nl_connect(nl_sk, NETLINK_ROUTE) != 0) goto cleanup; if(nl_send_auto_complete(nl_sk, msg) < 0) goto cleanup; if(netlink_set_kernel_only(nl_sk) < 0) goto cleanup; nl_recvmsgs(nl_sk, callbacks); cleanup: if(nl_sk) nl_socket_free(nl_sk); }