void tools_delete_router_address (const gchar *address) { struct nl_sock *sock = NULL; struct nl_addr *dst = NULL; struct nl_addr *gw = NULL; struct rtnl_nexthop *nhop = NULL; struct rtnl_route *route = NULL; sock = nl_socket_alloc (); nl_connect (sock, NETLINK_ROUTE); nhop = rtnl_route_nh_alloc (); nl_addr_parse (address, AF_INET, &gw); rtnl_route_nh_set_gateway (nhop, gw); rtnl_route_nh_set_flags (nhop, 0); route = rtnl_route_alloc (); rtnl_route_set_family (route, AF_INET); nl_addr_parse ("default", AF_INET, &dst); rtnl_route_add_nexthop (route, nhop); if (rtnl_route_delete (sock, route, NLM_F_CREATE | NLM_F_REPLACE) != 0) g_warning (_("Failed to delete default route.")); nl_socket_free (sock); rtnl_route_put (route); nl_addr_put (dst); nl_addr_put (gw); }
int main(int argc, char *argv[]) { int err; char host[256]; struct nl_addr *a; if (argc < 2) { fprintf(stderr, "Usage: nl-util-addr <address>\n"); return -1; } a = nl_addr_parse(argv[1], AF_UNSPEC); if (a == NULL) { fprintf(stderr, "Cannot parse address \"%s\"\n", argv[1]); return -1; } err = nl_addr_resolve(a, host, sizeof(host)); if (err != 0) { fprintf(stderr, "Cannot resolve address \"%s\": %d\n", argv[1], err); return -1; } printf("%s\n", host); return 0; }
TError TNlAddr::Parse(int family, const std::string &string) { Forget(); int ret = nl_addr_parse(string.c_str(), family, &Addr); if (ret) return TNl::Error(ret, "Cannot parse address " + string); return TError::Success(); }
struct nl_addr *nl_cli_addr_parse(const char *str, int family) { struct nl_addr *addr; int err; if ((err = nl_addr_parse(str, family, &addr)) < 0) nl_cli_fatal(err, "Unable to parse address \"%s\": %s", str, nl_geterror(err)); return addr; }
struct nl_addr *nltool_addr_parse(const char *str) { struct nl_addr *addr; addr = nl_addr_parse(str, AF_UNSPEC); if (!addr) fprintf(stderr, "Unable to parse address \"%s\": %s\n", str, nl_geterror()); return addr; }
/* Given an interface's MAC address, return the name (e.g., eth0) in human * readable format. Return NULL for no match */ char *iface_mac2device(char *mac) { struct nl_handle *handle = NULL; struct nl_cache *cache = NULL; struct rtnl_link *link = NULL; struct nl_addr *mac_as_nl_addr = NULL; char *retval = NULL; int i, n; if (mac == NULL) { return NULL; } if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) { return NULL; } if ((cache = _iface_get_link_cache(&handle)) == NULL) { return NULL; } n = nl_cache_nitems(cache); for (i = 0; i <= n; i++) { struct nl_addr *addr; if ((link = rtnl_link_get(cache, i)) == NULL) { continue; } addr = rtnl_link_get_addr(link); if (!nl_addr_cmp(mac_as_nl_addr, addr)) { retval = strdup(rtnl_link_get_name(link)); rtnl_link_put(link); break; } rtnl_link_put(link); } nl_close(handle); nl_handle_destroy(handle); return retval; }
static void change_cb(struct nl_cache *cache, struct nl_object *obj, int action) { struct nfnl_ct *ct = (struct nfnl_ct *) obj; static struct nl_addr *hack = NULL; if (!hack) hack = nl_addr_parse("194.88.212.233", AF_INET); if (!nl_addr_cmp(hack, nfnl_ct_get_src(ct, 1)) || !nl_addr_cmp(hack, nfnl_ct_get_dst(ct, 1))) { struct nl_dump_params dp = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; printf("UPDATE "); nl_object_dump(obj, &dp); } }
/* * Get the nexthop for the first default AF_INET route. Sets * *addr if found, caller must release reference to *addr. Returns 1 if an * error occurs, NULL *addr if no error but no AF_INET default route exists. */ static int get_default_gw_inet_addr(struct nl_sock *sk, struct nl_addr **addr) { struct nl_cache *route_cache; int err; err = rtnl_route_alloc_cache(sk, AF_INET, 0, &route_cache); if (err < 0) { warnx("rtnl_addr_alloc_cache() failed: %s", nl_geterror(err)); return 1; } /* Retrieve the first AF_INET default route. */ struct rtnl_route *filter; filter = rtnl_route_alloc(); assert(filter); rtnl_route_set_type(filter, 1); /* XXX RTN_UNICAST from linux/rtnetlink.h */ struct nl_addr *filter_addr; err = nl_addr_parse("default", AF_INET, &filter_addr); if (err < 0) { warnx("nl_addr_parse(default) failed: %s", nl_geterror(err)); rtnl_route_put(filter); nl_cache_free(route_cache); return 1; } rtnl_route_set_dst(filter, filter_addr); *addr = NULL; nl_cache_foreach_filter(route_cache, (struct nl_object *)filter, match_first_nh_gw, addr); /* No default gateway is not an error, so always return 0 here */ nl_addr_put(filter_addr); rtnl_route_put(filter); nl_cache_free(route_cache); return 0; }
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); } }
int configure_loopback_interface() { struct nl_sock *sock = NULL; struct rtnl_addr *addr = NULL; struct nl_addr* lo_addr = NULL; struct nl_cache *cache = NULL; struct rtnl_link *link = NULL, *link2 = NULL; int err, nlflags = NLM_F_CREATE, ret = 0; if(!want_cap(CAP_NET_ADMIN)) { errWarn("Cannot set the CAP_NET_ADMIN effective capability"); return -1; } sock = nl_socket_alloc(); if(sock == NULL) { errWarn("nl_socket_alloc"); return -1; } if((err = nl_connect(sock, NETLINK_ROUTE)) < 0) { fprintf(stderr, "Unable to connect to netlink: %s\n", nl_geterror(err)); ret = -1; goto out2; } if(rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache) < 0) { ret = -1; goto out; } link = rtnl_link_get_by_name(cache, "lo"); if (link == NULL) { ret = -1; goto out; } addr = rtnl_addr_alloc(); if(addr == NULL) { ret = -1; goto out; } rtnl_addr_set_link(addr, link); rtnl_addr_set_family(addr, AF_INET); if((err = nl_addr_parse("127.0.0.1/8", AF_INET, &lo_addr)) < 0) { fprintf(stderr, "Unable to parse address: %s\n", nl_geterror(err)); ret = -1; goto out; } if((err = rtnl_addr_set_local(addr, lo_addr)) < 0) { fprintf(stderr, "Unable to set address: %s\n", nl_geterror(err)); ret = -1; goto out; } nl_addr_put(lo_addr); lo_addr = NULL; if ((err = rtnl_addr_add(sock, addr, nlflags)) < 0) { fprintf(stderr, "Unable to add address: %s\n", nl_geterror(err)); ret = -1; goto out; } rtnl_addr_set_family(addr, AF_INET6); if((err = nl_addr_parse("::1/128", AF_INET6, &lo_addr)) < 0) { fprintf(stderr, "Unable to parse address: %s\n", nl_geterror(err)); ret = -1; goto out; } if((err = rtnl_addr_set_local(addr, lo_addr)) < 0) { fprintf(stderr, "Unable to set address: %s\n", nl_geterror(err)); ret = -1; goto out; } nl_addr_put(lo_addr); lo_addr = NULL; if ((err = rtnl_addr_add(sock, addr, nlflags)) < 0) { fprintf(stderr, "Unable to add address: %s\n", nl_geterror(err)); ret = -1; goto out; } link2 = rtnl_link_alloc(); if(link2 == NULL) { ret = -1; goto out; } rtnl_link_set_flags(link2, IFF_UP); if((err = rtnl_link_change(sock, link, link2, 0)) < 0) { fprintf(stderr, "Unable to change link: %s\n", nl_geterror(err)); ret = -1; goto out; } out: if(lo_addr!=NULL) nl_addr_put(lo_addr); if(link2!=NULL) rtnl_link_put(link2); if(link!=NULL) rtnl_link_put(link); if(cache!=NULL) nl_cache_put(cache); if(addr!=NULL) rtnl_addr_put(addr); nl_close(sock); out2: nl_socket_free(sock); drop_caps(); return ret; }
int main(int argc, char *argv[]) { struct nl_sock *nl_sock; struct nl_cache *link_cache; int ifindex; int ret = 0; int err = 0; if (argc < 2) { printf("%s ip gw on/off tip\n", argv[0]); return -1; } //link if (err = rtnl_route_read_table_names(ROUTE_TABLE)) { printf("failed to read %s. err = %s\n", ROUTE_TABLE, nl_geterror(err)); return -1;; } nl_sock = nl_socket_alloc(); if (NULL == nl_sock) { printf("failed to alloc netlink handler.\n"); return -1; } if (err = nl_connect(nl_sock, NETLINK_ROUTE)) { printf("failed to connect NETLINK_ROUTE. err = %s\n", nl_geterror(err)); ret = -1; goto release_nl; } if (err = rtnl_link_alloc_cache(nl_sock, AF_INET, &link_cache)) { printf("failed to allocate link cache. err = %s\n", nl_geterror(err)); ret = -1; goto release_nl; } ifindex = rtnl_link_name2i(link_cache, NAME); if (0 == ifindex) { printf("%s - failed to find.\n", NAME); ret = -1; goto release_link_cache; } struct rtnl_link * link = rtnl_link_get(link_cache, ifindex); if (link == NULL) { printf("can't get link.\n"); ret = -1; goto release_link_cache; } //rtnl_link_get_by_name struct nl_addr *lladdr = rtnl_link_get_addr(link); if (NULL == lladdr || AF_LLC != nl_addr_get_family(lladdr)) { printf("failed to get MAC\n"); ret = -1; goto release_link; } uint8_t mac_address[ETHER_ADDR_LEN]; memcpy(mac_address, nl_addr_get_binary_addr(lladdr), ETHER_ADDR_LEN); printf("%02X:%02X:%02X:%02X:%02X:%02X\n", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); //addr struct nl_cache * addr_cache; if (err = rtnl_addr_alloc_cache(nl_sock, &addr_cache)) { printf("fail to get addr_cache\n"); ret = -1; goto release_link; } struct rtnl_addr *addr = rtnl_addr_alloc(); rtnl_addr_set_ifindex(addr, ifindex); rtnl_addr_set_family(addr, AF_INET); int prefixlen = 16; nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, get_ip, &prefixlen); nl_cache_free(addr_cache); uint32_t ipaddr = inet_addr(argv[1]); struct nl_addr * local = nl_addr_build(AF_INET, &ipaddr, sizeof(ipaddr)); rtnl_addr_set_local(addr, local); rtnl_addr_set_ifindex(addr, ifindex); rtnl_addr_set_family(addr, AF_INET); rtnl_addr_set_prefixlen(addr, 32); if (!strcmp(argv[2], "on")) { if (err = rtnl_addr_add(nl_sock, addr, 0)) { printf("fail to add addr %s\n", nl_geterror(err)); ret = -1; goto release_addr; } } else { if (err = rtnl_addr_delete(nl_sock, addr, 0)) { printf("fail to del addr %s\n", nl_geterror(err)); ret = -1; goto release_addr; } } //neigh struct nl_cache * neigh_cache; if (err = rtnl_neigh_alloc_cache(nl_sock, &neigh_cache)) { printf("failed to allocate neighbor cache. err = %s\n", nl_geterror(err)); ret = -1; goto release_neigh_cache; } uint32_t gw = inet_addr(argv[3]); struct nl_addr * gw_addr = nl_addr_build(AF_INET, &gw, sizeof(gw)); struct rtnl_neigh * neigh = rtnl_neigh_get(neigh_cache, ifindex, gw_addr); if (neigh) { // It's optional struct nl_addr * lladdr = rtnl_neigh_get_lladdr(neigh); if (lladdr) { uint8_t mac_address[ETHER_ADDR_LEN]; memcpy(mac_address, nl_addr_get_binary_addr(lladdr), ETHER_ADDR_LEN); printf("gw %02X:%02X:%02X:%02X:%02X:%02X\n", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); } } nl_addr_put(gw_addr); //route struct nl_cache *route_cache; if (err = rtnl_route_alloc_cache(nl_sock, AF_INET, 0, &route_cache)) { printf("failed to allocate route cache. err = %s\n", nl_geterror(err)); ret = -1; goto release_neigh_cache; } struct rtnl_route *route = rtnl_route_alloc(); struct nl_addr * taddr; err = nl_addr_parse(argv[4], AF_INET, &taddr); if (err) { printf("failed to get taddr. err = %s\n", nl_geterror(err)); ret = -1; goto release_route_cache; } nl_cache_foreach_filter(route_cache, OBJ_CAST(route), get_route, NULL); /* struct nl_sock *nl_fib_sock; nl_fib_sock = nl_socket_alloc(); if (err = nl_connect(nl_fib_sock, NETLINK_FIB_LOOKUP)) { printf("failed to connect NETLINK_ROUTE. err = %s\n", nl_geterror(err)); ret = -1; goto release_nl; } struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_DETAILS, }; struct nl_cache *route_cache = flnl_result_alloc_cache(); struct flnl_request *req = flnl_request_alloc(); struct nl_addr * taddr; err = nl_addr_parse(argv[4], AF_INET, &taddr); if (err) { printf("failed to get taddr. err = %s\n", nl_geterror(err)); ret = -1; goto release_route; } int table = RT_TABLE_UNSPEC, scope = RT_SCOPE_UNIVERSE; flnl_request_set_addr(req, taddr); flnl_request_set_table(req, table); flnl_request_set_scope(req, scope); err = flnl_lookup(nl_fib_sock, req, route_cache); if (err) { printf("failed to fib lookup. err = %s\n", nl_geterror(err)); ret = -1; goto release_route_addr; } nl_cache_dump(route_cache, ¶ms); release_route_addr: nl_addr_put(taddr); release_route: nl_cache_free(route_cache); nl_object_put(OBJ_CAST(req)); nl_close(nl_fib_sock); nl_socket_free(nl_fib_sock); */ release_route_cache: nl_cache_free(route_cache); release_neigh_cache: nl_cache_free(neigh_cache); release_addr: nl_addr_put(local); rtnl_addr_put(addr); release_link: rtnl_link_put(link); release_link_cache: nl_cache_free(link_cache); release_nl: nl_close(nl_sock); nl_socket_free(nl_sock); return ret; }
static void get_filter(struct rtnl_route *r, int ac, char **av, int idx, struct nl_cache *cache, struct nl_cache *link_cache) { while (ac > idx) { if (!strcasecmp(av[idx], "src")) { if (ac > ++idx) { struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC); if (!a) goto err; rtnl_route_set_pref_src(r, a); nl_addr_put(a); } } else if (!strcasecmp(av[idx], "dst")) { if (ac > ++idx) { struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC); if (!a) goto err; rtnl_route_set_dst(r, a); nl_addr_put(a); } } else if (!strcasecmp(av[idx], "via")) { if (ac > ++idx) { struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC); if (!a) goto err; rtnl_route_set_gateway(r, a); nl_addr_put(a); } } else if (!strcasecmp(av[idx], "from")) { if (ac > ++idx) { struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC); if (!a) goto err; rtnl_route_set_src(r, a); nl_addr_put(a); } } else if (!strcasecmp(av[idx], "tos")) { if (ac > ++idx) rtnl_route_set_tos(r, strtoul(av[idx++], NULL, 0)); } else if (!strcasecmp(av[idx], "prio")) { if (ac > ++idx) rtnl_route_set_prio(r, strtoul(av[idx++], NULL, 0)); } else if (!strcasecmp(av[idx], "scope")) { if (ac > ++idx) rtnl_route_set_scope(r, rtnl_str2scope(av[idx++])); } else if (!strcasecmp(av[idx], "dev")) { if (ac > ++idx) { int ifindex = rtnl_link_name2i(link_cache, av[idx++]); if (ifindex == RTNL_LINK_NOT_FOUND) goto err_notfound; rtnl_route_set_oif(r, ifindex); } } else if (!strcasecmp(av[idx], "table")) { if (ac > ++idx) rtnl_route_set_table(r, strtoul(av[idx++], NULL, 0)); } else { fprintf(stderr, "What is '%s'?\n", av[idx]); exit(1); } } return; err_notfound: fprintf(stderr, "Unable to find device \"%s\"\n", av[idx-1]); exit(1); err: fprintf(stderr, "%s\n", nl_geterror()); exit(1); }
static int _set_ip(nozzle_t nozzle, int command, const char *ipaddr, const char *prefix, int secondary) { int fam; char *broadcast = NULL; int err = 0; #ifdef KNET_LINUX struct rtnl_addr *addr = NULL; struct nl_addr *local_addr = NULL; struct nl_addr *bcast_addr = NULL; struct nl_cache *cache = NULL; int ifindex; #endif #ifdef KNET_BSD char cmdline[4096]; char proto[6]; char *error_string = NULL; #endif if (!strchr(ipaddr, ':')) { fam = AF_INET; broadcast = generate_v4_broadcast(ipaddr, prefix); if (!broadcast) { errno = EINVAL; return -1; } } else { fam = AF_INET6; } #ifdef KNET_LINUX addr = rtnl_addr_alloc(); if (!addr) { errno = ENOMEM; return -1; } if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) { errno = ENOMEM; err = -1; goto out; } ifindex = rtnl_link_name2i(cache, nozzle->name); if (ifindex == 0) { errno = ENOENT; err = -1; goto out; } rtnl_addr_set_ifindex(addr, ifindex); if (nl_addr_parse(ipaddr, fam, &local_addr) < 0) { errno = EINVAL; err = -1; goto out; } if (rtnl_addr_set_local(addr, local_addr) < 0) { errno = EINVAL; err = -1; goto out; } if (broadcast) { if (nl_addr_parse(broadcast, fam, &bcast_addr) < 0) { errno = EINVAL; err = -1; goto out; } if (rtnl_addr_set_broadcast(addr, bcast_addr) < 0) { errno = EINVAL; err = -1; goto out; } } rtnl_addr_set_prefixlen(addr, atoi(prefix)); if (command == IP_ADD) { if (rtnl_addr_add(lib_cfg.nlsock, addr, 0) < 0) { errno = EINVAL; err = -1; goto out; } } else { if (rtnl_addr_delete(lib_cfg.nlsock, addr, 0) < 0) { errno = EINVAL; err = -1; goto out; } } out: if (addr) { rtnl_addr_put(addr); } if (local_addr) { nl_addr_put(local_addr); } if (bcast_addr) { nl_addr_put(bcast_addr); } if (cache) { nl_cache_put(cache); } if (broadcast) { free(broadcast); } return err; #endif #ifdef KNET_BSD /* * TODO: port to use ioctl and such, drop shell forking here */ memset(cmdline, 0, sizeof(cmdline)); if (fam == AF_INET) { snprintf(proto, sizeof(proto), "inet"); } else { snprintf(proto, sizeof(proto), "inet6"); } if (command == IP_ADD) { snprintf(cmdline, sizeof(cmdline)-1, "ifconfig %s %s %s/%s", nozzle->name, proto, ipaddr, prefix); if (broadcast) { snprintf(cmdline + strlen(cmdline), sizeof(cmdline) - strlen(cmdline) -1, " broadcast %s", broadcast); } if ((secondary) && (fam == AF_INET)) { snprintf(cmdline + strlen(cmdline), sizeof(cmdline) - strlen(cmdline) -1, " alias"); } } else { snprintf(cmdline, sizeof(cmdline)-1, "ifconfig %s %s %s/%s delete", nozzle->name, proto, ipaddr, prefix); } if (broadcast) { free(broadcast); } /* * temporary workaround as we port libnozzle to BSD ioctl * for IP address management */ err = execute_bin_sh_command(cmdline, &error_string); if (error_string) { free(error_string); error_string = NULL; } return err; #endif }