int main(int argc, char *argv[])
{
	struct rtnl_link *link;
	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;
	}

	link = rtnl_link_alloc();
	rtnl_link_set_name(link, "my_bond");

	if ((err = rtnl_link_delete(sk, link)) < 0) {
		nl_perror(err, "Unable to delete link");
		return err;
	}

	rtnl_link_put(link);
	nl_close(sk);

	return 0;
}
Example #2
0
static bool nl80211_init()
{
	int err;

	sock = nl_socket_alloc();
	if (!sock) {
		fprintf(stderr, "failed to allocate netlink socket\n");
		goto out;
	}

	err = genl_connect(sock);
	if (err) {
		nl_perror(err, "failed to make generic netlink connection");
		goto out;
	}

	err = genl_ctrl_alloc_cache(sock, &cache);
	if (err) {
		nl_perror(err, "failed to allocate netlink controller cache");
		goto out;
	}

	family = genl_ctrl_search_by_name(cache, NL80211_GENL_NAME);
	if (!family) {
		fprintf(stderr, "failed to find nl80211\n");
		goto out;
	}

	return true;
out:
	genl_family_put(family);
	nl_cache_free(cache);
	nl_socket_free(sock);
	return false;
}
int main(int argc, char *argv[])
{
	struct nl_cache_mngr *mngr;
	struct nl_sock *sock;
	struct nl_cache *ct;

	sock = nlt_socket_alloc();

	mngr = nl_cache_mngr_alloc(sock, NETLINK_NETFILTER, NL_AUTO_PROVIDE);
	if (!mngr) {
		nl_perror("nl_cache_mngr_alloc");
		return -1;
	}

	ct = nl_cache_mngr_add(mngr, "netfilter/ct", &change_cb);
	if (ct == NULL) {
		nl_perror("nl_cache_mngr_add(netfilter/ct)");
		return -1;
	}

	for (;;) {
		int err = nl_cache_mngr_poll(mngr, 5000);
		if (err < 0) {
			nl_perror("nl_cache_mngr_poll()");
			return -1;
		}

	}

	nl_cache_mngr_free(mngr);

	return 0;
}
Example #4
0
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;
}
Example #5
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;
}
Example #6
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;
}
Example #7
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;
}
int main(int argc, char *argv[])
{
	struct nl_sock *h[1025];
	int i;

	h[0] = nl_handle_alloc();
	printf("Created handle with port 0x%x\n",
			nl_socket_get_local_port(h[0]));
	nl_handle_destroy(h[0]);
	h[0] = nl_handle_alloc();
	printf("Created handle with port 0x%x\n",
			nl_socket_get_local_port(h[0]));
	nl_handle_destroy(h[0]);

	for (i = 0; i < 1025; i++) {
		h[i] = nl_handle_alloc();
		if (h[i] == NULL)
			nl_perror("Unable to allocate socket");
		else
			printf("Created handle with port 0x%x\n",
				nl_socket_get_local_port(h[i]));
	}

	return 0;
}
Example #9
0
static int get_devices_handler(struct nl_msg *n, void *arg)
{
	struct nlmsghdr *nlh = nlmsg_hdr(n);
	struct nlattr *attrs[NFC_ATTR_MAX + 1];
	char *name;
	uint32_t idx, protocols;
	bool powered;

	DBG("");

	genlmsg_parse(nlh, 0, attrs, NFC_ATTR_MAX, NULL);

	if (!attrs[NFC_ATTR_DEVICE_INDEX] ||
	    !attrs[NFC_ATTR_DEVICE_NAME] ||
	    !attrs[NFC_ATTR_PROTOCOLS]) {
		nl_perror(NLE_MISSING_ATTR, "NFC_CMD_GET_DEVICE");
		return NL_STOP;
	}

	idx = nla_get_u32(attrs[NFC_ATTR_DEVICE_INDEX]);
	name = nla_get_string(attrs[NFC_ATTR_DEVICE_NAME]);
	protocols = nla_get_u32(attrs[NFC_ATTR_PROTOCOLS]);

	if (!attrs[NFC_ATTR_DEVICE_POWERED])
		powered = false;
	else
		powered = nla_get_u8(attrs[NFC_ATTR_DEVICE_POWERED]);

	__near_manager_adapter_add(idx, name, protocols, powered);

	return NL_SKIP;
}
Example #10
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;
}
Example #11
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;
}
Example #12
0
int main(int argc, char **argv)
{
	int c;
	int i;
	int family;
	int group;
	struct nl_sock *nl;
	struct nl_msg *msg;
	char *dummy = NULL;

	/* Currently processed command info */
	struct iz_cmd cmd;


	/* Parse options */
	while (1) {
#ifdef HAVE_GETOPT_LONG
		int opt_idx = -1;
		c = getopt_long(argc, argv, "d::vh", iz_long_opts, &opt_idx);
#else
		c = getopt(argc, argv, "d::vh");
#endif
		if (c == -1)
			break;

		switch(c) {
		case 'd':
			if (optarg) {
				i = strtol(optarg, &dummy, 10);
				if (*dummy == '\0')
					iz_debug = nl_debug = i;
				else {
					fprintf(stderr, "Error: incorrect debug level: '%s'\n", optarg);
					exit(1);
				}
			} else
				iz_debug = nl_debug = 1;
			break;
		case 'v':
			printf(	"iz " VERSION "\n"
				"Copyright (C) 2008, 2009 by Siemens AG\n"
				"License GPLv2 GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.\n"
				"This is free software: you are free to change and redistribute it.\n"
				"There is NO WARRANTY, to the extent permitted by law.\n"
				"\n"
				"Written by Dmitry Eremin-Solenikov, Sergey Lapin and Maxim Osipov\n");
			return 0;
		case 'h':
			iz_help(argv[0]);
			return 0;
		default:
			iz_help(argv[0]);
			return 1;
		}
	}
	if (optind >= argc) {
		iz_help(argv[0]);
		return 1;
	}

	memset(&cmd, 0, sizeof(cmd));

	cmd.argc = argc - optind;
	cmd.argv = argv + optind;

	/* Parse command */
	cmd.desc = get_cmd(argv[optind]);
	if (!cmd.desc) {
		printf("Unknown command %s!\n", argv[optind]);
		return 1;
	}
	if (cmd.desc->parse) {
		i = cmd.desc->parse(&cmd);
		if (i == IZ_STOP_OK) {
			return 0;
		} else if (i == IZ_STOP_ERR) {
			printf("Command line parsing error!\n");
			return 1;
		}
	}

	/* Prepare NL command */
	nl = nl_socket_alloc();
	if (!nl) {
		nl_perror(NLE_NOMEM, "Could not allocate NL handle");
		return 1;
	}
	genl_connect(nl);
	family = genl_ctrl_resolve(nl, IEEE802154_NL_NAME);
	group = nl_get_multicast_id(nl,
			IEEE802154_NL_NAME, IEEE802154_MCAST_COORD_NAME);
	if (group < 0) {
		fprintf(stderr, "Could not get multicast group ID: %s\n", strerror(-group));
		return 1;
	}
	nl_socket_add_membership(nl, group);
	iz_seq = nl_socket_use_seq(nl) + 1;
	nl_socket_modify_cb(nl, NL_CB_VALID, NL_CB_CUSTOM,
		iz_cb_valid, (void*)&cmd);
	nl_socket_modify_cb(nl, NL_CB_FINISH, NL_CB_CUSTOM,
		iz_cb_finish, (void*)&cmd);
	nl_socket_modify_cb(nl, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
		iz_cb_seq_check, (void*)&cmd);

	/* Send request, if necessary */
	if (cmd.desc->request) {
		msg = nlmsg_alloc();
		if (!msg) {
			nl_perror(NLE_NOMEM, "Could not allocate NL message!\n"); /* FIXME: err */
			return 1;
		}
		genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0,
			cmd.flags, cmd.desc->nl_cmd, 1);

		if (cmd.desc->request(&cmd, msg) != IZ_CONT_OK) {
			printf("Request processing error!\n");
			return 1;
		}

		dprintf(1, "nl_send_auto_complete\n");
		nl_send_auto_complete(nl, msg);
		cmd.seq = nlmsg_hdr(msg)->nlmsg_seq;

		dprintf(1, "nlmsg_free\n");
		nlmsg_free(msg);
	}

	/* Received message handling loop */
	while (iz_exit == IZ_CONT_OK) {
		int err = nl_recvmsgs_default(nl);
		if (err != NLE_SUCCESS) {
			nl_perror(err, "Receive failed");
			return 1;
		}
	}
	nl_close(nl);

	if (iz_exit == IZ_STOP_ERR)
		return 1;

	return 0;
}
Example #13
0
int main(int argc, char *argv[])
{
	struct stat sb; // To check if config file exist.
	struct in_addr iaddrf, iaddrl;      // To validate IP addresses
    struct in6_addr i6addrf;   			// also
    cfg_t *cfg, *cfg_ipv4, *cfg_ipv6;
	const char *sect_name;
	char *addr_first, *addr_last;
    unsigned char addr_maskbits;
    int port_first, port_last;
    char which[sizeof("ABC")];
    
    struct config_struct cs;

	struct nl_sock *nls;
	int ret;

	if (argc != 2)
	{
		printf("Usage: %s <config-file>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ( stat(argv[1], &sb) == -1 )
	{
		printf("Error: Can not open configuration file: %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}

    cfg_opt_t ipv4_opts[] =
    {
        CFG_STR("ipv4_addr_net", IPV4_DEF_NET, CFGF_NONE), 
        CFG_INT("ipv4_addr_net_mask_bits", IPV4_DEF_MASKBITS, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_first", IPV4_DEF_POOL_FIRST, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_last", IPV4_DEF_POOL_LAST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_first", IPV4_DEF_TCP_POOL_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_last", IPV4_DEF_TCP_POOL_LAST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_first", IPV4_DEF_UDP_POOL_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_last", IPV4_DEF_UDP_POOL_LAST, CFGF_NONE), 
        CFG_END()
    };
	cfg_opt_t ipv6_opts[] =
    {
        CFG_STR("ipv6_net_prefix", IPV6_DEF_PREFIX, CFGF_NONE), 
        CFG_INT("ipv6_net_mask_bits", IPV6_DEF_MASKBITS, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_first", IPV6_DEF_TCP_POOL_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_last", IPV6_DEF_TCP_POOL_LAST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_first", IPV6_DEF_UDP_POOL_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_last", IPV6_DEF_UDP_POOL_LAST, CFGF_NONE), 
		CFG_END()
    };
    cfg_opt_t opts[] =
    {
        CFG_SEC("ipv4", ipv4_opts, CFGF_NONE),
        CFG_SEC("ipv6", ipv6_opts, CFGF_NONE),
        CFG_END()
    };

    cfg = cfg_init(opts, CFGF_NONE);
    if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR)
	{
		printf("Error parsing configuration file: %s\n", argv[1]);
        exit_error_conf(cfg);
	}

	/* Loading IPv4 configuration */
	{
        cfg_ipv4 = cfg_getsec(cfg, "ipv4");

		sect_name = cfg_name(cfg_ipv4);
		printf ("Section: %s\n", sect_name);

		addr_first = cfg_getstr(cfg_ipv4, "ipv4_addr_net");
        if ( inet_aton(addr_first, &iaddrf) == 0 )	// Validate ipv4 addr
		{
			printf("Error: Invalid IPv4 address net: %s\n", addr_first);
			exit_error_conf(cfg);
		}
        addr_maskbits = cfg_getint(cfg_ipv4, "ipv4_addr_net_mask_bits");
        if (addr_maskbits > 32 || addr_maskbits < 0)
        {
            printf("Error: Bad IPv4 network mask bits value: %d\n", addr_maskbits);
			exit_error_conf(cfg);
        }
		cs.ipv4_addr_net = iaddrf;
        cs.ipv4_addr_net_mask_bits = addr_maskbits;
		printf("\tPool Network: %s/%d\n", addr_first, addr_maskbits);
		//
		addr_first = cfg_getstr(cfg_ipv4, "ipv4_pool_range_first");
        addr_last = cfg_getstr(cfg_ipv4, "ipv4_pool_range_last");
		if ( inet_aton(addr_first, &iaddrf) == 0 )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_first: %s\n", addr_first);
			exit_error_conf(cfg);
		}
		if ( inet_aton(addr_last, &iaddrl) == 0 )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_last: %s\n", addr_last);
			exit_error_conf(cfg);
		}
		if (iaddrf.s_addr > iaddrl.s_addr)	// Validate that: first < last
		{
			printf("Error: First pool address is greater than last pool address.\n");
			exit_error_conf(cfg);
		}
        cs.ipv4_pool_range_first = iaddrf;
        cs.ipv4_pool_range_last = iaddrl;
		printf("\t\t- First address: %s\n", inet_ntoa(iaddrf));
		printf("\t\t- Last address: %s\n", inet_ntoa(iaddrl));
        //
        port_first = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_last");
        sprintf(which, "TCP");
        if (port_first < 0 || port_first > 65535)
        {
            printf("Error: Invalid first %s port: %d\n", which, port_first);
            exit_error_conf(cfg);
        }
        if (port_last < 0 || port_last > 65535)
        {
            printf("Error: Invalid last %s port: %d\n", which, port_last);
            exit_error_conf(cfg);
        }
        if (port_first > port_last)
        {
            printf("Error: First %s port is greater than last port.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_tcp_port_first = port_first;
        cs.ipv4_tcp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_last");
        sprintf(which, "UDP");
        if (port_first < 0 || port_first > 65535)
        {
            printf("Error: Invalid first %s port: %d\n", which, port_first);
            exit_error_conf(cfg);
        }
        if (port_last < 0 || port_last > 65535)
        {
            printf("Error: Invalid last %s port: %d\n", which, port_last);
            exit_error_conf(cfg);
        }
        if (port_first > port_last)
        {
            printf("Error: First %s port is greater than last port.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_udp_port_first = port_first;
        cs.ipv4_udp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
        
		printf ("\n" );
    }
	
    /* Loading IPv6 configuration */
	{
        cfg_ipv6 = cfg_getsec(cfg, "ipv6");

		sect_name = cfg_name(cfg_ipv6);
        
		printf ("Section: %s\n", sect_name );
		addr_first = cfg_getstr(cfg_ipv6, "ipv6_net_prefix");
        
        if ( inet_pton(AF_INET6, addr_first, &i6addrf) < 1 )	// Validate ipv6 addr
		{
			printf("Error: Invalid IPv6 address net: %s\n", addr_first);
			exit_error_conf(cfg);
		}
        addr_maskbits = cfg_getint(cfg_ipv6, "ipv6_net_mask_bits");
        if (addr_maskbits > 128 || addr_maskbits < 0)
        {
            printf("Error: Bad IPv6 network mask bits value: %d\n", addr_maskbits);
			exit_error_conf(cfg);
        }
		cs.ipv6_net_prefix = i6addrf;
        cs.ipv6_net_mask_bits = addr_maskbits;
		printf("\tPrefix: %s/%d\n", addr_first, addr_maskbits);
        //
        port_first = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_last");
        sprintf(which, "TCP");
        if (port_first < 0 || port_first > 65535)
        {
            printf("Error: Invalid first %s port: %d\n", which, port_first);
            exit_error_conf(cfg);
        }
        if (port_last < 0 || port_last > 65535)
        {
            printf("Error: Invalid last %s port: %d\n", which, port_last);
            exit_error_conf(cfg);
        }
        if (port_first > port_last)
        {
            printf("Error: First %s port is greater than last port.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_tcp_port_range_first = port_first;
        cs.ipv6_tcp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_last");
        sprintf(which, "UDP");
        if (port_first < 0 || port_first > 65535)
        {
            printf("Error: Invalid first %s port: %d\n", which, port_first);
            exit_error_conf(cfg);
        }
        if (port_last < 0 || port_last > 65535)
        {
            printf("Error: Invalid last %s port: %d\n", which, port_last);
            exit_error_conf(cfg);
        }
        if (port_first > port_last)
        {
            printf("Error: First %s port is greater than last port.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_udp_port_range_first = port_first;
        cs.ipv6_udp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
        
		printf ("\n" );
    }

	cfg_free(cfg);

    /* We got the configuration structure, now send it to the module
     * using netlink sockets. */

    // Reserve memory for netlink socket
    nls = nl_socket_alloc();
    if (!nls) {
        printf("bad nl_socket_alloc\n");
        return EXIT_FAILURE;
    }

	// Bind and connect the socket to a protocol
    ret = nl_connect(nls, NETLINK_USERSOCK);
    if (ret < 0) {
        nl_perror(ret, "nl_connect");
        nl_socket_free(nls);
        return EXIT_FAILURE;
    }

    ret = nl_send_simple(nls, MY_MSG_TYPE, 0, &(cs), sizeof(cs));
    if (ret < 0) {
        nl_perror(ret, "nl_send_simple");
        printf("Error sending message, is module loaded?\n");
        nl_close(nls);
        nl_socket_free(nls);
        return EXIT_FAILURE;
    } else {        
	    printf("Message sent (%d bytes):\n", ret);
        //print_nat64_run_conf(nrc);
    }
		

    nl_close(nls);
    nl_socket_free(nls);
    
    exit(EXIT_SUCCESS);
}
Example #14
0
static inline void __nl_perror(int error, const char *s)
{
	nl_perror(s);
}
Example #15
0
/**
* Main function of the user app that parses configuration file and sends it to
* NAT64 kernel module.
*
* @param argc	Qty of arguments in command line call.
* @param argv	Array of arguments in command line call.
*/
int main(int argc, char *argv[])
{
	struct stat sb; // To check if config file exist.
	struct in_addr iaddrn, iaddrf, iaddrl;      // To validate IP addresses
    struct in6_addr i6addrf;   			// also
    cfg_t *cfg, *cfg_ipv4, *cfg_ipv6;
	const char *sect_name;
	char *addr_first, *addr_last;
    unsigned char addr_maskbits;
    int port_first, port_last;
    char which[sizeof("ABC")];
    char str[INET_ADDRSTRLEN];
    
    struct config_struct cs;

	struct nl_sock *nls;
	int ret;

	int i = 0;
	struct ipv6_prefixes **ipv6_pref = NULL;
	unsigned char ipv6_pref_qty;
	char ipv6_def_prefix64[sizeof("1111:2222:3333:4444:5555:6666::/128")];
	char *ipv6_buf;  
	char *ipv6_check_addr; 
	char *ipv6_check_maskbits; 

	if (argc != 2)
	{
		printf("Usage: %s <config-file>\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ( stat(argv[1], &sb) == -1 )
	{
		printf("Error: Can not open configuration file: %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}

	// Load default configuration values for each config option, just in case 
	// they were not included in the config file.
    cfg_opt_t ipv4_opts[] =
    {
        CFG_STR("ipv4_addr_net", IPV4_DEF_NET, CFGF_NONE), 
        CFG_INT("ipv4_addr_net_mask_bits", IPV4_DEF_MASKBITS, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_first", IPV4_DEF_POOL_FIRST, CFGF_NONE), 
        CFG_STR("ipv4_pool_range_last", IPV4_DEF_POOL_LAST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_first", IPV4_DEF_TCP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_tcp_port_range_last", IPV4_DEF_TCP_PORTS_LAST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_first", IPV4_DEF_UDP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv4_udp_port_range_last", IPV4_DEF_UDP_PORTS_LAST, CFGF_NONE), 
        CFG_END()
    };

	// Load default configuration values for each config option, just in case 
	// they were not included in the config file.
	sprintf(ipv6_def_prefix64, "%s/%d", IPV6_DEF_PREFIX, IPV6_DEF_MASKBITS );
	cfg_opt_t ipv6_opts[] =
    {
        CFG_STR_LIST("ipv6_net_prefixes", ipv6_def_prefix64, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_first", IPV6_DEF_TCP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_tcp_port_range_last", IPV6_DEF_TCP_PORTS_LAST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_first", IPV6_DEF_UDP_PORTS_FIRST, CFGF_NONE), 
        CFG_INT("ipv6_udp_port_range_last", IPV6_DEF_UDP_PORTS_LAST, CFGF_NONE), 
		CFG_END()
    };
    // Define two sections in config file
    cfg_opt_t opts[] =
    {
        CFG_SEC("ipv4", ipv4_opts, CFGF_NONE),
        CFG_SEC("ipv6", ipv6_opts, CFGF_NONE),
        CFG_END()
    };

	// Parse config file
    cfg = cfg_init(opts, CFGF_NONE);
    if(cfg_parse(cfg, argv[1]) == CFG_PARSE_ERROR)
	{
		printf("Error parsing configuration file: %s\n", argv[1]);
        exit_error_conf(cfg);
	}

	/*
	 * Loading IPv4 configuration
	 *
	 */
	{
        cfg_ipv4 = cfg_getsec(cfg, "ipv4");

		sect_name = cfg_name(cfg_ipv4);
		printf ("Section: %s\n", sect_name);

		// Validate IPv4 pool address
		addr_first = cfg_getstr(cfg_ipv4, "ipv4_addr_net");
        if ( convert_ipv4_addr(addr_first, &iaddrn) == EXIT_FAILURE )	
		{
			printf("Error: Invalid IPv4 address net: %s\n", addr_first);
			exit_error_conf(cfg);
		}
		// Validate netmask bits
        addr_maskbits = cfg_getint(cfg_ipv4, "ipv4_addr_net_mask_bits");
        if ( validate_ipv4_netmask_bits(addr_maskbits) == EXIT_FAILURE )
        {
            printf("Error: Bad IPv4 network mask bits value: %d\n", addr_maskbits);
			exit_error_conf(cfg);
        }
        // Store values in config struct
		cs.ipv4_addr_net = iaddrn;
        cs.ipv4_addr_net_mask_bits = addr_maskbits;
		printf("\tPool Network: %s/%d\n", addr_first, addr_maskbits);
		
		// Validate pool addresses range
		addr_first = cfg_getstr(cfg_ipv4, "ipv4_pool_range_first");
        addr_last = cfg_getstr(cfg_ipv4, "ipv4_pool_range_last");
		if ( convert_ipv4_addr(addr_first, &iaddrf) == EXIT_FAILURE )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_first: %s\n", addr_first);
			exit_error_conf(cfg);
		}
		if ( convert_ipv4_addr(addr_last, &iaddrl) == EXIT_FAILURE  )	// Validate ipv4 addr
		{
			printf("Error: Malformed ipv4_pool_range_last: %s\n", addr_last);
			exit_error_conf(cfg);
		}
		if (  validate_ipv4_pool_range(&iaddrn, addr_maskbits, &iaddrf, &iaddrl) == EXIT_FAILURE )	// Validate that: first < last
		{
			printf("Error: Pool addresses badly defined.\n");
			exit_error_conf(cfg);
		}
		// Store values in config struct
        cs.ipv4_pool_range_first = iaddrf;
        cs.ipv4_pool_range_last = iaddrl;
        inet_ntop(AF_INET, &(iaddrf.s_addr), str, INET_ADDRSTRLEN);
		printf("\t\t- First address: %s\n", str);
        inet_ntop(AF_INET, &(iaddrl.s_addr), str, INET_ADDRSTRLEN);
		printf("\t\t- Last address: %s\n", str);
        
        // Validate port ranges
        port_first = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_tcp_port_range_last");
        sprintf(which, "TCP");
        if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            //~ printf("Error: Invalid first %s port: %d\n", which, port_first);
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_tcp_port_first = port_first;
        cs.ipv4_tcp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv4, "ipv4_udp_port_range_last");
        sprintf(which, "UDP");
       if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv4_udp_port_first = port_first;
        cs.ipv4_udp_port_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		printf ("\n" );
    }
	
    /*
     * Loading IPv6 configuration
     *
     */
	{
        cfg_ipv6 = cfg_getsec(cfg, "ipv6");

		sect_name = cfg_name(cfg_ipv6);
        
		printf ("Section: %s\n", sect_name );
        
        // Get number of IPv6 prefixes.
        ipv6_pref_qty = cfg_size(cfg_ipv6, "ipv6_net_prefixes"); 
        // Allocate memory for the array of prefixes.
        ipv6_pref = (struct ipv6_prefixes **) malloc(ipv6_pref_qty * sizeof(struct ipv6_prefixes *));
        for(i = 0; i < ipv6_pref_qty; i++)
        {
			// Split prefix and netmask bits
			ipv6_buf = cfg_getnstr(cfg_ipv6, "ipv6_net_prefixes", i);
			ipv6_check_addr = strtok(ipv6_buf, "/");
			ipv6_check_maskbits = strtok(NULL, "/");
			
			// Validate IPv6 addr
			if ( convert_ipv6_addr(ipv6_check_addr, &i6addrf) == EXIT_FAILURE )	
			{
				printf("Error: Invalid IPv6 address net: %s\n", ipv6_check_addr);
				exit_error_conf(cfg);
			}
			// Validate netmask bits
			addr_maskbits = atoi(ipv6_check_maskbits);
			if ( validate_ipv6_netmask_bits(addr_maskbits) == EXIT_FAILURE )
			{
				printf("Error: Bad IPv6 network mask bits value: %d\n", addr_maskbits);
				exit_error_conf(cfg);
			}
			
			// Allocate memory for each IPv6 prefix
			ipv6_pref[i] = (struct ipv6_prefixes *) malloc(sizeof(struct ipv6_prefixes));
			ipv6_pref[i]->addr = (i6addrf);
			ipv6_pref[i]->maskbits = addr_maskbits;
        }
        // Store prefixes in the config struct
        cs.ipv6_net_prefixes = ipv6_pref;
        cs.ipv6_net_prefixes_qty = ipv6_pref_qty;
			
               
        // Validate port ranges
        port_first = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_tcp_port_range_last");
        sprintf(which, "TCP");
		if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_tcp_port_range_first = port_first;
        cs.ipv6_tcp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
		//
        port_first = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_first");
        port_last = cfg_getint(cfg_ipv6, "ipv6_udp_port_range_last");
        sprintf(which, "UDP");
		if ( validate_ports_range(port_first, port_last) == EXIT_FAILURE )
        {
            printf("Error: Invalid %s ports range.\n", which);
            exit_error_conf(cfg);
        }
        cs.ipv6_udp_port_range_first = port_first;
        cs.ipv6_udp_port_range_last = port_last;
		printf("\t%s pool port range: %d-%d\n", which, port_first, port_last);
        
		printf ("\n" );
    }

	cfg_free(cfg);

    /* We got the configuration structure, now send it to the module
     * using netlink sockets. */

    // Reserve memory for netlink socket
    nls = nl_socket_alloc();
    if (!nls) {
        printf("bad nl_socket_alloc\n");
        return EXIT_FAILURE;
    }

	// Bind and connect the socket to kernel
    ret = nl_connect(nls, NETLINK_USERSOCK);
    if (ret < 0) {
        nl_perror(ret, "nl_connect");
        nl_socket_free(nls);
        return EXIT_FAILURE;
    }

	// Send socket to module
    ret = nl_send_simple(nls, MSG_TYPE_CONF, 0, &(cs), sizeof(cs));
    if (ret < 0) {
        nl_perror(ret, "nl_send_simple");
        printf("Error sending message, is module loaded?\n");
        nl_close(nls);
        nl_socket_free(nls);
        return EXIT_FAILURE;
    } else {        
	    printf("Message sent (%d bytes):\n", ret);
        //print_nat64_run_conf(nrc);
    }
		
    nl_close(nls);
    nl_socket_free(nls);
    
    exit(EXIT_SUCCESS);
}