TError TNl::ProxyNeighbour(int ifindex, const TNlAddr &addr, bool add) { struct rtnl_neigh *neigh; int ret; neigh = rtnl_neigh_alloc(); if (!neigh) return TError(EError::Unknown, "Cannot allocate neighbour"); ret = rtnl_neigh_set_dst(neigh, addr.Addr); if (ret) { rtnl_neigh_put(neigh); return Error(ret, "Cannot set neighbour dst"); } rtnl_neigh_set_flags(neigh, NTF_PROXY); rtnl_neigh_set_state(neigh, NUD_PERMANENT); rtnl_neigh_set_ifindex(neigh, ifindex); if (add) { Dump("add", neigh); ret = rtnl_neigh_add(Sock, neigh, NLM_F_CREATE | NLM_F_REPLACE); } else { Dump("del", neigh); ret = rtnl_neigh_delete(Sock, neigh, 0); if (ret == -NLE_OBJ_NOTFOUND) ret = 0; } rtnl_neigh_put(neigh); if (ret) return Error(ret, "Cannot modify neighbour for l3 network"); return TError::Success(); }
/** * Set the destination address of a neighbour * @arg neigh neighbour to change * @arg addr new destination address as string * * Translates the specified address to a binary format and assigns * it as the destination address by calling rtnl_neigh_set_dst(). * * @see rtnl_neigh_set_dst(); * @return 0 on success or a negative error code. */ int rtnl_neigh_set_dst_str(struct rtnl_neigh *neigh, const char *addr) { int err; struct nl_addr a = {0}; int hint = neigh->n_mask & NEIGH_HAS_FAMILY ? neigh->n_family : AF_UNSPEC; err = nl_str2addr(addr, &a, hint); if (err < 0) return err; return rtnl_neigh_set_dst(neigh, &a); }
static struct rtnl_neigh *create_filter_neigh_for_dst(struct nl_addr *dst_addr, int oif) { struct rtnl_neigh *filter_neigh; filter_neigh = rtnl_neigh_alloc(); if (filter_neigh == NULL) return NULL; rtnl_neigh_set_ifindex(filter_neigh, oif); rtnl_neigh_set_dst(filter_neigh, dst_addr); return filter_neigh; }
static void nl_ihandler_cb(struct incident *i, void *ctx) { g_debug("%s i %p ctx %p", __PRETTY_FUNCTION__, i, ctx); struct connection *con; incident_value_con_get(i, "con", &con); char *remote = con->remote.ip_string; char *local = con->local.ip_string; char *prefix = "::ffff:"; if( strncmp(local, prefix, strlen(prefix)) == 0) local += strlen(prefix); if( strncmp(remote, prefix, strlen(prefix)) == 0) remote += strlen(prefix); int ifindex; int err; { g_debug("local addr %s remote addr %s", local, remote); struct rtnl_addr *addr = rtnl_addr_alloc(); struct nl_addr *a; if ( ( err = nl_addr_parse(local, AF_UNSPEC, &a)) != 0 ) g_critical("could not parse addr %s (%s)", local, nl_geterror(err)); rtnl_addr_set_local(addr, a); nl_addr_put(a); struct rtnl_addr *res = NULL; nl_cache_foreach_filter(nl_runtime.addr_cache, OBJ_CAST(addr), cache_lookup_cb, &res); g_critical("LOCAL RTNL_ADDR %p", res); /* struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; nl_cache_dump_filter(nl_runtime.addr_cache, ¶ms, OBJ_CAST(addr)); */ ifindex = rtnl_addr_get_ifindex(res); } struct rtnl_neigh *res = NULL; { struct rtnl_neigh *neigh = rtnl_neigh_alloc(); rtnl_neigh_set_ifindex(neigh, ifindex); struct nl_addr *a; if ( ( err = nl_addr_parse(remote, AF_UNSPEC, &a)) != 0 ) g_critical("could not parse addr %s (%s)", remote, nl_geterror(err)); rtnl_neigh_set_dst(neigh, a); nl_addr_put(a); nl_cache_foreach_filter(nl_runtime.neigh_cache, OBJ_CAST(neigh), cache_lookup_cb, &res); } if( res ) { g_critical("GOT NEIGH %p", res); struct nl_addr *lladdr = rtnl_neigh_get_lladdr(res); char buf[123]; nl_addr2str(lladdr, buf, sizeof(buf)); g_critical("GOT NEIGH %s", buf); struct incident *i = incident_new("dionaea.module.nl.connection.info.mac"); incident_value_string_set(i, "mac", g_string_new(buf)); incident_value_con_set(i, "con", con); incident_report(i); incident_free(i); } }