Exemple #1
0
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);

}
Exemple #2
0
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;
}
Exemple #3
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();
}
Exemple #4
0
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;
}
Exemple #6
0
/* 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;
}
Exemple #9
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, &params, 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);
	}
}
Exemple #10
0
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;
}
Exemple #11
0
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, &params);

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);
}
Exemple #13
0
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
}