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 match_nl_table_cmd_to_type(FILE *fp, bool print, int valid, struct nlattr *tb[]) { unsigned int type, ifindex; int err; char iface[IFNAMSIZ]; struct nl_sock *fd = NULL; if (!tb[NET_MAT_IDENTIFIER_TYPE]) { MAT_LOG(ERR, "Warning: received rule msg without identifier type!\n"); return -EINVAL; } if (!tb[NET_MAT_IDENTIFIER]) { MAT_LOG(ERR, "Warning: received rule msg without identifier!\n"); return -EINVAL; } if (valid > 0 && !tb[valid]) { MAT_LOG(ERR, "Warning: received cmd without valid attribute expected %i\n", valid); return -ENOMSG; } if (nla_len(tb[NET_MAT_IDENTIFIER_TYPE]) < (int)sizeof(type)) { MAT_LOG(ERR, "Warning: invalid identifier type len\n"); return -EINVAL; } type = nla_get_u32(tb[NET_MAT_IDENTIFIER_TYPE]); switch (type) { case NET_MAT_IDENTIFIER_IFINDEX: fd = nl_socket_alloc(); err = nl_connect(fd, NETLINK_ROUTE); if (err < 0) { MAT_LOG(ERR,"Warning: Unable to connect socket\n"); break; } err = rtnl_link_alloc_cache(fd, AF_UNSPEC, &link_cache); if (err < 0) { MAT_LOG(ERR,"Warning: Unable to allocate cache\n"); break; } ifindex = nla_get_u32(tb[NET_MAT_IDENTIFIER]); rtnl_link_i2name(link_cache, (int)ifindex, iface, IFNAMSIZ); if (ifindex) pfprintf(fp, print, "%s (%u):\n", iface, ifindex); break; default: MAT_LOG(ERR, "Warning: unknown interface identifier type %i\n", type); break; } if (fd) { nl_close(fd); nl_socket_free(fd); } return 0; }
NetLinkManager::NetLinkManager() : _initialized(false), _sock(NULL), _refresh_cache(false) { ibrcommon::MutexLock l(_call_mutex); _handle = nl_handle_alloc(); nl_connect(_handle, NETLINK_ROUTE); _link_cache = rtnl_link_alloc_cache(_handle); if (_link_cache == NULL) { nl_close(_handle); nl_handle_destroy(_handle); throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } _addr_cache = rtnl_addr_alloc_cache(_handle); if (_addr_cache == NULL) { nl_close(_handle); nl_handle_destroy(_handle); nl_cache_free(_link_cache); _link_cache = NULL; throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } _initialized = true; // create a new socket for the netlink interface _sock = new ibrcommon::vsocket(); }
int sysnet_interface_set_mtu(VPNInterface *i, unsigned int mtu) { int err; struct nl_cache *link_cache; struct nl_sock *sock; struct rtnl_link *link; struct rtnl_link *new_link; sock = nl_socket_alloc(); nl_connect(sock, NETLINK_ROUTE); rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); link = rtnl_link_get_by_name(link_cache, i->name); new_link = rtnl_link_alloc(); if (!link) { tox_trace(i->context->tox, "can't find link \"%s\"", i->name); return -1; } rtnl_link_set_mtu(new_link, mtu); if ((err = rtnl_link_change(sock, link, new_link, 0)) < 0) { tox_trace(i->context->tox, "unable to change link \"%s\" flags: %s", rtnl_link_get_name(link), nl_geterror(err)); } rtnl_link_put(link); rtnl_link_put(new_link); nl_cache_free(link_cache); nl_socket_free(sock); return 0; }
static gboolean sync_connection_setup (NMNetlinkMonitor *self, GError **error) { NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND struct nl_cache *addr_cache; #endif int err; /* Set up the event listener connection */ priv->nlh_sync = nl_socket_alloc (); if (!priv->nlh_sync) { 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_sync, NULL, self, error)) goto error; #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND /* Work around apparent libnl bug; rtnl_addr requires that all * addresses have the "peer" attribute set in order to be compared * for equality, but this attribute is not normally set. As a * result, most addresses will not compare as equal even to * themselves, busting caching. */ rtnl_addr_alloc_cache (priv->nlh_sync, &addr_cache); g_warn_if_fail (addr_cache != NULL); nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80; nl_cache_free (addr_cache); #endif err = rtnl_link_alloc_cache (priv->nlh_sync, AF_UNSPEC, &priv->link_cache); if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE, _("unable to allocate netlink link cache for monitoring link status: %s"), nl_geterror (err)); goto error; } nl_cache_mngt_provide (priv->link_cache); return TRUE; error: if (priv->link_cache) { nl_cache_free (priv->link_cache); priv->link_cache = NULL; } if (priv->nlh_sync) { nl_socket_free (priv->nlh_sync); priv->nlh_sync = NULL; } return FALSE; }
int netem_init() { /* Allocate and initialize a new netlink handle */ if (!(sock = nl_socket_alloc())) { fprintf(stderr, "Failed to alloc netlink socket\n"); return -EOPNOTSUPP; } /* Bind and connect socket to protocol, NETLINK_ROUTE in our case. */ if (nl_connect(sock, NETLINK_ROUTE) < 0) { fprintf(stderr, "Failed to connect to kernel\n"); return -EOPNOTSUPP; } /* Retrieve a list of all available interfaces and populate cache. */ if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache) < 0) { fprintf(stderr, "Error creating link cache\n"); return -EOPNOTSUPP; } /* Retrieve a list of all available qdiscs and populate cache. */ if (rtnl_qdisc_alloc_cache(sock, &qdisc_cache) < 0) { fprintf(stderr, "Error creating qdisc cache\n"); return -EOPNOTSUPP; } return 0; }
LinuxPlatformBackend::LinuxPlatformBackend (QObject *parent) : PlatformBackend (parent) , Rtsock_ (nl_socket_alloc ()) { if (nl_connect (Rtsock_, NETLINK_ROUTE) >= 0) rtnl_link_alloc_cache (Rtsock_, AF_UNSPEC, &LinkCache_); else qWarning () << Q_FUNC_INFO << "unable to establish netlink conn"; }
const std::list<vaddress> NetLinkManager::getAddressList(const vinterface &interface, const vaddress::Family f) { ibrcommon::MutexLock l(_call_mutex); if (_refresh_cache) { nl_cache_free(_addr_cache); nl_cache_free(_link_cache); _link_cache = rtnl_link_alloc_cache(_handle); if (_link_cache == NULL) { throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } _addr_cache = rtnl_addr_alloc_cache(_handle); if (_addr_cache == NULL) { nl_cache_free(_link_cache); throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } // mark the cache as refreshed _refresh_cache = false; } std::list<vaddress> addresses; struct rtnl_addr *filter = rtnl_addr_alloc(); const std::string i = interface.toString(); rtnl_addr_set_ifindex(filter, rtnl_link_name2i(_link_cache, i.c_str())); if (f == vaddress::VADDRESS_UNSPEC) { rtnl_addr_set_family(filter, AF_INET6); nl_cache_foreach_filter(_addr_cache, (struct nl_object *) filter, add_addr_to_list, &addresses); rtnl_addr_set_family(filter, AF_INET); nl_cache_foreach_filter(_addr_cache, (struct nl_object *) filter, add_addr_to_list, &addresses); } else { rtnl_addr_set_family(filter, f); nl_cache_foreach_filter(_addr_cache, (struct nl_object *) filter, add_addr_to_list, &addresses); } rtnl_addr_put(filter); return addresses; }
int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link, *link2; struct nl_sock *sk; uint32_t tb_id; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if (!(link = rtnl_link_vrf_alloc())) { fprintf(stderr, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "vrf-red"); if ((err = rtnl_link_vrf_set_tableid(link, 10)) < 0) { nl_perror(err, "Unable to set VRF table id"); return err; } if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(link2 = rtnl_link_get_by_name(link_cache, "vrf-red"))) { fprintf(stderr, "Unable to lookup vrf-red"); return -1; } if ((err = rtnl_link_vrf_get_tableid(link2, &tb_id)) < 0) { nl_perror(err, "Unable to get VRF table id"); return err; } if (tb_id != 10) { fprintf(stderr, "Mismatch with VRF table id\n"); } rtnl_link_put(link); nl_close(sk); return 0; }
int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_cache *link_cache; struct nl_sock *sk; int err; 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 ((err = create_bridge(sk, link_cache, TEST_BRIDGE_NAME)) < 0) { nl_perror(err, "Unable to allocate testbridge"); return err; } nl_cache_refill(sk, link_cache); link = rtnl_link_get_by_name(link_cache, TEST_BRIDGE_NAME); struct rtnl_link *ltap = rtnl_link_get_by_name(link_cache, TEST_INTERFACE_NAME); if (!ltap) { fprintf(stderr, "You should create a tap interface before lunch this test (# tunctl -t %s)\n", TEST_INTERFACE_NAME); return -1; } if ((err = rtnl_link_enslave(sk, link, ltap)) < 0) { nl_perror(err, "Unable to enslave interface to his bridge\n"); return err; } if(rtnl_link_is_bridge(link) == 0) { fprintf(stderr, "Link is not a bridge\n"); return -2; } if(rtnl_link_get_master(ltap) <= 0) { fprintf(stderr, "Interface is not attached to a bridge\n"); return -3; } rtnl_link_put(ltap); rtnl_link_put(link); nl_cache_free(link_cache); nl_socket_free(sk); return 0; }
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; }
struct nl_cache *nltool_alloc_link_cache(struct nl_handle *nlh) { struct nl_cache *cache; cache = rtnl_link_alloc_cache(nlh); if (!cache) fprintf(stderr, "Unable to retrieve link cache: %s\n", nl_geterror()); else nl_cache_mngt_provide(cache); return cache; }
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; }
bool devEthernet::hasLink() { if ( ! _netlinkSocket ) { MOD_ERROR("hasLink() called on uninitialized netlink socket."); return false; } nl_cache* cache; if ( rtnl_link_alloc_cache (_netlinkSocket, AF_UNSPEC, &cache) ) { MOD_ERROR("hasLink() rtnl_link_alloc_cache error: %s", nl_geterror(errno)); return false; } rtnl_link* link = rtnl_link_get(cache, index()); if ( ! link ) { MOD_ERROR("hasLink() rtnl_link_get error: %s", nl_geterror(errno)); nl_cache_free(cache); return false; } // First, check that interface is able to send uint8_t operState = rtnl_link_get_operstate(link); #ifdef DEFINE_DEBUG char buf[100]; rtnl_link_operstate2str (operState, buf, 100); MOD_DEBUG("operState is 0x%x (%s).", operState, buf); #endif bool ret = false; // Next make sure there's a carrier #ifndef IFF_LOWER_UP const int IFF_LOWER_UP = 0x10000; #endif #ifndef IFF_DORMANT const int IFF_DORMANT = 0x20000; #endif if ( operState == OperUp) { unsigned int flags = rtnl_link_get_flags (link); ret = ( ((flags & IFF_LOWER_UP) == IFF_LOWER_UP) && ((flags & IFF_DORMANT) != IFF_DORMANT) ); } rtnl_link_put(link); nl_cache_free(cache); return ret; }
/* * Return an NETLINK_ROUTE cache. */ static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { struct nl_cache *cache = NULL; if ((*handle = _iface_get_handle()) == NULL) { return NULL; } if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { nl_close(*handle); nl_handle_destroy(*handle); return NULL; } return cache; }
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; }
char *utils_get_mac_addr(char *interface) { int buflen = 20; char *buf = NULL; struct nl_handle *nlh = NULL; struct nl_cache *cache = NULL; struct rtnl_link *link = NULL; struct nl_addr *addr = NULL; if (zstr(interface)) { return NULL; } if (init_handle(&nlh) != 0) { return NULL; } if ((cache = rtnl_link_alloc_cache(nlh)) == NULL) { return NULL; } if ((link = rtnl_link_get_by_name(cache, interface)) == NULL) { goto mac2str_error2; } if ((addr = rtnl_link_get_addr(link)) == NULL) { goto mac2str_error3; } if ((buf = calloc(sizeof(char *), buflen)) == NULL) { goto mac2str_error4; } buf = nl_addr2str(addr, buf, buflen); mac2str_error4: nl_addr_destroy(addr); mac2str_error3: rtnl_link_put(link); mac2str_error2: nl_close(nlh); nl_handle_destroy(nlh); return buf; }
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; }
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; }
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; }
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; }
// Returns the netlink link object associated with a given link by its // interface index. Returns None if the link is not found. inline Result<Netlink<struct rtnl_link>> get(int index) { Try<Netlink<struct nl_sock>> socket = routing::socket(); if (socket.isError()) { return Error(socket.error()); } // Dump all the netlink link objects from kernel. Note that the flag // AF_UNSPEC means all available families. struct nl_cache* c = NULL; int error = rtnl_link_alloc_cache(socket.get().get(), AF_UNSPEC, &c); if (error != 0) { return Error(nl_geterror(error)); } Netlink<struct nl_cache> cache(c); struct rtnl_link* l = rtnl_link_get(cache.get(), index); if (l == NULL) { return None(); } return Netlink<struct rtnl_link>(l); }
TError TNl::OpenLinks(std::vector<std::shared_ptr<TNlLink>> &links, bool all) { struct nl_cache *cache; int ret; ret = rtnl_link_alloc_cache(GetSock(), AF_UNSPEC, &cache); if (ret < 0) return Error(ret, "Cannot allocate link cache"); for (auto obj = nl_cache_get_first(cache); obj; obj = nl_cache_get_next(obj)) { auto link = (struct rtnl_link *)obj; if (!all && ((rtnl_link_get_flags(link) & (IFF_LOOPBACK | IFF_RUNNING)) != IFF_RUNNING)) continue; auto l = std::make_shared<TNlLink>(shared_from_this(), link); links.push_back(l); } nl_cache_free(cache); return TError::Success(); }
static int netlink3_set_interface_parameters(const interface_t *ifp, interface_t *base_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; // Allocate a new link if (!(new_state = rtnl_link_alloc())) goto err; if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 1) || rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ACCEPT_LOCAL, 1) || rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_RP_FILTER, 0) || rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_PROMOTE_SECONDARIES, 1) || rtnl_link_change (sk, link, new_state, 0)) goto err; rtnl_link_put(new_state); new_state = NULL; rtnl_link_put(link); link = NULL; /* Set arp_ignore and arp_filter on base interface if needed */ if (base_ifp->reset_arp_config) (base_ifp->reset_arp_config)++; else { if (!(link = rtnl_link_get(cache, base_ifp->ifindex))) goto err; if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_ARP_IGNORE, &base_ifp->reset_arp_ignore_value) < 0) goto err; if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_ARPFILTER, &base_ifp->reset_arp_filter_value) < 0) goto err; if (base_ifp->reset_arp_ignore_value != 1 || base_ifp->reset_arp_filter_value != 1 ) { /* The underlying interface mustn't reply for our address(es) */ if (!(new_state = rtnl_link_alloc())) goto err; if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 1) || rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARPFILTER, 1) || rtnl_link_change(sk, link, new_state, 0)) goto err; rtnl_link_put(new_state); new_state = NULL; rtnl_link_put(link); link = NULL; base_ifp->reset_arp_config = 1; } } 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 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(nfnlh, 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_handle *rtnlh; 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; if (nltool_init(argc, argv) < 0) return -1; nfnlh = nltool_alloc_handle(); if (nfnlh == NULL) return -1; nl_disable_sequence_check(nfnlh); nl_socket_modify_cb(nfnlh, 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"); return 2; } if (nfnl_connect(nfnlh) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } family = nl_str2af(argv[1]); if (family == AF_UNSPEC) { fprintf(stderr, "Unknown family: %s\n", argv[1]); goto errout; } nfnl_queue_pf_unbind(nfnlh, family); if (nfnl_queue_pf_bind(nfnlh, family) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } queue = nfnl_queue_alloc(); if (queue == NULL) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } 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) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } } 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 (nfnl_queue_create(nfnlh, queue) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } rtnlh = nltool_alloc_handle(); if (rtnlh == NULL) { goto errout_close; } if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) { fprintf(stderr, "%s\n", nl_geterror()); goto errout; } if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) { fprintf(stderr, "%s\n", nl_geterror()); goto errout_close; } nl_cache_mngt_provide(link_cache); while (1) { fd_set rfds; int nffd, rtfd, maxfd, retval; FD_ZERO(&rfds); maxfd = nffd = nl_socket_get_fd(nfnlh); FD_SET(nffd, &rfds); rtfd = nl_socket_get_fd(rtnlh); 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(nfnlh); if (FD_ISSET(rtfd, &rfds)) nl_recvmsgs_default(rtnlh); } } nl_cache_mngt_unprovide(link_cache); nl_cache_free(link_cache); nfnl_queue_put(queue); nl_close(rtnlh); nl_handle_destroy(rtnlh); errout_close: nl_close(nfnlh); nl_handle_destroy(nfnlh); errout: return err; }
/** * Query NETLINK for ethernet configuration * * @param ethinf Pointer to an available struct etherinfo element. The 'device' member * must contain a valid string to the device to query for information * @param nlc Pointer to the libnl handle, which is used for the query against NETLINK * @param query What to query for. Must be NLQRY_LINK or NLQRY_ADDR. * * @return Returns 1 on success, otherwise 0. */ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) { struct nl_cache *link_cache; struct nl_cache *addr_cache; struct rtnl_addr *addr; struct rtnl_link *link; struct etherinfo *ethinf = NULL; int ret = 0; if( !data || !data->ethinfo ) { return 0; } ethinf = data->ethinfo; /* Open a NETLINK connection on-the-fly */ if( !open_netlink(data) ) { PyErr_Format(PyExc_RuntimeError, "Could not open a NETLINK connection for %s", ethinf->device); return 0; } /* Find the interface index we're looking up. * As we don't expect it to change, we're reusing a "cached" * interface index if we have that */ if( ethinf->index < 0 ) { link_cache = rtnl_link_alloc_cache(*data->nlc); ethinf->index = rtnl_link_name2i(link_cache, ethinf->device); if( ethinf->index < 0 ) { return 0; } nl_cache_free(link_cache); } /* Query the for requested info vai NETLINK */ switch( query ) { case NLQRY_LINK: /* Extract MAC/hardware address of the interface */ link_cache = rtnl_link_alloc_cache(*data->nlc); link = rtnl_link_alloc(); rtnl_link_set_ifindex(link, ethinf->index); nl_cache_foreach_filter(link_cache, (struct nl_object *)link, callback_nl_link, ethinf); rtnl_link_put(link); nl_cache_free(link_cache); ret = 1; break; case NLQRY_ADDR: /* Extract IP address information */ addr_cache = rtnl_addr_alloc_cache(*data->nlc); addr = rtnl_addr_alloc(); rtnl_addr_set_ifindex(addr, ethinf->index); /* Make sure we don't have any old IPv6 addresses saved */ if( ethinf->ipv6_addresses ) { free_ipv6addresses(ethinf->ipv6_addresses); ethinf->ipv6_addresses = NULL; } /* Retrieve all address information */ nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, callback_nl_address, ethinf); rtnl_addr_put(addr); nl_cache_free(addr_cache); ret = 1; break; default: ret = 0; } return ret; }
int main(void) { struct nl_sock *sock; struct rtnl_link *link; uint32_t ht, htlink, htid, direction; char chashlink[16]=""; int err; struct nl_cache *link_cache; struct rtnl_act *act, *act2; uint32_t i; if (!(sock = nl_socket_alloc())) { printf("Unable to allocate netlink socket\n"); exit(1); } if ((err = nl_connect(sock, NETLINK_ROUTE)) < 0 ) { printf("Nu s-a putut conecta la NETLINK!\n"); nl_socket_free(sock); exit(1); } if ((err = rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache)) < 0) { printf("Unable to allocate link cache: %s\n", nl_geterror(err)); nl_socket_free(sock); exit(1); } /* lookup interface index of eth0 */ if (!(link = rtnl_link_get_by_name(link_cache, "eth0"))) { /* error */ printf("Interface not found\n"); nl_socket_free(sock); exit(1); } err=qdisc_add_ingress(sock, link); //printf("Add main hash table\n"); /* create u32 first hash filter table * */ /* formula calcul handle: * uint32_t handle = (htid << 20) | (hash << 12) | nodeid; */ /* * Upper limit of number of hash tables: 4096 (0xFFF) * Number of hashes in a table: 256 values (0xFF) * */ /* using 256 values for hash table * each entry in hash table match a byte from IP address specified later by a hash key */ for (i = 1; i <= 0xf; i++) u32_add_ht(sock, link, 1, i, 256); /* * attach a u32 filter to the first hash * that redirects all traffic and make a hash key * from the fist byte of the IP address * */ //divisor=0x0; // unused here //handle = 0x0; // unused here //hash = 0x0; // unused here //htid = 0x0; // unused here //nodeid = 0x0; // unused here // direction = 12 -> source IP // direction = 16 -> destination IP direction = 16; /* * which hash table will use * in our case is hash table no 1 defined previous * * There are 2 posibilities to set the the hash table: * 1. Using function get_u32_handle and sent a string in * format 10: where 10 is number of the hash table * 2. Create your own value in format: 0xa00000 * */ strcpy(chashlink, "1:"); //printf("Hash Link: %s\n", chashlink); //chashlink=malloc(sizeof(char) * htlink = 0x0; // is used by get_u32_handle to return the correct value of hash table (link) if(get_u32_handle(&htlink, chashlink)) { printf ("Illegal \"link\""); nl_socket_free(sock); exit(1); } //printf ("hash link : 0x%X\n", htlink); //printf ("hash link test : %u\n", (htlink && TC_U32_NODE(htlink))); if (htlink && TC_U32_NODE(htlink)) { printf("\"link\" must be a hash table.\n"); nl_socket_free(sock); exit(1); } /* the hash mask will hit the hash table (link) no 1: in our case */ /* set the hash key mask */ //hashmask = 0xFF000000UL; // the mask that is used to match the hash in specific table, in our case for example 1:a with mean the first byte which is 10 in hash table 1 /* Here we add a hash filter which match the first byte (see the hashmask value) * of the source IP (offset 12 in the packet header) * You can use also offset 16 to match the destination IP */ /* * Also we need a filter to match our rule * This mean that we will put a 0.0.0.0/0 filter in our first rule * that match the offset 12 (source IP) * Also you can put offset 16 to match the destination IP */ u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0, 0x0, direction, 0, 0, htlink, 0xff000000, direction, NULL, NULL); /* * For each first byte that we need to match we will create a new hash table * For example: you have those clases: 10.0.0.0/24 and 172.16.0.0/23 * For byte 10 and byte 172 will create a separate hash table that will match the second * byte from each class. * */ /* * Now we will create other filter under (ATENTION) our first hash table (link) 1: * Previous rule redirects the trafic according the hash mask to hash table (link) no 1: * Here we will match the hash tables from 1:0 to 1:ff. Under each hash table we will attach * other rules that matches next byte from IP source/destination IP and we will repeat the * previous steps. * */ act = rtnl_act_alloc(); if (!act) { printf("rtnl_act_alloc() returns %p\n", act); return -1; } rtnl_tc_set_kind(TC_CAST(act), "skbedit"); rtnl_skbedit_set_queue_mapping(act, 4); rtnl_skbedit_set_action(act, TC_ACT_PIPE); act2 = rtnl_act_alloc(); if (!act2) { printf("rtnl_act_alloc() returns %p\n", act2); return -1; } rtnl_tc_set_kind(TC_CAST(act2), "mirred"); rtnl_mirred_set_action(act2, TCA_EGRESS_REDIR); rtnl_mirred_set_policy(act2, TC_ACT_STOLEN); rtnl_mirred_set_ifindex(act2, rtnl_link_name2i(link_cache, "eth1")); // /8 check // 10.0.0.0/8 ht=get_u32_parse_handle("1:a:"); htid = (ht&0xFFFFF000); htlink=get_u32_parse_handle("2:"); u32_add_filter_on_ht_with_hashmask(sock, link, 1, 0x0a000000, 0xff000000, direction, 0, htid, htlink, 0x00ff0000, direction, act, act2); rtnl_act_put(act); nl_socket_free(sock); return 0; }