1591 lines
65 KiB
C
1591 lines
65 KiB
C
/*
|
|
* ni-window-interface.c
|
|
* This file is part of NetworkInador
|
|
*
|
|
* Copyright (C) 2021 - Gatuno
|
|
*
|
|
* NetworkInador is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* NetworkInador is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with NetworkInador; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <linux/if_addr.h>
|
|
#include <linux/if.h>
|
|
|
|
#include "ni-window-interface.h"
|
|
|
|
#include "ni-client.h"
|
|
#include "ni-interface.h"
|
|
#include "ni-ip.h"
|
|
#include "ni-add-ip-dialog.h"
|
|
#include "../src/link-types.h"
|
|
#include "ni-interface-chooser-dialog.h"
|
|
#include "ni-interface-filter.h"
|
|
|
|
struct _NIWindowInterfacePrivate {
|
|
NIInterface *ni_interface;
|
|
|
|
GtkWidget *vbox, *notebook;
|
|
GtkWidget *vbox_ipv4, *vbox_ipv6, *vbox_info, *vbox_bridges, *vbox_dhcpv4;
|
|
GtkWidget *info_name, *info_updown, *info_mtu, *info_slave;
|
|
GtkWidget *button_name_apply, *button_name_revert;
|
|
GtkWidget *button_mtu_apply, *button_mtu_revert;
|
|
GtkWidget *button_up, *button_down;
|
|
GtkWidget *button_slave_remove, *button_master_add;
|
|
GtkListStore *ipv4_store, *ipv6_store, *bridge_ports_store;
|
|
GtkWidget *del_ipv4_button, *del_ipv6_button, *del_bport_button;
|
|
GtkWidget *tree_ipv4, *tree_ipv6, *tree_bridge_ports;
|
|
|
|
GtkWidget *button_dhcp_run, *button_dhcp_stop;
|
|
GtkWidget *vbox_dhcpv4_info;
|
|
GtkWidget *check_flag_autorestart, *check_flag_no_dns, *check_flag_no_gws, *check_flag_no_ip;
|
|
GtkWidget *dhcpv4_process, *dhcpv4_status;
|
|
GtkWidget *dhcpv4_ip_label, *dhcpv4_gateway_label;
|
|
GtkWidget *dhcpv4_bcast_label, *dhcpv4_dns_label, *dhcpv4_server_label;
|
|
GtkWidget *dhcpv4_time_label, *dhcpv4_domain_label;
|
|
GtkWidget *menu_dhcpv4;
|
|
int dhcp_type;
|
|
};
|
|
|
|
enum {
|
|
PROP_NI_INTERFACE = 1,
|
|
|
|
N_PROPERTIES
|
|
};
|
|
|
|
enum {
|
|
IP_STORE_COL_MAIN_IP,
|
|
IP_STORE_COL_BROADCAST,
|
|
IP_STORE_COL_OBJECT,
|
|
|
|
NUM_IP_STORE_COLS
|
|
};
|
|
|
|
enum {
|
|
BRIDGE_PORT_STORE_COL_IFACE_NAME,
|
|
BRIDGE_PORT_STORE_COL_OBJECT,
|
|
|
|
NUM_BRIDGE_PORT_STORE_COLS
|
|
};
|
|
|
|
static void ni_window_interface_addr_added_cb (NIWindowInterface *window_iface, NIIP *ni_ip);
|
|
void ni_window_interface_update_state_from_flags (NIWindowInterface *window_iface);
|
|
void ni_window_interface_update_state_from_master (NIWindowInterface *window_iface);
|
|
static void ni_window_interface_name_cancel_cb (GtkWidget *widget, gpointer data);
|
|
static void ni_window_interface_mtu_cancel_cb (GtkWidget *widget, gpointer data);
|
|
static void prepare_bridge_tab (NIWindowInterface *window_iface);
|
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (NIWindowInterface, ni_window_interface, GTK_TYPE_WINDOW)
|
|
|
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
|
|
|
#if 0
|
|
static GObject *ni_interface_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) {
|
|
GObject *obj;
|
|
GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek (GTK_TYPE_WINDOW));
|
|
NIInterface *ni_interface;
|
|
|
|
obj = parent_class->constructor (type, n_construct_properties, construct_properties);
|
|
|
|
ni_interface = NI_INTERFACE (obj);
|
|
{
|
|
int g;
|
|
for (g = 0; g < n_construct_properties; g++) {
|
|
GParamSpec *pspec = construct_properties[g].pspec;
|
|
GValue *value = construct_properties[g].value;
|
|
|
|
/* Manejar el valor */
|
|
if (strcmp (g_param_spec_get_name (pspec), "index") == 0) {
|
|
printf ("Estableciendo sobre el constructor, el index\n");
|
|
ni_interface->priv->index = g_value_get_uint (value);
|
|
|
|
ni_interface_check_and_connect_signal (ni_interface);
|
|
} else if (strcmp (g_param_spec_get_name (pspec), "ni-client") == 0) {
|
|
ni_interface->priv->ni_client = NI_CLIENT (g_value_get_object (value));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return obj;
|
|
}
|
|
#endif
|
|
|
|
static gboolean ni_window_interface_delete_event (GtkWidget *widget, GdkEventAny *event) {
|
|
/* Restaurar la caja original del nombre de la interfaz, si está cambiada */
|
|
ni_window_interface_name_cancel_cb (NULL, widget);
|
|
ni_window_interface_mtu_cancel_cb (NULL, widget);
|
|
|
|
return gtk_widget_hide_on_delete (widget);
|
|
}
|
|
|
|
static void has_ip_selected_v4_cb (GtkTreeSelection *selection, gpointer user_data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) user_data;
|
|
|
|
if (gtk_tree_selection_count_selected_rows (selection) > 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_ipv4_button, TRUE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_ipv4_button, FALSE);
|
|
}
|
|
}
|
|
|
|
static void has_ip_selected_v6_cb (GtkTreeSelection *selection, gpointer user_data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) user_data;
|
|
|
|
if (gtk_tree_selection_count_selected_rows (selection) > 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_ipv6_button, TRUE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_ipv6_button, FALSE);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_addr_button_add_cb (GtkWidget *widget, int family, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
GtkWidget *dialog;
|
|
gint response;
|
|
NIClient *ni_client;
|
|
struct_addr addr, p2p_addr;
|
|
int prefix;
|
|
gboolean has_p2p;
|
|
uint32_t flags = 0;
|
|
|
|
dialog = ni_add_ip_dialog_new (family);
|
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window_iface));
|
|
|
|
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
|
|
|
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
if (response == GTK_RESPONSE_OK) {
|
|
/* Mandar la ip al network-inador */
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
|
|
ni_add_ip_dialog_get_address (NI_ADD_IP_DIALOG (dialog), &addr, &prefix);
|
|
has_p2p = ni_add_ip_dialog_has_p2p_address (NI_ADD_IP_DIALOG (dialog));
|
|
if (has_p2p) {
|
|
memcpy (&p2p_addr, &addr, sizeof (p2p_addr));
|
|
ni_add_ip_dialog_get_p2p_address (NI_ADD_IP_DIALOG (dialog), &addr);
|
|
}
|
|
|
|
flags |= IFA_F_PERMANENT;
|
|
if (ni_add_ip_dialog_get_noprefix (NI_ADD_IP_DIALOG (dialog))) {
|
|
flags |= IFA_F_NOPREFIXROUTE;
|
|
}
|
|
//void ni_client_ask_ip_new (NIClient *ni_client, NIInterface *ni_interface, int family, int prefix, struct_addr *addr, uint32_t flags, unsigned char scope, int has_local, struct_addr *local_addr, int has_brd, struct_addr *brd_addr) {
|
|
|
|
/* TODO: Pedir los tiempos de validez de la interfaz */
|
|
guint32 cacheinfo[2];
|
|
cacheinfo[0] = 0xFFFFFFFFU;
|
|
cacheinfo[1] = 0xFFFFFFFFU;
|
|
ni_client_ask_ip_new (ni_client, window_iface->priv->ni_interface, family, prefix, &addr, flags, 0, has_p2p, (has_p2p ? &p2p_addr : NULL), FALSE, NULL, cacheinfo);
|
|
}
|
|
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
static void ni_window_interface_addr_button_del_cb (GtkWidget *widget, int family, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkTreeSelection *selection;
|
|
NIIP *ni_ip;
|
|
|
|
if (family == AF_INET) {
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window_iface->priv->tree_ipv4));
|
|
} else if (family == AF_INET6) {
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window_iface->priv->tree_ipv6));
|
|
}
|
|
|
|
gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
|
|
gtk_tree_model_get (model, &iter, IP_STORE_COL_OBJECT, &ni_ip, -1);
|
|
|
|
ni_client_ask_ip_delete (ni_interface_get_client (window_iface->priv->ni_interface), window_iface->priv->ni_interface, ni_ip);
|
|
}
|
|
|
|
static void ni_window_interface_addr_v4_button_add_cb (GtkWidget *widget, gpointer data) {
|
|
ni_window_interface_addr_button_add_cb (widget, AF_INET, data);
|
|
}
|
|
|
|
static void ni_window_interface_addr_v6_button_add_cb (GtkWidget *widget, gpointer data) {
|
|
ni_window_interface_addr_button_add_cb (widget, AF_INET6, data);
|
|
}
|
|
|
|
static void has_bport_selected_cb (GtkTreeSelection *selection, gpointer user_data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) user_data;
|
|
|
|
if (gtk_tree_selection_count_selected_rows (selection) > 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_bport_button, TRUE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->del_bport_button, FALSE);
|
|
}
|
|
}
|
|
|
|
static gboolean ni_window_interface_filter_only_master_zero (const NIInterfaceFilterInfo *filter_info, gpointer data) {
|
|
return (filter_info->master == 0);
|
|
}
|
|
|
|
static void ni_window_interface_bport_button_add_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
NIInterfaceFilter *iface_filter;
|
|
int res;
|
|
NIInterface *slave_iface;
|
|
guint new_slave;
|
|
NIClient *ni_client;
|
|
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
GtkWidget *dialog = ni_interface_chooser_dialog_new (ni_client);
|
|
|
|
iface_filter = ni_interface_filter_new ();
|
|
/* Ella no puede ser su propio esclavo */
|
|
ni_interface_filter_add_index (iface_filter, ni_interface_get_index (window_iface->priv->ni_interface), TRUE);
|
|
|
|
/* Agregar un filtro especial que solo permita interfaces que tengan por master == 0 */
|
|
ni_interface_filter_add_custom (iface_filter, ni_window_interface_filter_only_master_zero, NULL, NULL);
|
|
|
|
ni_interface_chooser_dialog_set_filter (NI_INTERFACE_CHOOSER_DIALOG (dialog), iface_filter);
|
|
|
|
res = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
if (res == GTK_RESPONSE_OK) {
|
|
new_slave = ni_interface_chooser_dialog_get_index (NI_INTERFACE_CHOOSER_DIALOG (dialog));
|
|
|
|
slave_iface = ni_client_get_interface_by_index (ni_client, new_slave);
|
|
|
|
if (slave_iface != NULL) {
|
|
ni_client_ask_interface_set_master (ni_client, slave_iface, window_iface->priv->ni_interface);
|
|
}
|
|
}
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
static void ni_window_interface_bport_button_del_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
GtkTreeSelection *selection;
|
|
NIInterface *slave;
|
|
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window_iface->priv->tree_bridge_ports));
|
|
|
|
gtk_tree_selection_get_selected (selection, &model, &iter);
|
|
|
|
gtk_tree_model_get (model, &iter, BRIDGE_PORT_STORE_COL_OBJECT, &slave, -1);
|
|
|
|
ni_client_ask_interface_clear_master (ni_interface_get_client (window_iface->priv->ni_interface), slave);
|
|
}
|
|
|
|
static void ni_window_interface_addr_v4_button_del_cb (GtkWidget *widget, gpointer data) {
|
|
ni_window_interface_addr_button_del_cb (widget, AF_INET, data);
|
|
}
|
|
|
|
static void ni_window_interface_addr_v6_button_del_cb (GtkWidget *widget, gpointer data) {
|
|
ni_window_interface_addr_button_del_cb (widget, AF_INET6, data);
|
|
}
|
|
|
|
/* Función para renderizar el tiempo de la IP en el arbol */
|
|
void ni_window_interface_cell_renderer_timestamp (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) {
|
|
NIIP *ni_ip;
|
|
char buffer[256];
|
|
guint32 valid, prefered;
|
|
gint horas, minutos, segundos;
|
|
|
|
gtk_tree_model_get (tree_model, iter, IP_STORE_COL_OBJECT, &ni_ip, -1);
|
|
|
|
valid = ni_ip_get_ifa_valid (ni_ip);
|
|
prefered = ni_ip_get_ifa_prefered (ni_ip);
|
|
|
|
if (valid == 0xFFFFFFFFU) {
|
|
g_object_set (cell, "text", "Indefinida", NULL);
|
|
} else {
|
|
horas = valid / 3600;
|
|
segundos = valid - (horas * 3600);
|
|
minutos = segundos / 60;
|
|
segundos = segundos - (minutos * 60);
|
|
|
|
if (horas > 0) {
|
|
if (minutos > 0) {
|
|
snprintf (buffer, sizeof (buffer), "%i hora(s), %i minuto(s)", horas, minutos);
|
|
} else {
|
|
snprintf (buffer, sizeof (buffer), "%i hora(s)", horas);
|
|
}
|
|
} else if (minutos > 0) {
|
|
if (segundos > 0) {
|
|
snprintf (buffer, sizeof (buffer), "%i minuto(s), %i segundo(s)", minutos, segundos);
|
|
} else {
|
|
snprintf (buffer, sizeof (buffer), "%i minuto(s)", minutos);
|
|
}
|
|
} else {
|
|
snprintf (buffer, sizeof (buffer), "%i segundo(s)", segundos);
|
|
}
|
|
g_object_set (cell, "text", buffer, NULL);
|
|
}
|
|
}
|
|
|
|
/* Evento cuando cambian el nombre de la interfaz en el entry */
|
|
static void ni_window_interface_name_edit_cb (GtkEditable *editable, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
const gchar *original_name = ni_interface_get_name (window_iface->priv->ni_interface);
|
|
const gchar *current_name = gtk_entry_get_text (GTK_ENTRY (window_iface->priv->info_name));
|
|
|
|
if (current_name[0] == 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, TRUE);
|
|
} else if (strcmp (original_name, current_name) == 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, TRUE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, TRUE);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_name_cancel_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
gtk_entry_set_text (GTK_ENTRY (window_iface->priv->info_name), ni_interface_get_name (window_iface->priv->ni_interface));
|
|
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE);
|
|
}
|
|
|
|
static void ni_window_interface_name_apply_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
const gchar *new_name;
|
|
|
|
if (gtk_widget_get_sensitive (window_iface->priv->button_name_apply) == FALSE) {
|
|
return;
|
|
}
|
|
new_name = gtk_entry_get_text (GTK_ENTRY (window_iface->priv->info_name));
|
|
|
|
ni_interface_set_name (window_iface->priv->ni_interface, new_name);
|
|
|
|
/* TODO: Activar el ícono de "cargando" en el entry
|
|
gtk_entry_set_icon_from_gicon (GTK_ENTRY (window_iface->priv->info_name), GTK_ENTRY_ICON_SECONDARY, */
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE);
|
|
}
|
|
|
|
/* Eventos cuando cambian el mtu */
|
|
static void ni_window_interface_mtu_edit_cb (GtkSpinButton *spin, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
guint original_mtu = ni_interface_get_mtu (window_iface->priv->ni_interface);
|
|
guint new_mtu = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (window_iface->priv->info_mtu));
|
|
|
|
if (new_mtu == 0) {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, TRUE);
|
|
} else if (new_mtu == original_mtu) {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, TRUE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, TRUE);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_mtu_cancel_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window_iface->priv->info_mtu), ni_interface_get_mtu (window_iface->priv->ni_interface));
|
|
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE);
|
|
}
|
|
|
|
static void ni_window_interface_mtu_apply_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
guint new_mtu;
|
|
|
|
if (gtk_widget_get_sensitive (window_iface->priv->button_mtu_apply) == FALSE) {
|
|
return;
|
|
}
|
|
new_mtu = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (window_iface->priv->info_mtu));
|
|
|
|
ni_interface_set_mtu (window_iface->priv->ni_interface, new_mtu);
|
|
|
|
/* TODO: Activar el ícono de "cargando" en el entry
|
|
gtk_entry_set_icon_from_gicon (GTK_ENTRY (window_iface->priv->info_name), GTK_ENTRY_ICON_SECONDARY, */
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_mtu_revert, FALSE);
|
|
}
|
|
|
|
|
|
static void ni_window_interface_down_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
|
|
ni_interface_set_down (window_iface->priv->ni_interface);
|
|
}
|
|
|
|
static void ni_window_interface_up_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
|
|
ni_interface_set_up (window_iface->priv->ni_interface);
|
|
}
|
|
|
|
static void ni_window_interface_make_slave_click_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
NIInterfaceFilter *iface_filter;
|
|
int res;
|
|
NIInterface *master_iface;
|
|
guint new_master;
|
|
NIClient *ni_client;
|
|
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
GtkWidget *dialog = ni_interface_chooser_dialog_new (ni_client);
|
|
|
|
iface_filter = ni_interface_filter_new ();
|
|
/* Ella no puede ser su propia master */
|
|
ni_interface_filter_add_index (iface_filter, ni_interface_get_index (window_iface->priv->ni_interface), TRUE);
|
|
|
|
/* TODO: ¿Solo los bridges pueden ser maestros? */
|
|
ni_interface_filter_add_type (iface_filter, NI_LINK_TYPE_BRIDGE, FALSE);
|
|
|
|
ni_interface_chooser_dialog_set_filter (NI_INTERFACE_CHOOSER_DIALOG (dialog), iface_filter);
|
|
|
|
res = gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
if (res == GTK_RESPONSE_OK) {
|
|
new_master = ni_interface_chooser_dialog_get_index (NI_INTERFACE_CHOOSER_DIALOG (dialog));
|
|
|
|
master_iface = ni_client_get_interface_by_index (ni_client, new_master);
|
|
|
|
if (master_iface != NULL) {
|
|
ni_client_ask_interface_set_master (ni_client, window_iface->priv->ni_interface, master_iface);
|
|
}
|
|
}
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
static void ni_window_interface_clear_slave_click_cb (GtkWidget *widget, gpointer data) {
|
|
NIWindowInterface *window_iface = (NIWindowInterface *) data;
|
|
NIClient *ni_client;
|
|
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
|
|
ni_client_ask_interface_clear_master (ni_client, window_iface->priv->ni_interface);
|
|
}
|
|
|
|
/* Eventos que vienen del network-inador */
|
|
static void ni_window_interface_addr_added_cb (NIWindowInterface *window_iface, NIIP *ni_ip) {
|
|
char buffer[256], ip[128], local[128];
|
|
guint prefix, family, family_size;
|
|
|
|
family = ni_ip_get_family (ni_ip);
|
|
inet_ntop (family, ni_ip_get_addr (ni_ip), ip, sizeof (ip));
|
|
prefix = ni_ip_get_prefix (ni_ip);
|
|
|
|
if (family == AF_INET) {
|
|
family_size = sizeof (struct in_addr);
|
|
} else if (family == AF_INET6) {
|
|
family_size = sizeof (struct in6_addr);
|
|
}
|
|
|
|
if (ni_ip_has_local (ni_ip) &&
|
|
memcmp (ni_ip_get_local_addr (ni_ip), ni_ip_get_addr (ni_ip), family_size) != 0) {
|
|
inet_ntop (family, ni_ip_get_local_addr (ni_ip), local, sizeof (local));
|
|
|
|
snprintf (buffer, sizeof (buffer), "%s peer %s/%u", local, ip, prefix);
|
|
} else {
|
|
snprintf (buffer, sizeof (buffer), "%s/%u", ip, prefix);
|
|
}
|
|
|
|
if (family == AF_INET) {
|
|
gtk_list_store_insert_with_values (window_iface->priv->ipv4_store, NULL, -1, IP_STORE_COL_MAIN_IP, buffer, IP_STORE_COL_OBJECT, ni_ip, -1);
|
|
} else if (family == AF_INET6) {
|
|
gtk_list_store_insert_with_values (window_iface->priv->ipv6_store, NULL, -1, IP_STORE_COL_MAIN_IP, buffer, IP_STORE_COL_OBJECT, ni_ip, -1);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_new_ip_cb (NIInterface *ni_interface, NIIP *ni_ip, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
ni_window_interface_addr_added_cb (window_iface, ni_ip);
|
|
}
|
|
|
|
static void ni_window_interface_delete_ip_cb (NIInterface *ni_interface, NIIP *ni_ip, gpointer data) {
|
|
GtkTreeIter iter;
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
gboolean has;
|
|
guint family;
|
|
GtkListStore *p;
|
|
void *iter_obj;
|
|
|
|
family = ni_ip_get_family (ni_ip);
|
|
|
|
if (family == AF_INET) {
|
|
p = window_iface->priv->ipv4_store;
|
|
} else if (family == AF_INET6) {
|
|
p = window_iface->priv->ipv6_store;
|
|
}
|
|
|
|
has = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (p), &iter);
|
|
while (has) {
|
|
gtk_tree_model_get (GTK_TREE_MODEL (p), &iter, IP_STORE_COL_OBJECT, &iter_obj, -1);
|
|
|
|
if (iter_obj == ni_ip) {
|
|
/* Eliminar este objeto */
|
|
gtk_list_store_remove (p, &iter);
|
|
return;
|
|
}
|
|
has = gtk_tree_model_iter_next (GTK_TREE_MODEL (p), &iter);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_changed_name_cb (GObject *object, GParamSpec *sp, gpointer data) {
|
|
NIInterface *ni_interface = NI_INTERFACE (object);
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
gchar *name;
|
|
|
|
/* Cambiar el título */
|
|
name = g_strdup_printf ("Interfaz %s", ni_interface_get_name (window_iface->priv->ni_interface));
|
|
gtk_window_set_title (GTK_WINDOW (window_iface), name);
|
|
|
|
/* Cambiar la label que corresponde al nombre */
|
|
gtk_entry_set_text (GTK_ENTRY (window_iface->priv->info_name), ni_interface_get_name (window_iface->priv->ni_interface));
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE);
|
|
|
|
g_free (name);
|
|
}
|
|
|
|
static void ni_window_interface_changed_flags_cb (GObject *object, GParamSpec *sp, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
ni_window_interface_update_state_from_flags (window_iface);
|
|
}
|
|
|
|
static void ni_window_interface_changed_master_cb (GObject *object, GParamSpec *sp, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
ni_window_interface_update_state_from_master (window_iface);
|
|
}
|
|
|
|
static void ni_window_interface_update_dhcp_status (NIWindowInterface *window_iface, NIInterface *ni_interface) {
|
|
guint type, status, prefix, lease_time;
|
|
char buffer[2048];
|
|
char buffer_ip[256];
|
|
const struct_addr *addr;
|
|
gint pos = 0, c, g;
|
|
const char *domain_name;
|
|
|
|
type = ni_interface_get_dhcp_type (ni_interface);
|
|
|
|
if (type == 0) {
|
|
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Ninguno");
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "No hay proceso corriendo");
|
|
} else {
|
|
if (type == 1) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Cliente DHCP ISC");
|
|
} else if (type == 2) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_process), "Cliente Busybox UDHCPC");
|
|
}
|
|
|
|
status = ni_interface_get_dhcp_status (ni_interface);
|
|
if (status == 5) {
|
|
/* El proceso murió */
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Proceso muerto");
|
|
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
|
|
return;
|
|
} else if (status == 0 || status == 4) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Buscando...");
|
|
gtk_widget_hide (window_iface->priv->vbox_dhcpv4_info);
|
|
return;
|
|
} else if (status == 1 || status == 2) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Concesión obtenida");
|
|
} else if (status == 3) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_status), "Concesión expirada");
|
|
}
|
|
|
|
addr = ni_interface_get_dhcp_addr (ni_interface);
|
|
prefix = ni_interface_get_dhcp_prefix (ni_interface);
|
|
|
|
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
|
|
g_snprintf (buffer, sizeof (buffer), "%s/%i", buffer_ip, prefix);
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_ip_label), buffer);
|
|
|
|
c = ni_interface_get_dhcp_gw_count (ni_interface);
|
|
addr = ni_interface_get_dhcp_gw_addr (ni_interface);
|
|
|
|
if (c == 0) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_gateway_label), "");
|
|
} else {
|
|
pos = 0;
|
|
for (g = 0; g < c; g++) {
|
|
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
|
|
|
|
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s", buffer_ip);
|
|
if (g != c - 1) {
|
|
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, ", ");
|
|
}
|
|
}
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_gateway_label), buffer);
|
|
}
|
|
|
|
if (ni_interface_has_dhcp_brd_addr (ni_interface)) {
|
|
addr = ni_interface_get_dhcp_brd_addr (ni_interface);
|
|
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
|
|
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_bcast_label), buffer_ip);
|
|
} else {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_bcast_label), "");
|
|
}
|
|
|
|
c = ni_interface_get_dhcp_dns_count (ni_interface);
|
|
addr = ni_interface_get_dhcp_dns_addr (ni_interface);
|
|
|
|
if (c == 0) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_dns_label), "");
|
|
} else {
|
|
pos = 0;
|
|
for (g = 0; g < c; g++) {
|
|
inet_ntop (AF_INET, &addr[g], buffer_ip, sizeof (buffer_ip));
|
|
|
|
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, "%s", buffer_ip);
|
|
if (g != c - 1) {
|
|
pos += g_snprintf (&buffer[pos], sizeof (buffer) - pos, ", ");
|
|
}
|
|
}
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_dns_label), buffer);
|
|
}
|
|
|
|
if (ni_interface_has_dhcp_server_addr (ni_interface)) {
|
|
addr = ni_interface_get_dhcp_server_addr (ni_interface);
|
|
inet_ntop (AF_INET, addr, buffer_ip, sizeof (buffer_ip));
|
|
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_server_label), buffer_ip);
|
|
} else {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_server_label), "");
|
|
}
|
|
|
|
lease_time = ni_interface_get_dhcp_lease_time (ni_interface);
|
|
|
|
if (lease_time != 0) {
|
|
g_snprintf (buffer, sizeof (buffer), "%i seg(s)", lease_time);
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_time_label), buffer);
|
|
} else {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_time_label), "");
|
|
}
|
|
|
|
domain_name = ni_interface_get_dhcp_domain_name (ni_interface);
|
|
if (domain_name != NULL) {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_domain_label), domain_name);
|
|
} else {
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->dhcpv4_domain_label), "");
|
|
}
|
|
|
|
gtk_widget_show (window_iface->priv->vbox_dhcpv4_info);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_dhcp_type_changed_cb (NIInterface *ni_interface, guint old_type, guint new_type, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
/* Obtuvimos cambio en el estado del DHCP, actualizar los botones y ejecutar la información de estado */
|
|
if (new_type == 0) {
|
|
/* El dhcp está muerto */
|
|
gtk_widget_set_sensitive (window_iface->priv->button_dhcp_run, TRUE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_dhcp_stop, FALSE);
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->button_dhcp_run, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_dhcp_stop, TRUE);
|
|
}
|
|
|
|
ni_window_interface_update_dhcp_status (window_iface, ni_interface);
|
|
}
|
|
|
|
static void ni_window_interface_dhcp_status_updated_cb (NIInterface *ni_interface, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
ni_window_interface_update_dhcp_status (window_iface, ni_interface);
|
|
}
|
|
|
|
/* Eventos de bridges */
|
|
static gboolean ni_window_interface_check_bport_to_delete_foreach_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
|
|
static void ni_window_interface_removed_from_bridge_cb (NIInterface *ni_interface, guint old_master, gpointer data);
|
|
|
|
static void ni_window_interface_added_to_bridge_cb (NIInterface *ni_interface, guint new_master, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
guint our_index;
|
|
|
|
our_index = ni_interface_get_index (window_iface->priv->ni_interface);
|
|
if (new_master == our_index) {
|
|
/* Esta interfaz acaba de ser esclavizada a nuestra interfaz */
|
|
gtk_list_store_insert_with_values (window_iface->priv->bridge_ports_store, NULL, -1, BRIDGE_PORT_STORE_COL_IFACE_NAME, ni_interface_get_name (ni_interface), BRIDGE_PORT_STORE_COL_OBJECT, ni_interface, -1);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_removed_from_bridge_cb (NIInterface *ni_interface, guint old_master, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
guint our_index;
|
|
|
|
our_index = ni_interface_get_index (window_iface->priv->ni_interface);
|
|
|
|
if (old_master == our_index) {
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL (window_iface->priv->bridge_ports_store), ni_window_interface_check_bport_to_delete_foreach_cb, ni_interface);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_new_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
guint our_index, master_other;
|
|
|
|
our_index = ni_interface_get_index (window_iface->priv->ni_interface);
|
|
|
|
g_signal_connect (ni_interface, "added-to-bridge", G_CALLBACK (ni_window_interface_added_to_bridge_cb), window_iface);
|
|
g_signal_connect (ni_interface, "removed-from-bridge", G_CALLBACK (ni_window_interface_removed_from_bridge_cb), window_iface);
|
|
|
|
/* Estoy esperando esta señal porque la interfaz podría ser esclava mía */
|
|
master_other = ni_interface_get_master (ni_interface);
|
|
if (master_other == our_index) {
|
|
/* Esta interfaz está esclavizada a nuestra interfaz */
|
|
gtk_list_store_insert_with_values (window_iface->priv->bridge_ports_store, NULL, -1, BRIDGE_PORT_STORE_COL_IFACE_NAME, ni_interface_get_name (ni_interface), BRIDGE_PORT_STORE_COL_OBJECT, ni_interface, -1);
|
|
}
|
|
}
|
|
|
|
static gboolean ni_window_interface_check_bport_to_delete_foreach_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) {
|
|
NIInterface *deleted_iface, *iface;
|
|
|
|
deleted_iface = (NIInterface *) data;
|
|
|
|
gtk_tree_model_get (model, iter, BRIDGE_PORT_STORE_COL_OBJECT, &iface, -1);
|
|
|
|
if (ni_interface_get_index (deleted_iface) == ni_interface_get_index (iface)) {
|
|
gtk_list_store_remove (GTK_LIST_STORE (model), iter);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void ni_window_interface_del_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
/* Espero esta señal porque podría ser que alguno de mis interfaces esclavizadas en el bridge, se haya eliminado */
|
|
|
|
gtk_tree_model_foreach (GTK_TREE_MODEL (window_iface->priv->bridge_ports_store), ni_window_interface_check_bport_to_delete_foreach_cb, ni_interface);
|
|
}
|
|
|
|
/* Eventos de actualización del estado de la propia interfaz */
|
|
void ni_window_interface_update_state_from_flags (NIWindowInterface *window_iface) {
|
|
guint flags;
|
|
|
|
/* Recuperar las flags */
|
|
flags = ni_interface_get_flags (window_iface->priv->ni_interface);
|
|
|
|
if (flags & IFF_UP) {
|
|
gtk_widget_set_sensitive (window_iface->priv->info_name, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_apply, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_name_revert, FALSE);
|
|
gtk_entry_set_text (GTK_ENTRY (window_iface->priv->info_name), ni_interface_get_name (window_iface->priv->ni_interface));
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->info_updown), "UP");
|
|
} else {
|
|
gtk_widget_set_sensitive (window_iface->priv->info_name, TRUE);
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->info_updown), "DOWN");
|
|
}
|
|
}
|
|
|
|
void ni_window_interface_update_state_from_master (NIWindowInterface *window_iface) {
|
|
guint master_index;
|
|
NIInterface *other_iface;
|
|
|
|
master_index = ni_interface_get_master (window_iface->priv->ni_interface);
|
|
|
|
if (master_index == 0) {
|
|
/* No hay master de esta intefaz */
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->info_slave), "<Ninguno>");
|
|
gtk_widget_set_sensitive (window_iface->priv->button_slave_remove, FALSE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_master_add, TRUE);
|
|
} else {
|
|
other_iface = ni_client_get_interface_by_index (ni_interface_get_client (window_iface->priv->ni_interface), master_index);
|
|
|
|
gtk_label_set_text (GTK_LABEL (window_iface->priv->info_slave), ni_interface_get_name (other_iface));
|
|
gtk_widget_set_sensitive (window_iface->priv->button_slave_remove, TRUE);
|
|
gtk_widget_set_sensitive (window_iface->priv->button_master_add, FALSE);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_aditional_setup_for_bridge (NIWindowInterface *window_iface) {
|
|
NIClient *ni_client;
|
|
GList *all_ifaces, *g;
|
|
NIInterface *other_iface;
|
|
guint our_index, other_index;
|
|
GtkTreeIter iter;
|
|
|
|
/* Crear la tab de los bridges */
|
|
prepare_bridge_tab (window_iface);
|
|
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
/* Conectar la señal de agregado al bridge y la de nueva interfaz */
|
|
g_signal_connect (ni_client, "new-interface", G_CALLBACK (ni_window_interface_new_interface_cb), window_iface);
|
|
|
|
g_signal_connect (ni_client, "delete-interface", G_CALLBACK (ni_window_interface_del_interface_cb), window_iface);
|
|
|
|
/* Listar todas las interfaces que tengan listado como esclavo mi interfaz */
|
|
all_ifaces = ni_client_get_list_interfaces (ni_client);
|
|
|
|
our_index = ni_interface_get_index (window_iface->priv->ni_interface);
|
|
for (g = all_ifaces; g != NULL; g = g->next) {
|
|
other_iface = (NIInterface *) g->data;
|
|
|
|
if (window_iface->priv->ni_interface == other_iface) continue; /* No me interesa mi propia interfaz */
|
|
ni_window_interface_new_interface_cb (ni_client, other_iface, window_iface);
|
|
}
|
|
}
|
|
|
|
/* Eventos de los botones de DHCP */
|
|
static void ni_window_interface_dhcp_run_cb (GtkWidget *button, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
guint flags;
|
|
|
|
flags = 0;
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_autorestart))) {
|
|
flags |= 0x0001;
|
|
}
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_dns))) {
|
|
flags |= 0x0002;
|
|
}
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_gws))) {
|
|
flags |= 0x0004;
|
|
}
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window_iface->priv->check_flag_no_ip))) {
|
|
flags |= 0x0008;
|
|
}
|
|
|
|
// Ejecutar el DHCP aquí
|
|
ni_interface_run_dhcp (window_iface->priv->ni_interface, window_iface->priv->dhcp_type, flags);
|
|
}
|
|
|
|
static void ni_window_interface_dhcp_stop_cb (GtkWidget *button, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
// Ejecutar el DHCP aquí
|
|
ni_interface_stop_dhcp (window_iface->priv->ni_interface);
|
|
}
|
|
|
|
static void ni_window_interface_dhcp_type_isc_cb (GtkWidget *button, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (button))) {
|
|
window_iface->priv->dhcp_type = 1;
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_dhcp_type_busybox_cb (GtkWidget *button, gpointer data) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
|
|
|
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (button))) {
|
|
window_iface->priv->dhcp_type = 2;
|
|
}
|
|
}
|
|
|
|
/* Construcción del objeto */
|
|
static void ni_window_interface_constructed (GObject *obj) {
|
|
GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek (GTK_TYPE_WINDOW));
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (obj);
|
|
const GList *ip_list, *g;
|
|
NIIP *ni_ip;
|
|
gchar *name;
|
|
guint flags;
|
|
|
|
parent_class->constructed (obj);
|
|
|
|
if (window_iface->priv->ni_interface == NULL) return;
|
|
|
|
/* Cambiar el título */
|
|
name = g_strdup_printf ("Interfaz %s", ni_interface_get_name (window_iface->priv->ni_interface));
|
|
gtk_window_set_title (GTK_WINDOW (obj), name);
|
|
g_free (name);
|
|
|
|
/* Conectar la señal de IP agregada y la señal de IP eliminada */
|
|
g_signal_connect (window_iface->priv->ni_interface, "new-ip", G_CALLBACK (ni_window_interface_new_ip_cb), window_iface);
|
|
g_signal_connect (window_iface->priv->ni_interface, "delete-ip", G_CALLBACK (ni_window_interface_delete_ip_cb), window_iface);
|
|
g_signal_connect (window_iface->priv->ni_interface, "notify::name", G_CALLBACK (ni_window_interface_changed_name_cb), window_iface);
|
|
g_signal_connect (window_iface->priv->ni_interface, "notify::flags", G_CALLBACK (ni_window_interface_changed_flags_cb), window_iface);
|
|
g_signal_connect (window_iface->priv->ni_interface, "notify::master-index", G_CALLBACK (ni_window_interface_changed_master_cb), window_iface);
|
|
|
|
g_signal_connect (window_iface->priv->ni_interface, "dhcp-type-changed", G_CALLBACK (ni_window_interface_dhcp_type_changed_cb), window_iface);
|
|
g_signal_connect (window_iface->priv->ni_interface, "dhcp-status-updated", G_CALLBACK (ni_window_interface_dhcp_status_updated_cb), window_iface);
|
|
|
|
/* TODO: Recorrer las ips, y procesar la información */
|
|
ip_list = ni_interface_get_ip_list (window_iface->priv->ni_interface);
|
|
|
|
for (g = ip_list; g != NULL; g = g->next) {
|
|
ni_ip = (NIIP *) g->data;
|
|
|
|
ni_window_interface_addr_added_cb (window_iface, ni_ip);
|
|
}
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (window_iface->priv->info_name), ni_interface_get_name (window_iface->priv->ni_interface));
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (window_iface->priv->info_mtu), ni_interface_get_mtu(window_iface->priv->ni_interface));
|
|
ni_window_interface_update_state_from_flags (window_iface);
|
|
ni_window_interface_update_state_from_master (window_iface);
|
|
|
|
if (ni_interface_get_iface_type (window_iface->priv->ni_interface) == NI_LINK_TYPE_BRIDGE) {
|
|
ni_window_interface_aditional_setup_for_bridge (window_iface);
|
|
}
|
|
|
|
ni_window_interface_dhcp_type_changed_cb (window_iface->priv->ni_interface, 0, ni_interface_get_dhcp_type (window_iface->priv->ni_interface), window_iface);
|
|
}
|
|
|
|
static void ni_window_interface_dispose (GObject *obj) {
|
|
NIWindowInterface *window_iface;
|
|
GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek (GTK_TYPE_WINDOW));
|
|
NIClient *ni_client;
|
|
|
|
window_iface = NI_WINDOW_INTERFACE (obj);
|
|
|
|
g_object_unref (window_iface->priv->ni_interface);
|
|
window_iface->priv->ni_interface = NULL;
|
|
|
|
/* Desconectar todos los manejadores de señal del ni_client */
|
|
if (window_iface->priv->ni_interface != NULL) {
|
|
ni_client = ni_interface_get_client (window_iface->priv->ni_interface);
|
|
|
|
g_signal_handlers_disconnect_by_data (window_iface->priv->ni_interface, window_iface);
|
|
g_signal_handlers_disconnect_by_data (ni_client, window_iface);
|
|
}
|
|
|
|
parent_class->dispose (obj);
|
|
}
|
|
|
|
#if 0
|
|
static void ni_window_interface_finalize (GObject *obj) {
|
|
NIWindowInterface *window_iface;
|
|
GObjectClass *parent_class = G_OBJECT_CLASS (g_type_class_peek (GTK_TYPE_WINDOW));
|
|
|
|
window_iface = NI_WINDOW_INTERFACE (obj);
|
|
|
|
/* Nada que hacer, por el momento */
|
|
|
|
parent_class->finalize (obj);
|
|
}
|
|
#endif
|
|
|
|
static void ni_window_interface_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (object);
|
|
g_return_if_fail (NI_IS_WINDOW_INTERFACE (object));
|
|
|
|
switch (prop_id) {
|
|
case PROP_NI_INTERFACE:
|
|
window_iface->priv->ni_interface = NI_INTERFACE (g_value_get_object (value));
|
|
g_object_ref (window_iface->priv->ni_interface);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
|
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (object);
|
|
g_return_if_fail (NI_IS_WINDOW_INTERFACE (object));
|
|
|
|
switch (prop_id) {
|
|
case PROP_NI_INTERFACE:
|
|
g_value_set_object (value, window_iface->priv->ni_interface);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void ni_window_interface_class_init (NIWindowInterfaceClass *klass) {
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
|
|
object_class->set_property = ni_window_interface_set_property;
|
|
object_class->get_property = ni_window_interface_get_property;
|
|
object_class->constructed = ni_window_interface_constructed;
|
|
object_class->dispose = ni_window_interface_dispose;
|
|
|
|
widget_class->delete_event = ni_window_interface_delete_event;
|
|
|
|
obj_properties[PROP_NI_INTERFACE] = g_param_spec_object (
|
|
"ni-interface",
|
|
"Network Inador Client Interface",
|
|
"The interface object",
|
|
NI_TYPE_INTERFACE,
|
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
|
|
}
|
|
|
|
GtkWidget *ni_window_interface_create_tree_for_ip (GtkListStore *store, GtkWidget **tree) {
|
|
GtkWidget *scrolled;
|
|
GtkAdjustment *h, *v;
|
|
GtkTreeViewColumn *column;
|
|
GtkCellRenderer *renderer;
|
|
|
|
*tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
|
|
|
gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (*tree), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
|
|
h = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
|
|
v = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
|
|
|
|
scrolled = gtk_scrolled_window_new (h, v);
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
|
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
column = gtk_tree_view_column_new_with_attributes ("Dirección", renderer, "text", IP_STORE_COL_MAIN_IP, NULL);
|
|
gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (column), TRUE);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
|
|
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
column = gtk_tree_view_column_new ();
|
|
gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (column), TRUE);
|
|
gtk_tree_view_column_set_title (GTK_TREE_VIEW_COLUMN (column), "Vigencia");
|
|
gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, TRUE);
|
|
gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), renderer, ni_window_interface_cell_renderer_timestamp, NULL, NULL);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled), *tree);
|
|
|
|
return scrolled;
|
|
}
|
|
|
|
GtkWidget *ni_window_interface_create_tree_for_bridge_ports (GtkListStore *store, GtkWidget **tree) {
|
|
GtkWidget *scrolled;
|
|
GtkAdjustment *h, *v;
|
|
GtkTreeViewColumn *column;
|
|
GtkCellRenderer *renderer;
|
|
|
|
*tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
|
|
|
h = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
|
|
v = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (*tree));
|
|
|
|
scrolled = gtk_scrolled_window_new (h, v);
|
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
|
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
column = gtk_tree_view_column_new_with_attributes ("Interfaz", renderer, "text", BRIDGE_PORT_STORE_COL_IFACE_NAME, NULL);
|
|
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled), *tree);
|
|
|
|
return scrolled;
|
|
}
|
|
|
|
static void prepare_info_tab (NIWindowInterface *window_iface) {
|
|
GtkWidget *vbox, *hbox, *label;
|
|
GtkSizeGroup *size_l;
|
|
GtkWindow *window = GTK_WINDOW (window_iface);
|
|
NIWindowInterfacePrivate *priv = window_iface->priv;
|
|
|
|
priv->vbox_info = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
label = gtk_label_new ("Info");
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->vbox_info, label);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->vbox_info), 5);
|
|
|
|
size_l = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
|
|
/* Poner las labels de información de la propia interfaz */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Nombre de la interfaz:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->button_name_revert = gtk_button_new_from_icon_name ("view-refresh", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_name_revert, FALSE);
|
|
g_signal_connect (priv->button_name_revert, "clicked", G_CALLBACK (ni_window_interface_name_cancel_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_name_revert, FALSE, FALSE, 0);
|
|
|
|
priv->button_name_apply = gtk_button_new_from_icon_name ("document-save", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_name_apply, FALSE);
|
|
g_signal_connect (priv->button_name_apply, "clicked", G_CALLBACK (ni_window_interface_name_apply_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_name_apply, FALSE, FALSE, 0);
|
|
|
|
priv->info_name = gtk_entry_new ();
|
|
gtk_entry_set_text (GTK_ENTRY (priv->info_name), "<Desconocido>");
|
|
gtk_widget_set_sensitive (priv->info_name, FALSE);
|
|
g_signal_connect (priv->info_name, "changed", G_CALLBACK (ni_window_interface_name_edit_cb), window_iface);
|
|
g_signal_connect (priv->info_name, "activate", G_CALLBACK (ni_window_interface_name_apply_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->info_name, TRUE, TRUE, 0);
|
|
|
|
/* La botonera del MTU */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("MTU:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->button_mtu_revert = gtk_button_new_from_icon_name ("view-refresh", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_mtu_revert, FALSE);
|
|
g_signal_connect (priv->button_mtu_revert, "clicked", G_CALLBACK (ni_window_interface_mtu_cancel_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_mtu_revert, FALSE, FALSE, 0);
|
|
|
|
priv->button_mtu_apply = gtk_button_new_from_icon_name ("document-save", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_mtu_apply, FALSE);
|
|
g_signal_connect (priv->button_mtu_apply, "clicked", G_CALLBACK (ni_window_interface_mtu_apply_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_mtu_apply, FALSE, FALSE, 0);
|
|
|
|
/* TODO: Revisar el minimo y máximo del MTU */
|
|
priv->info_mtu = gtk_spin_button_new_with_range (1200, 9000, 10);
|
|
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (priv->info_mtu), 0);
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->info_mtu), 0);
|
|
g_signal_connect (priv->info_mtu, "value-changed", G_CALLBACK (ni_window_interface_mtu_edit_cb), window_iface);
|
|
g_signal_connect (priv->info_mtu, "activate", G_CALLBACK (ni_window_interface_mtu_apply_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->info_mtu, TRUE, TRUE, 0);
|
|
|
|
/* Las banderas de la intefaz */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Estado:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->button_down = gtk_button_new_from_icon_name ("go-down", GTK_ICON_SIZE_BUTTON);
|
|
g_signal_connect (priv->button_down, "clicked", G_CALLBACK (ni_window_interface_down_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_down, FALSE, FALSE, 0);
|
|
|
|
priv->button_up = gtk_button_new_from_icon_name ("go-up", GTK_ICON_SIZE_BUTTON);
|
|
g_signal_connect (priv->button_up, "clicked", G_CALLBACK (ni_window_interface_up_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_up, FALSE, FALSE, 0);
|
|
|
|
priv->info_updown = gtk_label_new ("");
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->info_updown, FALSE, FALSE, 0);
|
|
|
|
/* Presenta si la interfaz está esclavizada o no */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Interfaz maestra:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->button_slave_remove = gtk_button_new_from_icon_name ("edit-delete", GTK_ICON_SIZE_BUTTON);
|
|
g_signal_connect (priv->button_slave_remove, "clicked", G_CALLBACK (ni_window_interface_clear_slave_click_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_slave_remove, FALSE, FALSE, 0);
|
|
|
|
priv->button_master_add = gtk_button_new_from_icon_name ("insert-link", GTK_ICON_SIZE_BUTTON);
|
|
g_signal_connect (priv->button_master_add, "clicked", G_CALLBACK (ni_window_interface_make_slave_click_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_master_add, FALSE, FALSE, 0);
|
|
|
|
priv->info_slave = gtk_label_new ("");
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->info_slave, FALSE, FALSE, 0);
|
|
}
|
|
|
|
static void prepare_bridge_tab (NIWindowInterface *window_iface) {
|
|
GtkWidget *vbox, *hbox, *vbox2;
|
|
GtkSizeGroup *size_l;
|
|
GtkWindow *window = GTK_WINDOW (window_iface);
|
|
NIWindowInterfacePrivate *priv = window_iface->priv;
|
|
GtkWidget *scrolled;
|
|
GtkWidget *button, *label, *label_tab;
|
|
GtkTreeSelection *selection;
|
|
|
|
priv->vbox_bridges = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
label_tab = gtk_label_new ("Bridge");
|
|
gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), priv->vbox_bridges, label_tab, 1);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->vbox_bridges), 5);
|
|
|
|
size_l = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
|
|
/* TODO: Poner aquí las labels de información de bridges */
|
|
/* Preparar el list store */
|
|
priv->bridge_ports_store = gtk_list_store_new (NUM_BRIDGE_PORT_STORE_COLS, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_bridges), vbox, TRUE, TRUE, 5);
|
|
|
|
label = gtk_label_new ("Interfaces en el bridge:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
|
|
|
|
scrolled = ni_window_interface_create_tree_for_bridge_ports (priv->bridge_ports_store, &priv->tree_bridge_ports);
|
|
gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 0);
|
|
|
|
/* Botonera del tree view */
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
|
|
|
|
button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
g_signal_connect (button, "clicked", G_CALLBACK (ni_window_interface_bport_button_add_cb), window_iface);
|
|
|
|
priv->del_bport_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), priv->del_bport_button, FALSE, FALSE, 0);
|
|
g_signal_connect (priv->del_bport_button, "clicked", G_CALLBACK (ni_window_interface_bport_button_del_cb), window_iface);
|
|
gtk_widget_set_sensitive (priv->del_bport_button, FALSE);
|
|
|
|
/* Conectar la señal de cambio de selección del tree view */
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_bridge_ports));
|
|
g_signal_connect (selection, "changed", G_CALLBACK (has_bport_selected_cb), window_iface);
|
|
|
|
gtk_widget_show_all (priv->vbox_bridges);
|
|
gtk_widget_show (label_tab);
|
|
}
|
|
|
|
static void prepare_dhcpv4_tab (NIWindowInterface *window_iface) {
|
|
GtkWidget *vbox, *hbox, *label, *button;
|
|
GtkSizeGroup *size_l;
|
|
GtkWidget *expander;
|
|
GtkWindow *window = GTK_WINDOW (window_iface);
|
|
NIWindowInterfacePrivate *priv = window_iface->priv;
|
|
GtkWidget *item;
|
|
|
|
priv->vbox_dhcpv4 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
label = gtk_label_new ("DHCPv4");
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->vbox_dhcpv4, label);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->vbox_dhcpv4), 5);
|
|
|
|
size_l = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
|
|
/* Poner las labels de información de la propia interfaz */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), hbox, FALSE, FALSE, 0);
|
|
|
|
/* Preparar el menú para ejecutar el cliente de DHCP */
|
|
priv->menu_dhcpv4 = gtk_menu_new ();
|
|
priv->dhcp_type = 1;
|
|
|
|
item = gtk_radio_menu_item_new_with_label (NULL, "Correr ISC DHCP Client");
|
|
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
|
|
g_signal_connect (item, "activate", G_CALLBACK (ni_window_interface_dhcp_type_isc_cb), window_iface);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_dhcpv4), item);
|
|
gtk_widget_show (item);
|
|
|
|
item = gtk_radio_menu_item_new_with_label_from_widget (GTK_RADIO_MENU_ITEM (item), "Correr Busybox UDHCPC");
|
|
g_signal_connect (item, "activate", G_CALLBACK (ni_window_interface_dhcp_type_busybox_cb), window_iface);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_dhcpv4), item);
|
|
gtk_widget_show (item);
|
|
|
|
label = gtk_label_new ("Cliente DHCP:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->button_dhcp_stop = gtk_button_new_from_icon_name ("process-stop", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_dhcp_stop, FALSE);
|
|
g_signal_connect (priv->button_dhcp_stop, "clicked", G_CALLBACK (ni_window_interface_dhcp_stop_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_dhcp_stop, FALSE, FALSE, 0);
|
|
|
|
button = gtk_menu_button_new ();
|
|
gtk_menu_button_set_popup (GTK_MENU_BUTTON (button), priv->menu_dhcpv4);
|
|
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
priv->button_dhcp_run = gtk_button_new_from_icon_name ("system-run", GTK_ICON_SIZE_BUTTON);
|
|
gtk_widget_set_sensitive (priv->button_dhcp_run, FALSE);
|
|
g_signal_connect (priv->button_dhcp_run, "clicked", G_CALLBACK (ni_window_interface_dhcp_run_cb), window_iface);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->button_dhcp_run, FALSE, FALSE, 0);
|
|
|
|
/* Generar un expander para opciones avanzadas */
|
|
expander = gtk_expander_new_with_mnemonic ("_Opciones avanzadas");
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), expander, FALSE, FALSE, 0);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
|
gtk_container_add (GTK_CONTAINER (expander), vbox);
|
|
|
|
/* Primera opción, autoreiniciar */
|
|
priv->check_flag_autorestart = gtk_check_button_new_with_label ("Autoreiniciar proceso");
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_autorestart), TRUE);
|
|
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_autorestart, FALSE, FALSE, 3);
|
|
|
|
/* Segunda opción, no instalar información DNS */
|
|
priv->check_flag_no_dns = gtk_check_button_new_with_label ("No instalar información DNS");
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_dns), FALSE);
|
|
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_dns, FALSE, FALSE, 3);
|
|
|
|
/* Tercera opción, no instalar información del gateway */
|
|
priv->check_flag_no_gws = gtk_check_button_new_with_label ("No instalar rutas por defecto");
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_gws), FALSE);
|
|
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_gws, FALSE, FALSE, 3);
|
|
|
|
/* Cuarta opción, no instalar información de las ips */
|
|
priv->check_flag_no_ip = gtk_check_button_new_with_label ("No instalar dirección IP adquirida");
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check_flag_no_ip), FALSE);
|
|
gtk_box_pack_start (GTK_BOX (vbox), priv->check_flag_no_ip, FALSE, FALSE, 3);
|
|
|
|
|
|
/* Las labels del estado */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Tipo de cliente:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_process = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_process), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_process), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_process, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Estado:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_status = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_status), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_status), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_status, FALSE, FALSE, 0);
|
|
|
|
/* Un super vbox para ocultar toda la información de DHCP */
|
|
priv->vbox_dhcpv4_info = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4), priv->vbox_dhcpv4_info, FALSE, FALSE, 10);
|
|
|
|
/* Placeholder para la IP */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Dirección IP:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_ip_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_ip_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_ip_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_ip_label, FALSE, FALSE, 0);
|
|
|
|
/* Placeholder para el gateway */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Gateway:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_gateway_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_gateway_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_gateway_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_gateway_label, FALSE, FALSE, 0);
|
|
|
|
/* Placeholder para el broadcast, si está presente */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Broadcast:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_bcast_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_bcast_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_bcast_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_bcast_label, FALSE, FALSE, 0);
|
|
|
|
/* Placer holder para los DNS */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("DNS:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_dns_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_dns_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_dns_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_dns_label, FALSE, FALSE, 0);
|
|
|
|
/* Placer holder para el nombre del servidor DHCP */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Servidor DHCP:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_server_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_server_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_server_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_server_label, FALSE, FALSE, 0);
|
|
|
|
/* Placeholder para el tiempo de concesión */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Tiempo de concesión:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_time_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_time_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_time_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_time_label, FALSE, FALSE, 0);
|
|
|
|
/* Placeholder para el dominio */
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_dhcpv4_info), hbox, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new ("Dominio:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
gtk_size_group_add_widget (size_l, label);
|
|
|
|
priv->dhcpv4_domain_label = gtk_label_new ("");
|
|
gtk_label_set_xalign (GTK_LABEL (priv->dhcpv4_domain_label), 0.0);
|
|
gtk_label_set_selectable (GTK_LABEL (priv->dhcpv4_domain_label), TRUE);
|
|
gtk_box_pack_end (GTK_BOX (hbox), priv->dhcpv4_domain_label, FALSE, FALSE, 0);
|
|
}
|
|
|
|
static void ni_window_interface_init (NIWindowInterface *window_iface) {
|
|
NIWindowInterfacePrivate *priv = ni_window_interface_get_instance_private (window_iface);
|
|
window_iface->priv = priv;
|
|
GtkWindow *window = GTK_WINDOW (window_iface);
|
|
GtkWidget *hbox, *label, *button, *image;
|
|
GtkWidget *vbox, *scrolled, *vbox2;
|
|
GtkTreeSelection *selection;
|
|
GtkSizeGroup *size_l;
|
|
|
|
/* initialize all public and private members to reasonable default values.
|
|
* They are all automatically initialized to 0 to begin with. */
|
|
priv->ni_interface = NULL;
|
|
gtk_window_set_title (window, "Interfaz");
|
|
|
|
priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_container_add (GTK_CONTAINER (window), priv->vbox);
|
|
|
|
priv->notebook = gtk_notebook_new ();
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox), priv->notebook, TRUE, TRUE, 0);
|
|
|
|
/* Página de la información general de la interfaz */
|
|
prepare_info_tab (window_iface);
|
|
|
|
/* Página de IPv4 */
|
|
priv->vbox_ipv4 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
label = gtk_label_new ("IPv4");
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->vbox_ipv4, label);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->vbox_ipv4), 5);
|
|
|
|
/* Preparar el list store */
|
|
priv->ipv4_store = gtk_list_store_new (NUM_IP_STORE_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_ipv4), vbox, TRUE, TRUE, 5);
|
|
|
|
label = gtk_label_new ("Direcciones:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
|
|
|
|
scrolled = ni_window_interface_create_tree_for_ip (priv->ipv4_store, &priv->tree_ipv4);
|
|
gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 0);
|
|
|
|
/* Botonera del tree view */
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
|
|
|
|
button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
g_signal_connect (button, "clicked", G_CALLBACK (ni_window_interface_addr_v4_button_add_cb), window_iface);
|
|
|
|
priv->del_ipv4_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), priv->del_ipv4_button, FALSE, FALSE, 0);
|
|
g_signal_connect (priv->del_ipv4_button, "clicked", G_CALLBACK (ni_window_interface_addr_v4_button_del_cb), window_iface);
|
|
gtk_widget_set_sensitive (priv->del_ipv4_button, FALSE);
|
|
|
|
/* Conectar la señal de cambio de selección del tree view */
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv4));
|
|
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v4_cb), window_iface);
|
|
|
|
/* Página del cliente de DHCP */
|
|
prepare_dhcpv4_tab (window_iface);
|
|
|
|
/* Página de IPv6 */
|
|
priv->vbox_ipv6 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
label = gtk_label_new ("IPv6");
|
|
gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->vbox_ipv6, label);
|
|
gtk_container_set_border_width (GTK_CONTAINER (priv->vbox_ipv6), 5);
|
|
|
|
/* Preparar el list store */
|
|
priv->ipv6_store = gtk_list_store_new (NUM_IP_STORE_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox_ipv6), vbox, TRUE, TRUE, 5);
|
|
|
|
label = gtk_label_new ("Direcciones:");
|
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
|
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
|
|
|
|
scrolled = ni_window_interface_create_tree_for_ip (priv->ipv6_store, &priv->tree_ipv6);
|
|
gtk_box_pack_start (GTK_BOX (hbox), scrolled, TRUE, TRUE, 0);
|
|
|
|
/* Botonera del tree view */
|
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
|
|
|
|
button = gtk_button_new_from_icon_name ("list-add", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
|
g_signal_connect (button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_add_cb), window_iface);
|
|
|
|
priv->del_ipv6_button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
gtk_box_pack_start (GTK_BOX (vbox2), priv->del_ipv6_button, FALSE, FALSE, 0);
|
|
g_signal_connect (priv->del_ipv6_button, "clicked", G_CALLBACK (ni_window_interface_addr_v6_button_del_cb), window_iface);
|
|
gtk_widget_set_sensitive (priv->del_ipv6_button, FALSE);
|
|
|
|
/* Conectar la señal de cambio de selección del tree view */
|
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree_ipv6));
|
|
g_signal_connect (selection, "changed", G_CALLBACK (has_ip_selected_v6_cb), window_iface);
|
|
|
|
/* La botonera inferior */
|
|
hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
|
|
gtk_box_pack_start (GTK_BOX (priv->vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
/* El boton de cerrar */
|
|
button = gtk_button_new_with_label ("Cerrar");
|
|
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_hide_on_delete), window);
|
|
image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_BUTTON);
|
|
gtk_button_set_image (GTK_BUTTON (button), image);
|
|
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show_all (priv->vbox);
|
|
}
|
|
|
|
GtkWidget* ni_window_interface_new (NIInterface *ni_interface) {
|
|
NIWindowInterface *window_iface;
|
|
|
|
window_iface = g_object_new (NI_TYPE_WINDOW_INTERFACE, "type", GTK_WINDOW_TOPLEVEL, "ni-interface", ni_interface, NULL);
|
|
|
|
return GTK_WIDGET (window_iface);
|
|
}
|
|
|