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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
static inline void __nl_perror(int error, const char *s) { nl_perror(s); }
/** * 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); }