Esempio n. 1
0
/**
 * Set the outgoing interface of a route via a interface name
 * @arg route		route to be changed
 * @arg cache		link cache to look up interface index
 * @arg name		interface name of new outgoing interface
 * @return 0 on success or a negative error code.
 */
int rtnl_route_set_oif_name(struct rtnl_route *route,
			    struct nl_cache *cache, const char *name)
{
	int i = rtnl_link_name2i(cache, name);

	if (RTNL_LINK_NOT_FOUND == i)
		return nl_error(ENOENT, "Link %s is unknown", name);
	rtnl_route_set_oif(route, i);
	return 0;
}
	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;
	}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/**
 * Set interface index via interface name
 * @arg neigh		neighbour to change
 * @arg cache		link cache holding all links
 * @arg name		name of interface
 * @return 0 on success or a negative error code
 */
int rtnl_neigh_set_ifindex_name(struct rtnl_neigh *neigh,
				struct nl_cache *cache, const char *name)
{
	int i;

	if (cache->c_type != RTNL_LINK)
		return nl_error(EINVAL, "Must be link cache");

	i = rtnl_link_name2i(cache, name);

	if (RTNL_LINK_NOT_FOUND == i)
		return nl_error(ENOENT, "Link %s is unknown", name);

	rtnl_neigh_set_ifindex(neigh, i);
	return 0;
}
int
nm_netlink_iface_to_index (const char *iface)
{
	NMNetlinkMonitor *self;
	NMNetlinkMonitorPrivate *priv;
	int idx;

	g_return_val_if_fail (iface != NULL, -1);

	self = nm_netlink_monitor_get ();
	priv = NM_NETLINK_MONITOR_GET_PRIVATE (self);

	nl_cache_refill (priv->nlh_sync, priv->link_cache);
	idx = rtnl_link_name2i (priv->link_cache, iface);
	g_object_unref (self);

	return idx;
}
Esempio n. 7
0
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
int main(int argc, char *argv[])
{
	struct nl_handle *nlh;
	struct nl_cache *link_cache;
	int err = -1, ifindex;

	if (nltool_init(argc, argv) < 0)
		return -1;

	if (argc < 2 || !strcmp(argv[1], "-h")) {
		printf("Usage: nl-link-name2ifindex <name>\n");
		return -1;
	}

	nlh = nl_handle_alloc_nondefault(nltool_cbset);
	if (!nlh)
		return -1;

	if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
		goto errout;

	link_cache = nltool_alloc_link_cache(nlh);
	if (!link_cache)
		goto errout;

	if ((ifindex = rtnl_link_name2i(link_cache, argv[1])) == RTNL_LINK_NOT_FOUND)
		fprintf(stderr, "Interface %s does not exist\n", argv[1]);
	else
		printf("%d\n", ifindex);

	nl_cache_free(link_cache);
	err = 0;
errout:
	nl_close(nlh);
	nl_handle_destroy(nlh);

	return err;
}
Esempio n. 10
0
/**
 * 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;
}
Esempio n. 12
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;
}
Esempio n. 13
0
File: vlan_util.c Progetto: imw/hapd
/*
 * Add a vlan interface with name 'vlan_if_name', VLAN ID 'vid' and
 * tagged interface 'if_name'.
 *
 * returns -1 on error
 * returns 1 if the interface already exists
 * returns 0 otherwise
*/
int vlan_add(const char *if_name, int vid, const char *vlan_if_name)
{
	int ret = -1;
	struct nl_sock *handle = NULL;
	struct nl_cache *cache = NULL;
	struct rtnl_link *rlink = NULL;
	int if_idx = 0;

	wpa_printf(MSG_DEBUG, "VLAN: vlan_add(if_name=%s, vid=%d, "
		   "vlan_if_name=%s)", if_name, vid, vlan_if_name);

	if ((os_strlen(if_name) + 1) > IFNAMSIZ) {
		wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'",
			   if_name);
		return -1;
	}

	if ((os_strlen(vlan_if_name) + 1) > IFNAMSIZ) {
		wpa_printf(MSG_ERROR, "VLAN: Interface name too long: '%s'",
			   vlan_if_name);
		return -1;
	}

	handle = nl_socket_alloc();
	if (!handle) {
		wpa_printf(MSG_ERROR, "VLAN: failed to open netlink socket");
		goto vlan_add_error;
	}

	if (nl_connect(handle, NETLINK_ROUTE) < 0) {
		wpa_printf(MSG_ERROR, "VLAN: failed to connect to netlink");
		goto vlan_add_error;
	}

	if (rtnl_link_alloc_cache(handle, AF_UNSPEC, &cache) < 0) {
		cache = NULL;
		wpa_printf(MSG_ERROR, "VLAN: failed to alloc cache");
		goto vlan_add_error;
	}

	if (!(if_idx = rtnl_link_name2i(cache, if_name))) {
		/* link does not exist */
		wpa_printf(MSG_ERROR, "VLAN: interface %s does not exist",
			   if_name);
		goto vlan_add_error;
	}

	if ((rlink = rtnl_link_get_by_name(cache, vlan_if_name))) {
		/* link does exist */
		rtnl_link_put(rlink);
		rlink = NULL;
		wpa_printf(MSG_ERROR, "VLAN: interface %s already exists",
			   vlan_if_name);
		ret = 1;
		goto vlan_add_error;
	}

	rlink = rtnl_link_alloc();
	if (!rlink) {
		wpa_printf(MSG_ERROR, "VLAN: failed to allocate new link");
		goto vlan_add_error;
	}

	if (rtnl_link_set_type(rlink, "vlan") < 0) {
		wpa_printf(MSG_ERROR, "VLAN: failed to set link type");
		goto vlan_add_error;
	}

	rtnl_link_set_link(rlink, if_idx);
	rtnl_link_set_name(rlink, vlan_if_name);

	if (rtnl_link_vlan_set_id(rlink, vid) < 0) {
		wpa_printf(MSG_ERROR, "VLAN: failed to set link vlan id");
		goto vlan_add_error;
	}

	if (rtnl_link_add(handle, rlink, NLM_F_CREATE) < 0) {
		wpa_printf(MSG_ERROR, "VLAN: failed to create link %s for "
			   "vlan %d on %s (%d)",
			   vlan_if_name, vid, if_name, if_idx);
		goto vlan_add_error;
	}

	ret = 0;

vlan_add_error:
	if (rlink)
		rtnl_link_put(rlink);
	if (cache)
		nl_cache_free(cache);
	if (handle)
		nl_socket_free(handle);
	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);
}
Esempio n. 15
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
}