static void add_routes_section (CEPageIP4 *page) { GtkWidget *widget; GtkWidget *frame; GtkWidget *list; gint i; widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section")); frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (widget), frame); page->routes_list = list = gtk_list_box_new (); gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); gtk_container_add (GTK_CONTAINER (frame), list); page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch")); gtk_switch_set_active (page->auto_routes, !nm_setting_ip4_config_get_ignore_auto_routes (page->setting)); g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page); add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row)); for (i = 0; i < nm_setting_ip4_config_get_num_routes (page->setting); i++) { NMIP4Route *route; struct in_addr tmp_addr; gchar address[INET_ADDRSTRLEN + 1]; gchar netmask[INET_ADDRSTRLEN + 1]; gchar gateway[INET_ADDRSTRLEN + 1]; gint metric; route = nm_setting_ip4_config_get_route (page->setting, i); if (!route) continue; tmp_addr.s_addr = nm_ip4_route_get_dest (route); (void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address)); tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route)); (void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask)); tmp_addr.s_addr = nm_ip4_route_get_next_hop (route); (void) inet_ntop (AF_INET, &tmp_addr, &gateway[0], sizeof (gateway)); metric = nm_ip4_route_get_metric (route); add_route_row (page, address, netmask, gateway, metric); } if (nm_setting_ip4_config_get_num_routes (page->setting) == 0) add_empty_route_row (page); gtk_widget_show_all (widget); }
static void test_everything_via_vpn (NMVpnPluginUiInterface *plugin, const char *dir) { NMConnection *connection; NMSettingConnection *s_con; NMSettingIP4Config *s_ip4; GError *error = NULL; char *pcf; const char *expected_id = "All your traffic are belong to VPN"; pcf = g_build_path ("/", dir, "everything-via-vpn.pcf", NULL); ASSERT (pcf != NULL, "everything-via-vpn", "failed to create pcf path"); connection = nm_vpn_plugin_ui_interface_import (plugin, pcf, &error); if (error) FAIL ("everything-via-vpn", "error importing %s: %s", pcf, error->message); ASSERT (connection != NULL, "everything-via-vpn", "error importing %s: (unknown)", pcf); /* Connection setting */ s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "everything-via-vpn", "missing 'connection' setting"); ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0, "everything-via-vpn", "unexpected connection ID"); /* IP4 setting */ s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "everything-via-vpn", "missing 'ip4-config' setting"); ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE, "everything-via-vpn", "never-default unexpectedly FALSE"); ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 0, "everything-via-vpn", "unexpected number of routes"); g_free (pcf); }
static void test_basic_import (NMVpnPluginUiInterface *plugin, const char *dir) { NMConnection *connection; NMSettingConnection *s_con; NMSettingIP4Config *s_ip4; NMSettingVPN *s_vpn; NMIP4Route *route; struct in_addr tmp; const char *expected_id = "Basic VPN"; const char *expected_route1_dest = "10.0.0.0"; const char *expected_route1_gw = "0.0.0.0"; const char *expected_route2_dest = "172.16.0.0"; const char *expected_route2_gw = "0.0.0.0"; connection = get_basic_connection ("basic-import", plugin, dir, "basic.pcf"); ASSERT (connection != NULL, "basic-import", "failed to import connection"); /* Connection setting */ s_con = nm_connection_get_setting_connection (connection); ASSERT (s_con != NULL, "basic-import", "missing 'connection' setting"); ASSERT (strcmp (nm_setting_connection_get_id (s_con), expected_id) == 0, "basic-import", "unexpected connection ID"); ASSERT (nm_setting_connection_get_uuid (s_con) == NULL, "basic-import", "unexpected valid UUID"); /* IP4 setting */ s_ip4 = nm_connection_get_setting_ip4_config (connection); ASSERT (s_ip4 != NULL, "basic-import", "missing 'ip4-config' setting"); ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 0, "basic-import", "unexpected addresses"); ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE, "basic-import", "never-default unexpectedly FALSE"); ASSERT (nm_setting_ip4_config_get_method (s_ip4) == NULL, "basic-import", "unexpected IPv4 method"); ASSERT (nm_setting_ip4_config_get_dhcp_client_id (s_ip4) == NULL, "basic-import", "unexpected valid DHCP client ID"); ASSERT (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL, "basic-import", "unexpected valid DHCP hostname"); ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 0, "basic-import", "unexpected DNS searches"); ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 0, "basic-import", "unexpected DNS servers"); ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 2, "basic-import", "unexpected number of routes"); /* Route #1 */ route = nm_setting_ip4_config_get_route (s_ip4, 0); ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0, "basic-import", "couldn't convert expected route destination #1"); ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr, "basic-import", "unexpected route #1 destination"); ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0, "basic-import", "couldn't convert expected route next hop #1"); ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr, "basic-import", "unexpected route #1 next hop"); ASSERT (nm_ip4_route_get_prefix (route) == 8, "basic-import", "unexpected route #1 prefix"); ASSERT (nm_ip4_route_get_metric (route) == 0, "basic-import", "unexpected route #1 metric"); /* Route #2 */ route = nm_setting_ip4_config_get_route (s_ip4, 1); ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0, "basic-import", "couldn't convert expected route destination #2"); ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr, "basic-import", "unexpected route #2 destination"); ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0, "basic-import", "couldn't convert expected route next hop #2"); ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr, "basic-import", "unexpected route #2 next hop"); ASSERT (nm_ip4_route_get_prefix (route) == 16, "basic-import", "unexpected route #2 prefix"); ASSERT (nm_ip4_route_get_metric (route) == 0, "basic-import", "unexpected route #2 metric"); /* VPN setting */ s_vpn = nm_connection_get_setting_vpn (connection); ASSERT (s_vpn != NULL, "basic-import", "missing 'vpn' setting"); /* Data items */ test_items ("basic-import-data", s_vpn, &basic_items[0], FALSE); /* Secrets */ test_items ("basic-import-secrets", s_vpn, &basic_secrets[0], TRUE); g_object_unref (connection); }
void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) { int i, j; gboolean setting_never_default; if (!setting) return; /* Defaults are just fine */ if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) { nm_ip4_config_reset_nameservers (ip4_config); nm_ip4_config_reset_domains (ip4_config); nm_ip4_config_reset_searches (ip4_config); } if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) nm_ip4_config_reset_routes (ip4_config); for (i = 0; i < nm_setting_ip4_config_get_num_dns (setting); i++) { guint32 ns; gboolean found = FALSE; /* Avoid dupes */ ns = nm_setting_ip4_config_get_dns (setting, i); for (j = 0; j < nm_ip4_config_get_num_nameservers (ip4_config); j++) { if (nm_ip4_config_get_nameserver (ip4_config, j) == ns) { found = TRUE; break; } } if (!found) nm_ip4_config_add_nameserver (ip4_config, ns); } /* DNS search domains */ for (i = 0; i < nm_setting_ip4_config_get_num_dns_searches (setting); i++) { const char *search = nm_setting_ip4_config_get_dns_search (setting, i); gboolean found = FALSE; /* Avoid dupes */ for (j = 0; j < nm_ip4_config_get_num_searches (ip4_config); j++) { if (!strcmp (search, nm_ip4_config_get_search (ip4_config, j))) { found = TRUE; break; } } if (!found) nm_ip4_config_add_search (ip4_config, search); } /* IPv4 addresses */ for (i = 0; i < nm_setting_ip4_config_get_num_addresses (setting); i++) { NMIP4Address *setting_addr = nm_setting_ip4_config_get_address (setting, i); guint32 num; num = nm_ip4_config_get_num_addresses (ip4_config); for (j = 0; j < num; j++) { NMIP4Address *cfg_addr = nm_ip4_config_get_address (ip4_config, j); /* Dupe, override with user-specified address */ if (nm_ip4_address_get_address (cfg_addr) == nm_ip4_address_get_address (setting_addr)) { nm_ip4_config_replace_address (ip4_config, j, setting_addr); break; } } if (j == num) nm_ip4_config_add_address (ip4_config, setting_addr); } /* IPv4 routes */ for (i = 0; i < nm_setting_ip4_config_get_num_routes (setting); i++) { NMIP4Route *setting_route = nm_setting_ip4_config_get_route (setting, i); guint32 num; num = nm_ip4_config_get_num_routes (ip4_config); for (j = 0; j < num; j++) { NMIP4Route *cfg_route = nm_ip4_config_get_route (ip4_config, j); /* Dupe, override with user-specified route */ if ( (nm_ip4_route_get_dest (cfg_route) == nm_ip4_route_get_dest (setting_route)) && (nm_ip4_route_get_prefix (cfg_route) == nm_ip4_route_get_prefix (setting_route)) && (nm_ip4_route_get_next_hop (cfg_route) == nm_ip4_route_get_next_hop (setting_route))) { nm_ip4_config_replace_route (ip4_config, j, setting_route); break; } } if (j == num) nm_ip4_config_add_route (ip4_config, setting_route); } setting_never_default = nm_setting_ip4_config_get_never_default (setting); if (nm_setting_ip4_config_get_ignore_auto_routes (setting)) nm_ip4_config_set_never_default (ip4_config, setting_never_default); else { if (setting_never_default) nm_ip4_config_set_never_default (ip4_config, TRUE); } }
GtkWidget * ip4_routes_dialog_new (NMSettingIP4Config *s_ip4, gboolean automatic) { GtkBuilder *builder; GtkWidget *dialog, *widget, *ok_button; GtkListStore *store; GtkTreeIter model_iter; GtkTreeSelection *selection; gint offset; GtkTreeViewColumn *column; GtkCellRenderer *renderer; int i; GSList *renderers = NULL; GError* error = NULL; /* Initialize temporary storage vars */ g_free (last_edited); last_edited = NULL; last_path = NULL; g_free (last_path); last_column = -1; builder = gtk_builder_new (); if (!gtk_builder_add_from_file (builder, UIDIR "/ce-ip4-routes.ui", &error)) { g_warning ("Couldn't load builder file: %s", error->message); g_error_free (error); return NULL; } dialog = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_routes_dialog")); if (!dialog) { g_warning ("%s: Couldn't load ip4 routes dialog from .ui file.", __func__); g_object_unref (builder); return NULL; } gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); g_object_set_data_full (G_OBJECT (dialog), "builder", builder, (GDestroyNotify) g_object_unref); ok_button = GTK_WIDGET (gtk_builder_get_object (builder, "ok_button")); store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* Add existing routes */ for (i = 0; i < nm_setting_ip4_config_get_num_routes (s_ip4); i++) { NMIP4Route *route = nm_setting_ip4_config_get_route (s_ip4, i); struct in_addr tmp_addr; char ip_string[INET_ADDRSTRLEN]; char *tmp; if (!route) { g_warning ("%s: empty IP4 route structure!", __func__); continue; } gtk_list_store_append (store, &model_iter); tmp_addr.s_addr = nm_ip4_route_get_dest (route);; if (inet_ntop (AF_INET, &tmp_addr, &ip_string[0], sizeof (ip_string))) gtk_list_store_set (store, &model_iter, COL_ADDRESS, ip_string, -1); tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route)); if (inet_ntop (AF_INET, &tmp_addr, &ip_string[0], sizeof (ip_string))) gtk_list_store_set (store, &model_iter, COL_PREFIX, ip_string, -1); tmp_addr.s_addr = nm_ip4_route_get_next_hop (route); if (tmp_addr.s_addr && inet_ntop (AF_INET, &tmp_addr, &ip_string[0], sizeof (ip_string))) gtk_list_store_set (store, &model_iter, COL_NEXT_HOP, ip_string, -1); if (nm_ip4_route_get_metric (route)) { tmp = g_strdup_printf ("%d", nm_ip4_route_get_metric (route)); gtk_list_store_set (store, &model_iter, COL_METRIC, tmp, -1); g_free (tmp); } } widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_routes")); gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store)); g_object_unref (store); /* IP Address column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_ADDRESS)); g_signal_connect (renderer, "editing-started", G_CALLBACK (ip4_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Address"), renderer, "text", COL_ADDRESS, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Prefix column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_PREFIX)); g_signal_connect (renderer, "editing-started", G_CALLBACK (ip4_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Netmask"), renderer, "text", COL_PREFIX, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Gateway column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_NEXT_HOP)); g_signal_connect (renderer, "editing-started", G_CALLBACK (ip4_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Gateway"), renderer, "text", COL_NEXT_HOP, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); /* Metric column */ renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "editable", TRUE, NULL); g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), builder); g_object_set_data (G_OBJECT (renderer), "column", GUINT_TO_POINTER (COL_METRIC)); g_signal_connect (renderer, "editing-started", G_CALLBACK (uint_cell_editing_started), ok_button); g_signal_connect (renderer, "editing-canceled", G_CALLBACK (cell_editing_canceled), builder); renderers = g_slist_append (renderers, renderer); offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (widget), -1, _("Metric"), renderer, "text", COL_METRIC, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), offset - 1); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE); g_object_set_data_full (G_OBJECT (dialog), "renderers", renderers, (GDestroyNotify) g_slist_free); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); g_signal_connect (selection, "changed", G_CALLBACK (list_selection_changed), GTK_WIDGET (gtk_builder_get_object (builder, "ip4_route_delete_button"))); g_signal_connect (widget, "button-press-event", G_CALLBACK (tree_view_button_pressed_cb), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_route_add_button")); gtk_widget_set_sensitive (widget, TRUE); g_signal_connect (widget, "clicked", G_CALLBACK (route_add_clicked), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_route_delete_button")); gtk_widget_set_sensitive (widget, FALSE); g_signal_connect (widget, "clicked", G_CALLBACK (route_delete_clicked), builder); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_ignore_auto_routes")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_ip4_config_get_ignore_auto_routes (s_ip4)); gtk_widget_set_sensitive (widget, automatic); widget = GTK_WIDGET (gtk_builder_get_object (builder, "ip4_never_default")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), nm_setting_ip4_config_get_never_default (s_ip4)); /* Update initial validity */ validate (dialog); return dialog; }