Agrego cliente gtk para pruebas de eventos.
parent
715dfeddf7
commit
7b7906e0f6
|
@ -42,3 +42,8 @@ po/stamp-po
|
||||||
|
|
||||||
*.gmo
|
*.gmo
|
||||||
*.mo
|
*.mo
|
||||||
|
|
||||||
|
client-gtk/inador-gtk-client
|
||||||
|
client-gtk/ni-marshal.c
|
||||||
|
client-gtk/ni-marshal.h
|
||||||
|
client-gtk/core
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
SUBDIRS = src po
|
SUBDIRS = src client-gtk po
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Automake file for NetworkInador GTK Client
|
||||||
|
|
||||||
|
BUILT_SOURCES = \
|
||||||
|
ni-marshal.c \
|
||||||
|
ni-marshal.h
|
||||||
|
|
||||||
|
bin_PROGRAMS = inador-gtk-client
|
||||||
|
inador_gtk_client_SOURCES = main.c \
|
||||||
|
ni-client.c ni-client.h \
|
||||||
|
ni-interface.c ni-interface.h \
|
||||||
|
ni-window-interface.c ni-window-interface.h \
|
||||||
|
ni-ip.c ni-ip.h \
|
||||||
|
$(BUILT_SOURCES)
|
||||||
|
|
||||||
|
#inador_gtk_client_CPPFLAGS = -DGAMEDATA_DIR=\"$(gamedatadir)/\" -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
||||||
|
inador_gtk_client_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS)
|
||||||
|
inador_gtk_client_CFLAGS = $(GTK_CFLAGS) $(AM_CFLAGS)
|
||||||
|
inador_gtk_client_LDADD = $(GTK_LIBS)
|
||||||
|
LDADD = $(LIBINTL)
|
||||||
|
|
||||||
|
ni-marshal.h: $(srcdir)/ni-marshal.list
|
||||||
|
$(AM_V_GEN) ( $(GLIB_GENMARSHAL) --prefix=_ni_marshal $(srcdir)/ni-marshal.list \
|
||||||
|
--header \
|
||||||
|
--internal > ni-marshal.h.tmp \
|
||||||
|
&& mv ni-marshal.h.tmp ni-marshal.h ) \
|
||||||
|
|| ( rm -f ni-marshal.h.tmp && exit 1 )
|
||||||
|
|
||||||
|
ni-marshal.c: $(srcdir)/ni-marshal.list
|
||||||
|
$(AM_V_GEN) ( $(GLIB_GENMARSHAL) --prefix=_ni_marshal $(srcdir)/ni-marshal.list \
|
||||||
|
--header \
|
||||||
|
--body \
|
||||||
|
--internal > ni-marshal.c.tmp \
|
||||||
|
&& mv ni-marshal.c.tmp ni-marshal.c ) \
|
||||||
|
|| ( rm -f ni-marshal.c.tmp && exit 1 )
|
||||||
|
|
||||||
|
EXTRA_DIST = ni-marshal.list
|
||||||
|
|
||||||
|
CLEANFILES = \
|
||||||
|
$(BUILT_SOURCES)
|
||||||
|
|
|
@ -0,0 +1,284 @@
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include <linux/if_arp.h>
|
||||||
|
|
||||||
|
#include "ni-client.h"
|
||||||
|
#include "ni-interface.h"
|
||||||
|
#include "ni-window-interface.h"
|
||||||
|
#include "../src/link-types.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
COL_IFACE_OBJECT,
|
||||||
|
|
||||||
|
COL_IFACE_INDEX,
|
||||||
|
COL_IFACE_NAME,
|
||||||
|
|
||||||
|
COL_IFACE_ICON,
|
||||||
|
|
||||||
|
COL_IFACE_WINDOW,
|
||||||
|
|
||||||
|
NUM_COLS_IFACE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
INTERFACES_GROUP_ETHERNET,
|
||||||
|
INTERFACES_GROUP_WIFI,
|
||||||
|
INTERFACES_GROUP_BRIDGES,
|
||||||
|
INTERFACES_GROUP_OTHER,
|
||||||
|
INTERFACES_GROUP_LOOP_DUMMY,
|
||||||
|
NUM_INTERFACES_GROUP
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int group_type;
|
||||||
|
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *label;
|
||||||
|
GtkWidget *iconview;
|
||||||
|
GtkWidget *scrolled;
|
||||||
|
GtkTreeModel *model_filter;
|
||||||
|
} UINetworkType;
|
||||||
|
|
||||||
|
const char *group_names[NUM_INTERFACES_GROUP] = {
|
||||||
|
"Redes cableadas",
|
||||||
|
"Redes inalámbricas",
|
||||||
|
"Puentes",
|
||||||
|
"Otros",
|
||||||
|
"Loopback y otros tipos"
|
||||||
|
};
|
||||||
|
|
||||||
|
GtkListStore *interfaces_store;
|
||||||
|
NIClient *ni_client;
|
||||||
|
GtkWidget *ventana;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *empty_label = NULL;
|
||||||
|
GHashTable *network_blocks_list;
|
||||||
|
|
||||||
|
static void click_interface_cb (GtkIconView *iconview, GtkTreePath *path, gpointer data) {
|
||||||
|
UINetworkType *network_block = (UINetworkType *) data;
|
||||||
|
GtkTreeIter iter, real_iter;
|
||||||
|
GtkWidget *ventana;
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
|
||||||
|
gtk_tree_model_get_iter (GTK_TREE_MODEL (network_block->model_filter), &iter, path);
|
||||||
|
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (network_block->model_filter), &iter, COL_IFACE_OBJECT, &ni_interface, COL_IFACE_WINDOW, &ventana, -1);
|
||||||
|
|
||||||
|
if (ventana == NULL) {
|
||||||
|
ventana = ni_window_interface_new (ni_interface);
|
||||||
|
|
||||||
|
gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (network_block->model_filter), &real_iter, &iter);
|
||||||
|
gtk_list_store_set (interfaces_store, &real_iter, COL_IFACE_WINDOW, ventana, -1);
|
||||||
|
}
|
||||||
|
gtk_widget_show (ventana);
|
||||||
|
}
|
||||||
|
|
||||||
|
int guess_interface_type (NIInterface *ni_interface) {
|
||||||
|
guint type;
|
||||||
|
|
||||||
|
type = ni_interface_get_iface_type (ni_interface);
|
||||||
|
if (type == NI_LINK_TYPE_ETHERNET) {
|
||||||
|
return INTERFACES_GROUP_ETHERNET;
|
||||||
|
} else if (type == NI_LINK_TYPE_WIFI) {
|
||||||
|
return INTERFACES_GROUP_WIFI;
|
||||||
|
} else if (type == NI_LINK_TYPE_DUMMY || type == NI_LINK_TYPE_LOOPBACK) {
|
||||||
|
return INTERFACES_GROUP_LOOP_DUMMY;
|
||||||
|
} else if (type == NI_LINK_TYPE_BRIDGE) {
|
||||||
|
return INTERFACES_GROUP_BRIDGES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return INTERFACES_GROUP_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean network_block_model_filter_by_type (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
const gchar *iface_type;
|
||||||
|
UINetworkType *network_block = (UINetworkType *) data;
|
||||||
|
|
||||||
|
gtk_tree_model_get (model, iter, COL_IFACE_OBJECT, &ni_interface, -1);
|
||||||
|
if (ni_interface == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//iface_type = ni_interface_get_iface_type (ni_interface);
|
||||||
|
if (guess_interface_type (ni_interface) == network_block->group_type) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINetworkType * create_block_list (int type) {
|
||||||
|
UINetworkType *network_block;
|
||||||
|
int g, pos;
|
||||||
|
|
||||||
|
if (g_hash_table_size (network_blocks_list) == 0) {
|
||||||
|
/* Eliminar la etiqueta */
|
||||||
|
gtk_widget_destroy (empty_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
network_block = g_new0 (UINetworkType, 1);
|
||||||
|
|
||||||
|
network_block->group_type = type;
|
||||||
|
|
||||||
|
network_block->model_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (interfaces_store), NULL);
|
||||||
|
printf ("Para el group type: %i, el model_filter: %p\n", type, network_block->model_filter);
|
||||||
|
gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (network_block->model_filter), network_block_model_filter_by_type, network_block, NULL);
|
||||||
|
|
||||||
|
network_block->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), network_block->vbox, FALSE, FALSE, 5);
|
||||||
|
/* Reordenar los grupos presentes, dentro del vbox */
|
||||||
|
pos = 0;
|
||||||
|
for (g = 0; g < NUM_INTERFACES_GROUP && g < type; g++) {
|
||||||
|
if (g_hash_table_lookup (network_blocks_list, GINT_TO_POINTER (g)) != NULL) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gtk_box_reorder_child (GTK_BOX (vbox), network_block->vbox, pos);
|
||||||
|
|
||||||
|
network_block->label = gtk_label_new (group_names [type]);
|
||||||
|
gtk_box_pack_start (GTK_BOX (network_block->vbox), network_block->label, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
network_block->iconview = gtk_icon_view_new_with_model (network_block->model_filter);
|
||||||
|
g_signal_connect (network_block->iconview, "item-activated", G_CALLBACK (click_interface_cb), network_block);
|
||||||
|
|
||||||
|
gtk_icon_view_set_text_column (GTK_ICON_VIEW (network_block->iconview), COL_IFACE_NAME);
|
||||||
|
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (network_block->iconview), COL_IFACE_ICON);
|
||||||
|
//gtk_icon_view_set_columns (GTK_ICON_VIEW (network_block->iconview), 1000);
|
||||||
|
gtk_icon_view_set_reorderable (GTK_ICON_VIEW (network_block->iconview), FALSE);
|
||||||
|
|
||||||
|
network_block->scrolled = gtk_scrolled_window_new (
|
||||||
|
gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (network_block->iconview)),
|
||||||
|
gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (network_block->iconview)));
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (network_block->scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (network_block->scrolled), network_block->iconview);
|
||||||
|
gtk_box_pack_start (GTK_BOX (network_block->vbox), network_block->scrolled, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
gtk_widget_show_all (network_block->vbox);
|
||||||
|
|
||||||
|
return network_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean locate_interface_from_store (GtkListStore *store, GtkTreeIter *iter, guint index) {
|
||||||
|
gboolean has;
|
||||||
|
guint index_data;
|
||||||
|
|
||||||
|
has = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), iter);
|
||||||
|
while (has) {
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (interfaces_store), iter, COL_IFACE_INDEX, &index_data, -1);
|
||||||
|
|
||||||
|
if (index == index_data) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
has = gtk_tree_model_iter_next (GTK_TREE_MODEL (interfaces_store), iter);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void interface_changed_name_cb (GObject *object, GParamSpec *sp, gpointer data) {
|
||||||
|
NIInterface *ni_interface = NI_INTERFACE (object);
|
||||||
|
guint index;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
index = ni_interface_get_index (ni_interface);
|
||||||
|
|
||||||
|
if (locate_interface_from_store (interfaces_store, &iter, index)) {
|
||||||
|
gtk_list_store_set (interfaces_store, &iter, COL_IFACE_NAME, ni_interface_get_name (ni_interface), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void new_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
||||||
|
guint index;
|
||||||
|
UINetworkType *network_block;
|
||||||
|
int type;
|
||||||
|
GdkPixbuf *icon;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
type = guess_interface_type (ni_interface);
|
||||||
|
network_block = g_hash_table_lookup (network_blocks_list, GINT_TO_POINTER (type));
|
||||||
|
|
||||||
|
if (network_block == NULL) {
|
||||||
|
/* El bloque está vacio, pedir crearlo */
|
||||||
|
network_block = create_block_list (type);
|
||||||
|
|
||||||
|
g_hash_table_insert (network_blocks_list, GINT_TO_POINTER (type), network_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == INTERFACES_GROUP_ETHERNET) {
|
||||||
|
icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "network-wired", 32, 0, NULL);
|
||||||
|
} else {
|
||||||
|
icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), "network-wired", 32, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_list_store_insert (interfaces_store, &iter, -1);
|
||||||
|
gtk_list_store_set (interfaces_store, &iter, COL_IFACE_OBJECT, ni_interface, COL_IFACE_INDEX, ni_interface_get_index (ni_interface), COL_IFACE_NAME, ni_interface_get_name (ni_interface), COL_IFACE_ICON, icon, COL_IFACE_WINDOW, NULL, -1);
|
||||||
|
|
||||||
|
g_signal_connect (ni_interface, "notify::name", G_CALLBACK (interface_changed_name_cb), NULL);
|
||||||
|
|
||||||
|
g_object_unref (icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_interface_cb (NIClient *ni_client, NIInterface *ni_interface, gpointer data) {
|
||||||
|
GtkWidget *ventana;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
if (locate_interface_from_store (interfaces_store, &iter, ni_interface_get_index (ni_interface))) {
|
||||||
|
gtk_tree_model_get (GTK_TREE_MODEL (interfaces_store), &iter, COL_IFACE_WINDOW, &ventana, -1);
|
||||||
|
/* Eliminar este objeto */
|
||||||
|
if (ventana != NULL) {
|
||||||
|
gtk_widget_destroy (ventana);
|
||||||
|
}
|
||||||
|
gtk_list_store_remove (interfaces_store, &iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cerrar_ventana_cb (GtkWidget *ventana, gpointer data) {
|
||||||
|
g_object_unref (ni_client);
|
||||||
|
gtk_main_quit ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
gboolean connected;
|
||||||
|
GtkWidget *label, *scrolled;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
ni_client = ni_client_new ();
|
||||||
|
|
||||||
|
connected = ni_client_connect (ni_client);
|
||||||
|
g_signal_connect (ni_client, "new-interface", G_CALLBACK (new_interface_cb), NULL);
|
||||||
|
g_signal_connect (ni_client, "delete-interface", G_CALLBACK (delete_interface_cb), NULL);
|
||||||
|
|
||||||
|
interfaces_store = gtk_list_store_new (NUM_COLS_IFACE, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
|
||||||
|
|
||||||
|
network_blocks_list = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
|
ventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (ventana), "Interfaces");
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (ventana), 640, 480);
|
||||||
|
g_signal_connect (ventana, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||||
|
|
||||||
|
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (ventana), scrolled);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
gtk_widget_set_size_request (vbox, 260, -1);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (scrolled), vbox);
|
||||||
|
|
||||||
|
if (connected == FALSE) {
|
||||||
|
empty_label = gtk_label_new ("El servicio del network inador no está corriendo\n");
|
||||||
|
} else {
|
||||||
|
empty_label = gtk_label_new ("Recuperando información...\n");
|
||||||
|
}
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), empty_label, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
gtk_widget_show_all (ventana);
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,443 @@
|
||||||
|
/*
|
||||||
|
* ni-client.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 <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include "ni-client.h"
|
||||||
|
#include "ni-interface.h"
|
||||||
|
#include "ni-marshal.h"
|
||||||
|
#include "../src/network-inador-manager.h"
|
||||||
|
|
||||||
|
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||||
|
|
||||||
|
/* Privados desde el ni-interface */
|
||||||
|
void ni_interface_consume_values (NIInterface *ni_interface, char *name, gint arp_type, guint master_index, guint mtu, guint flags);
|
||||||
|
|
||||||
|
/* Privados locales */
|
||||||
|
static void ni_client_dispose (GObject *obj);
|
||||||
|
static void ni_client_finalize (GObject *obj);
|
||||||
|
|
||||||
|
struct _NIClientPrivate {
|
||||||
|
int client_socket;
|
||||||
|
|
||||||
|
gchar *socket_path;
|
||||||
|
GHashTable *interfaces;
|
||||||
|
guint source;
|
||||||
|
guint events;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_SOCKET_PATH = 1,
|
||||||
|
|
||||||
|
N_PROPERTIES
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DATA_READ,
|
||||||
|
|
||||||
|
NEW_INTERFACE,
|
||||||
|
|
||||||
|
DELETE_INTERFACE,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (NIClient, ni_client, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static gboolean ni_client_data_read (NIClient *ni_client, gpointer data, guint size);
|
||||||
|
|
||||||
|
static void ni_client_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
NIClient *ni_client = NI_CLIENT (object);
|
||||||
|
g_return_if_fail (NI_IS_CLIENT (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_SOCKET_PATH:
|
||||||
|
if (ni_client->priv->socket_path != NULL) {
|
||||||
|
g_free (ni_client->priv->socket_path);
|
||||||
|
}
|
||||||
|
ni_client->priv->socket_path = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
NIClient *ni_client = NI_CLIENT (object);
|
||||||
|
g_return_if_fail (NI_IS_CLIENT (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_SOCKET_PATH:
|
||||||
|
g_value_set_string (value, ni_client->priv->socket_path);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_class_init (NIClientClass *klass) {
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->set_property = ni_client_set_property;
|
||||||
|
object_class->get_property = ni_client_get_property;
|
||||||
|
object_class->dispose = ni_client_dispose;
|
||||||
|
object_class->finalize = ni_client_finalize;
|
||||||
|
|
||||||
|
obj_properties[PROP_SOCKET_PATH] = g_param_spec_string (
|
||||||
|
"socket-path",
|
||||||
|
"Socket Path",
|
||||||
|
"The path of the unix socket.",
|
||||||
|
COMMAND_SOCKET_PATH,
|
||||||
|
G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
|
||||||
|
|
||||||
|
signals[DATA_READ] = g_signal_new ("packet-read",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NIClientClass, data_response),
|
||||||
|
g_signal_accumulator_true_handled,
|
||||||
|
NULL,
|
||||||
|
_ni_marshal_BOOLEAN__POINTER_UINT,
|
||||||
|
G_TYPE_BOOLEAN,
|
||||||
|
2,
|
||||||
|
G_TYPE_POINTER | G_SIGNAL_TYPE_STATIC_SCOPE,
|
||||||
|
G_TYPE_UINT);
|
||||||
|
|
||||||
|
signals[NEW_INTERFACE] = g_signal_new ("new-interface",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NIClientClass, new_interface),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
NI_TYPE_INTERFACE);
|
||||||
|
|
||||||
|
signals[DELETE_INTERFACE] = g_signal_new ("delete-interface",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NIClientClass, delete_interface),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
NI_TYPE_INTERFACE);
|
||||||
|
|
||||||
|
klass->data_response = ni_client_data_read;
|
||||||
|
klass->new_interface = NULL;
|
||||||
|
klass->delete_interface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_process_interface_response (NIClient *ni_client, gpointer data, guint size) {
|
||||||
|
printf ("Interface response\n");
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
unsigned char *buffer = (unsigned char *) data;
|
||||||
|
|
||||||
|
uint32_t index, master_index, mtu, type;
|
||||||
|
uint16_t flags;
|
||||||
|
uint8_t bits;
|
||||||
|
guint name_size;
|
||||||
|
char iface_name[128];
|
||||||
|
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
memcpy (&type, &buffer[6], 4);
|
||||||
|
memcpy (&master_index, &buffer[10], 4);
|
||||||
|
memcpy (&mtu, &buffer[14], 4);
|
||||||
|
memcpy (&flags, &buffer[18], 2);
|
||||||
|
bits = buffer[20];
|
||||||
|
|
||||||
|
name_size = buffer[21];
|
||||||
|
memcpy (iface_name, &buffer[22], name_size);
|
||||||
|
iface_name[name_size] = 0;
|
||||||
|
|
||||||
|
/* Insertar y crear */
|
||||||
|
ni_interface = g_object_new (NI_TYPE_INTERFACE, "ni-client", ni_client, "index", index, "wireless", (bits == 0 ? FALSE : TRUE), "type", type, "name", iface_name, "mtu", mtu, "flags", flags, "master-index", master_index, NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert (ni_client->priv->interfaces, GINT_TO_POINTER(index), ni_interface);
|
||||||
|
|
||||||
|
g_signal_emit (ni_client, signals[NEW_INTERFACE], 0, ni_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean ni_client_data_read (NIClient *ni_client, gpointer data, guint size) {
|
||||||
|
unsigned char *buffer = (unsigned char *) data;
|
||||||
|
uint32_t index;
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
|
||||||
|
if (buffer[0] == NET_INADOR_TYPE_EVENT) {
|
||||||
|
switch (buffer[1]) {
|
||||||
|
case NET_INADOR_EVENT_IFACE_ADDED:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
/* Si la interfaz no existe, proccesarla yo, para que se cree el objeto, si la interfaz ya existe, dejar pasar el mensaje */
|
||||||
|
ni_interface = (NIInterface *) g_hash_table_lookup (ni_client->priv->interfaces, GINT_TO_POINTER(index));
|
||||||
|
|
||||||
|
if (ni_interface == NULL) {
|
||||||
|
ni_client_process_interface_response (ni_client, data, size);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NET_INADOR_EVENT_IFACE_REMOVED:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
/* La interfaz fué eliminada, nosotros procesamos este evento */
|
||||||
|
ni_interface = (NIInterface *) g_hash_table_lookup (ni_client->priv->interfaces, GINT_TO_POINTER(index));
|
||||||
|
|
||||||
|
if (ni_interface == NULL) {
|
||||||
|
/* ¿Evento de una interfaz eliminada? Ignorar */
|
||||||
|
} else {
|
||||||
|
g_hash_table_remove (ni_client->priv->interfaces, GINT_TO_POINTER(index));
|
||||||
|
|
||||||
|
g_signal_emit (ni_client, signals[DELETE_INTERFACE], 0, ni_interface);
|
||||||
|
|
||||||
|
g_object_unref (ni_interface);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (buffer[0] == NET_INADOR_TYPE_RESPONSE) {
|
||||||
|
switch (buffer[1]) {
|
||||||
|
case NET_INADOR_RESPONSE_IFACE:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
/* Si la interfaz no existe, proccesarla yo, para que se cree el objeto, si la interfaz ya existe, dejar pasar el mensaje */
|
||||||
|
ni_interface = (NIInterface *) g_hash_table_lookup (ni_client->priv->interfaces, GINT_TO_POINTER(index));
|
||||||
|
|
||||||
|
if (ni_interface == NULL) {
|
||||||
|
ni_client_process_interface_response (ni_client, data, size);
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Procesar los datos aquí */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean ni_client_read_from_socket (GIOChannel *source, GIOCondition condition, gpointer data) {
|
||||||
|
NIClient *ni_client = NI_CLIENT (data);
|
||||||
|
unsigned char buffer[8192];
|
||||||
|
int res;
|
||||||
|
gboolean stop;
|
||||||
|
int g;
|
||||||
|
|
||||||
|
res = recv (ni_client->priv->client_socket, buffer, sizeof (buffer), 0);
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
/* El socket se cerró */
|
||||||
|
close (ni_client->priv->client_socket);
|
||||||
|
ni_client->priv->client_socket = -1;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Data arrival: %i\n", res);
|
||||||
|
for (g = 0; g < res; g++) {
|
||||||
|
printf ("%02hhx ", buffer[g]);
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
/* Tenemos datos, hacer una validación básica */
|
||||||
|
if (buffer[0] != NET_INADOR_TYPE_RESPONSE &&
|
||||||
|
buffer[0] != NET_INADOR_TYPE_RESPONSE_ERROR &&
|
||||||
|
buffer[0] != NET_INADOR_TYPE_EVENT &&
|
||||||
|
buffer[0] != NET_INADOR_TYPE_RESPONSE_LISTING_END) {
|
||||||
|
/* Tipo de paquete inválido */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_emit (ni_client, signals[DATA_READ], 0, (void *) buffer, res, &stop);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean ni_client_foreach_remove_every_interface (gpointer key, gpointer value, gpointer user_data) {
|
||||||
|
NIInterface *ni_interface = NI_INTERFACE (value);
|
||||||
|
|
||||||
|
g_object_unref (ni_interface);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_dispose (GObject *obj) {
|
||||||
|
NIClient *ni_client;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_client = NI_CLIENT (obj);
|
||||||
|
|
||||||
|
/* Recorrer todos los objetos interface para quitarles una referencia y liberarlos */
|
||||||
|
g_hash_table_foreach_remove (ni_client->priv->interfaces, ni_client_foreach_remove_every_interface, NULL);
|
||||||
|
|
||||||
|
if (ni_client->priv->source > 0) {
|
||||||
|
g_source_remove (ni_client->priv->source);
|
||||||
|
ni_client->priv->source = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class->dispose (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_finalize (GObject *obj) {
|
||||||
|
NIClient *ni_client;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_client = NI_CLIENT (obj);
|
||||||
|
|
||||||
|
g_hash_table_destroy (ni_client->priv->interfaces);
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket >= 0) {
|
||||||
|
close (ni_client->priv->client_socket);
|
||||||
|
ni_client->priv->client_socket = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_client->priv->socket_path != NULL) {
|
||||||
|
g_free (ni_client->priv->socket_path);
|
||||||
|
ni_client->priv->socket_path = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent_class->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_client_init (NIClient *ni_client) {
|
||||||
|
NIClientPrivate *priv = ni_client_get_instance_private (ni_client);
|
||||||
|
ni_client->priv = priv;
|
||||||
|
|
||||||
|
priv->client_socket = -1;
|
||||||
|
priv->socket_path = NULL;
|
||||||
|
priv->source = 0;
|
||||||
|
priv->events = NET_INADOR_EVENT_MASK_INTERFACES | NET_INADOR_EVENT_MASK_IP;
|
||||||
|
|
||||||
|
priv->interfaces = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ni_client_update_event_mask (NIClient *ni_client) {
|
||||||
|
unsigned char buffer[8];
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_SET_EVENT_MASK;
|
||||||
|
memcpy (&buffer[2], &ni_client->priv->events, 4);
|
||||||
|
|
||||||
|
send (ni_client->priv->client_socket, buffer, 6, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ni_client_ask_interfaces (NIClient *ni_client) {
|
||||||
|
unsigned char buffer[8];
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_LIST_IFACES;
|
||||||
|
|
||||||
|
send (ni_client->priv->client_socket, buffer, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family) {
|
||||||
|
unsigned char buffer[8];
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = ni_interface_get_index (ni_interface);
|
||||||
|
buffer[0] = NET_INADOR_TYPE_COMMAND;
|
||||||
|
buffer[1] = NET_INADOR_COMMAND_LIST_IP;
|
||||||
|
memcpy (&buffer[2], &index, 4);
|
||||||
|
buffer[6] = family;
|
||||||
|
|
||||||
|
send (ni_client->priv->client_socket, buffer, 7, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean ni_client_connect (NIClient *ni_client) {
|
||||||
|
int s, ret;
|
||||||
|
struct sockaddr_un path_dest;
|
||||||
|
GIOChannel *channel;
|
||||||
|
|
||||||
|
if (ni_client->priv->client_socket >= 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = socket (AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0);
|
||||||
|
|
||||||
|
if (s < 0) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_dest.sun_family = AF_UNIX;
|
||||||
|
strncpy (path_dest.sun_path, ni_client->priv->socket_path, sizeof (path_dest.sun_path));
|
||||||
|
ret = connect (s, (struct sockaddr *) &path_dest, sizeof (path_dest));
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
perror ("Connect");
|
||||||
|
close (s);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tengo socket, instalar vigilante */
|
||||||
|
ni_client->priv->client_socket = s;
|
||||||
|
channel = g_io_channel_unix_new (s);
|
||||||
|
ni_client->priv->source = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, ni_client_read_from_socket, ni_client);
|
||||||
|
g_io_channel_unref (channel);
|
||||||
|
|
||||||
|
/* Pedir eventos */
|
||||||
|
ni_client_update_event_mask (ni_client);
|
||||||
|
|
||||||
|
/* Pedir un listado de interfaces */
|
||||||
|
ni_client_ask_interfaces (ni_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ni_client_disconnect (NIClient *ni_client) {
|
||||||
|
/* TODO: Escribir esto */
|
||||||
|
}
|
||||||
|
|
||||||
|
NIClient *ni_client_new (void) {
|
||||||
|
return g_object_new (NI_TYPE_CLIENT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
NIClient *ni_client_new_with_path (const char *path) {
|
||||||
|
return g_object_new (NI_TYPE_CLIENT, "socket-path", path, NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* ni-client.h
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* inclusion guard */
|
||||||
|
#ifndef __NI_CLIENT_H__
|
||||||
|
#define __NI_CLIENT_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _NIClientClass NIClientClass;
|
||||||
|
typedef struct _NIClient NIClient;
|
||||||
|
typedef struct _NIClientPrivate NIClientPrivate;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type declaration.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Type declaration.
|
||||||
|
*/
|
||||||
|
#define NI_TYPE_CLIENT (ni_client_get_type ())
|
||||||
|
#define NI_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NI_TYPE_CLIENT, NIClient))
|
||||||
|
#define NI_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NI_TYPE_CLIENT, NIClientClass))
|
||||||
|
#define NI_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NI_TYPE_CLIENT))
|
||||||
|
#define NI_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NI_TYPE_CLIENT))
|
||||||
|
#define NI_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NI_TYPE_CLIENT, NIClientClass))
|
||||||
|
|
||||||
|
GType ni_client_get_type (void);
|
||||||
|
|
||||||
|
struct _NIClientClass {
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
gboolean (* data_response) (NIClient *ni_client, gpointer data, guint size);
|
||||||
|
/*gboolean (* data_response_error) (NiClient *ni_client, gpointer data, guint size);*/
|
||||||
|
void (*new_interface) (NIClient *ni_client, gpointer ni_interface);
|
||||||
|
void (*delete_interface) (NIClient *ni_client, gpointer ni_interface);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NIClient {
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
NIClientPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _NIInterface NIInterface;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method definitions.
|
||||||
|
*/
|
||||||
|
NIClient *ni_client_new (void);
|
||||||
|
NIClient *ni_client_new_with_path (const char *path);
|
||||||
|
gboolean ni_client_connect (NIClient *ni_client);
|
||||||
|
void ni_client_ask_ip_interface (NIClient *ni_client, NIInterface *ni_interface, int family);
|
||||||
|
void ni_client_ask_ips (NIClient *ni_client, NIInterface *ni_interface);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NI_CLIENT_H__ */
|
|
@ -0,0 +1,651 @@
|
||||||
|
/*
|
||||||
|
* ni-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 "ni-client.h"
|
||||||
|
#include "ni-interface.h"
|
||||||
|
#include "ni-ip.h"
|
||||||
|
|
||||||
|
#include "../src/network-inador-manager.h"
|
||||||
|
|
||||||
|
struct _NIInterfacePrivate {
|
||||||
|
NIClient *ni_client;
|
||||||
|
|
||||||
|
guint index;
|
||||||
|
gchar *name;
|
||||||
|
guint type;
|
||||||
|
|
||||||
|
guint master_index;
|
||||||
|
guint mtu;
|
||||||
|
guint flags;
|
||||||
|
|
||||||
|
gboolean is_wireless;
|
||||||
|
GList *ip_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_NI_CLIENT = 1,
|
||||||
|
|
||||||
|
PROP_INDEX,
|
||||||
|
PROP_NAME,
|
||||||
|
PROP_TYPE,
|
||||||
|
|
||||||
|
PROP_MASTER_INDEX,
|
||||||
|
|
||||||
|
PROP_MTU,
|
||||||
|
|
||||||
|
PROP_FLAGS,
|
||||||
|
|
||||||
|
PROP_WIRELESS,
|
||||||
|
|
||||||
|
N_PROPERTIES
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NEW_IP,
|
||||||
|
|
||||||
|
DELETE_IP,
|
||||||
|
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
struct _SearchIP {
|
||||||
|
guint family;
|
||||||
|
guint prefix;
|
||||||
|
|
||||||
|
struct_addr local_addr;
|
||||||
|
struct_addr addr;
|
||||||
|
|
||||||
|
gboolean has_local_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (NIInterface, ni_interface, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static gboolean ni_interface_process_interface_response (NIClient *ni_client, unsigned char *buffer, guint size, gpointer data);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static GObject *ni_interface_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties) {
|
||||||
|
GObject *obj;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
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 void ni_interface_constructed (GObject *obj) {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
parent_class->constructed (obj);
|
||||||
|
|
||||||
|
ni_interface = NI_INTERFACE (obj);
|
||||||
|
|
||||||
|
if (ni_interface->priv->ni_client != NULL && ni_interface->priv->index != 0) {
|
||||||
|
/* Conectar la señal de datos */
|
||||||
|
g_signal_connect (ni_interface->priv->ni_client, "packet-read", G_CALLBACK (ni_interface_process_interface_response), ni_interface);
|
||||||
|
|
||||||
|
/* Solicitar listado de IP's */
|
||||||
|
ni_client_ask_ip_interface (ni_interface->priv->ni_client, ni_interface, AF_UNSPEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_dispose (GObject *obj) {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_interface = NI_INTERFACE (obj);
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (ni_interface->priv->ni_client, G_CALLBACK (ni_interface_process_interface_response), ni_interface);
|
||||||
|
|
||||||
|
/* Quitar la referencia hacia el ni_client */
|
||||||
|
g_object_unref (ni_interface->priv->ni_client);
|
||||||
|
|
||||||
|
parent_class->dispose (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_finalize (GObject *obj) {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_interface = NI_INTERFACE (obj);
|
||||||
|
|
||||||
|
/* Nada que hacer, por el momento */
|
||||||
|
|
||||||
|
parent_class->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
NIInterface *ni_interface = NI_INTERFACE (object);
|
||||||
|
g_return_if_fail (NI_IS_INTERFACE (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_NI_CLIENT:
|
||||||
|
ni_interface->priv->ni_client = NI_CLIENT (g_value_get_object (value));
|
||||||
|
g_object_ref (ni_interface->priv->ni_client);
|
||||||
|
break;
|
||||||
|
case PROP_INDEX:
|
||||||
|
ni_interface->priv->index = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_NAME:
|
||||||
|
if (ni_interface->priv->name != NULL) {
|
||||||
|
g_free (ni_interface->priv->name);
|
||||||
|
}
|
||||||
|
ni_interface->priv->name = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
|
case PROP_TYPE:
|
||||||
|
ni_interface->priv->type = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_WIRELESS:
|
||||||
|
ni_interface->priv->is_wireless = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_MTU:
|
||||||
|
ni_interface->priv->mtu = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_MASTER_INDEX:
|
||||||
|
ni_interface->priv->master_index = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
case PROP_FLAGS:
|
||||||
|
ni_interface->priv->flags = g_value_get_uint (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
NIInterface *ni_interface = NI_INTERFACE (object);
|
||||||
|
g_return_if_fail (NI_IS_INTERFACE (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_NI_CLIENT:
|
||||||
|
g_value_set_object (value, ni_interface->priv->ni_client);
|
||||||
|
break;
|
||||||
|
case PROP_INDEX:
|
||||||
|
g_value_set_uint (value, ni_interface->priv->index);
|
||||||
|
break;
|
||||||
|
case PROP_NAME:
|
||||||
|
g_value_set_string (value, ni_interface->priv->name);
|
||||||
|
break;
|
||||||
|
case PROP_TYPE:
|
||||||
|
g_value_set_uint (value, ni_interface->priv->type);
|
||||||
|
break;
|
||||||
|
case PROP_WIRELESS:
|
||||||
|
g_value_set_boolean (value, ni_interface->priv->is_wireless);
|
||||||
|
break;
|
||||||
|
case PROP_MTU:
|
||||||
|
g_value_set_uint (value, ni_interface->priv->mtu);
|
||||||
|
break;
|
||||||
|
case PROP_MASTER_INDEX:
|
||||||
|
g_value_set_uint (value, ni_interface->priv->master_index);
|
||||||
|
break;
|
||||||
|
case PROP_FLAGS:
|
||||||
|
g_value_set_uint (value, ni_interface->priv->flags);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_class_init (NIInterfaceClass *klass) {
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->set_property = ni_interface_set_property;
|
||||||
|
object_class->get_property = ni_interface_get_property;
|
||||||
|
object_class->constructed = ni_interface_constructed;
|
||||||
|
object_class->dispose = ni_interface_dispose;
|
||||||
|
object_class->finalize = ni_interface_finalize;
|
||||||
|
|
||||||
|
obj_properties[PROP_NI_CLIENT] = g_param_spec_object (
|
||||||
|
"ni-client",
|
||||||
|
"Network Inador Client",
|
||||||
|
"The client object",
|
||||||
|
NI_TYPE_CLIENT,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_INDEX] = g_param_spec_uint (
|
||||||
|
"index",
|
||||||
|
"Index",
|
||||||
|
"The index of the interface.",
|
||||||
|
1, G_MAXUINT, 1,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_NAME] = g_param_spec_string (
|
||||||
|
"name",
|
||||||
|
"Name",
|
||||||
|
"Name of the interface",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_TYPE] = g_param_spec_uint (
|
||||||
|
"type",
|
||||||
|
"Interface Type",
|
||||||
|
"Type of the interface.",
|
||||||
|
0, G_MAXUINT, 1,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_MASTER_INDEX] = g_param_spec_uint (
|
||||||
|
"master-index",
|
||||||
|
"Master index",
|
||||||
|
"The index of the master interface",
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_MTU] = g_param_spec_uint (
|
||||||
|
"mtu",
|
||||||
|
"MTU",
|
||||||
|
"The mtu of the interface.",
|
||||||
|
0, G_MAXUINT, 1500,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_FLAGS] = g_param_spec_uint (
|
||||||
|
"flags",
|
||||||
|
"Flags",
|
||||||
|
"The flags of the interface.",
|
||||||
|
0, G_MAXUINT, 0,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
obj_properties[PROP_WIRELESS] = g_param_spec_boolean (
|
||||||
|
"wireless",
|
||||||
|
"Wireless",
|
||||||
|
"Indicates if this interface is wireless",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
|
||||||
|
|
||||||
|
signals[NEW_IP] = g_signal_new ("new-ip",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
NI_TYPE_IP);
|
||||||
|
|
||||||
|
signals[DELETE_IP] = g_signal_new ("delete-ip",
|
||||||
|
G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
g_cclosure_marshal_VOID__OBJECT,
|
||||||
|
G_TYPE_NONE,
|
||||||
|
1,
|
||||||
|
NI_TYPE_IP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint ni_interface_locate_ip (gconstpointer *a, gconstpointer *b) {
|
||||||
|
NIIP *ni_ip = (NIIP *) a;
|
||||||
|
struct _SearchIP *search_ip = (struct _SearchIP *) b;
|
||||||
|
int family_size = 0;
|
||||||
|
|
||||||
|
if (ni_ip_get_family (ni_ip) != search_ip->family) return -1;
|
||||||
|
|
||||||
|
if (search_ip->family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (search_ip->family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_ip_get_prefix (ni_ip) != search_ip->prefix) return -1;
|
||||||
|
|
||||||
|
if (memcmp (ni_ip_get_addr (ni_ip), &search_ip->addr, family_size) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_ip_has_local (ni_ip) != search_ip->has_local_addr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (search_ip->has_local_addr) {
|
||||||
|
if (memcmp (ni_ip_get_local_addr (ni_ip), &search_ip->local_addr, family_size) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_process_interface_update (NIInterface *ni_interface, gpointer data, guint size) {
|
||||||
|
unsigned char *buffer = (unsigned char *) data;
|
||||||
|
|
||||||
|
uint32_t master_index, mtu;
|
||||||
|
uint16_t flags;
|
||||||
|
guint name_size;
|
||||||
|
char iface_name[128];
|
||||||
|
|
||||||
|
memcpy (&master_index, &buffer[10], 4);
|
||||||
|
memcpy (&mtu, &buffer[14], 4);
|
||||||
|
memcpy (&flags, &buffer[18], 2);
|
||||||
|
|
||||||
|
name_size = buffer[21];
|
||||||
|
memcpy (iface_name, &buffer[22], name_size);
|
||||||
|
iface_name[name_size] = 0;
|
||||||
|
|
||||||
|
g_object_freeze_notify (G_OBJECT (ni_interface));
|
||||||
|
if (ni_interface->priv->name == NULL) {
|
||||||
|
ni_interface->priv->name = g_strdup (iface_name);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_NAME]);
|
||||||
|
} else if (strcmp (ni_interface->priv->name, iface_name) != 0) {
|
||||||
|
g_free (ni_interface->priv->name);
|
||||||
|
|
||||||
|
ni_interface->priv->name = g_strdup (iface_name);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_NAME]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->master_index != master_index) {
|
||||||
|
ni_interface->priv->master_index = master_index;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_MASTER_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->mtu != mtu) {
|
||||||
|
ni_interface->priv->master_index = master_index;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_MASTER_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->flags != flags) {
|
||||||
|
ni_interface->priv->flags = flags;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_FLAGS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (ni_interface));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_process_ip_added (NIInterface *ni_interface, gpointer data, guint size) {
|
||||||
|
unsigned char *buffer = (unsigned char *) data;
|
||||||
|
uint32_t index, flags;
|
||||||
|
guint family, prefix, bits, scope, pos;
|
||||||
|
gint family_size = 0;
|
||||||
|
gboolean has_local_addr = FALSE, has_brd_addr = FALSE;
|
||||||
|
NIIP *ni_ip;
|
||||||
|
struct_addr addr, local_addr, brd_addr;
|
||||||
|
GList *g;
|
||||||
|
|
||||||
|
family = buffer[6];
|
||||||
|
prefix = buffer[7];
|
||||||
|
bits = buffer[8];
|
||||||
|
scope = buffer[9];
|
||||||
|
|
||||||
|
if (bits & 0x01) has_local_addr = TRUE;
|
||||||
|
if (bits & 0x02) has_brd_addr = TRUE;
|
||||||
|
memcpy (&flags, &buffer[10], 4);
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&addr, &buffer[14], family_size);
|
||||||
|
|
||||||
|
pos = 14 + family_size;
|
||||||
|
if (has_local_addr) {
|
||||||
|
memcpy (&local_addr, &buffer[pos], family_size);
|
||||||
|
pos += family_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_brd_addr) {
|
||||||
|
memcpy (&brd_addr, &buffer[pos], family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ni_ip = ni_ip_new (ni_interface, family, prefix, &addr, flags, scope, has_local_addr, (has_local_addr ? &local_addr : NULL), has_brd_addr, (has_brd_addr ? &brd_addr : NULL));
|
||||||
|
|
||||||
|
ni_interface->priv->ip_list = g_list_append (ni_interface->priv->ip_list, ni_ip);
|
||||||
|
|
||||||
|
printf ("Emitiendo signal de IP-addr\n");
|
||||||
|
g_signal_emit (ni_interface, signals[NEW_IP], 0, ni_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_interface_process_ip_removed (NIInterface *ni_interface, gpointer data, guint size) {
|
||||||
|
unsigned char *buffer = (unsigned char *) data;
|
||||||
|
struct _SearchIP search_ip;
|
||||||
|
gint family_size = 0;
|
||||||
|
guint bits, pos;
|
||||||
|
GList *g;
|
||||||
|
NIIP *ni_ip;
|
||||||
|
|
||||||
|
search_ip.family = buffer[6];
|
||||||
|
search_ip.prefix = buffer[7];
|
||||||
|
bits = buffer[8];
|
||||||
|
|
||||||
|
if (bits & 0x01) search_ip.has_local_addr = TRUE;
|
||||||
|
|
||||||
|
if (search_ip.family == AF_INET) {
|
||||||
|
family_size = sizeof (struct in_addr);
|
||||||
|
} else if (search_ip.family == AF_INET6) {
|
||||||
|
family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&search_ip.addr, &buffer[10], family_size);
|
||||||
|
|
||||||
|
pos = 10 + family_size;
|
||||||
|
if (search_ip.has_local_addr) {
|
||||||
|
memcpy (&search_ip.local_addr, &buffer[pos], family_size);
|
||||||
|
pos += family_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Localizar la IP y eliminarla */
|
||||||
|
g = g_list_find_custom (ni_interface->priv->ip_list, &search_ip, (GCompareFunc) ni_interface_locate_ip);
|
||||||
|
|
||||||
|
if (g == NULL) {
|
||||||
|
/* ¿IP eliminada sin que exista? Super error */
|
||||||
|
} else {
|
||||||
|
ni_ip = (NIIP *) g->data;
|
||||||
|
ni_interface->priv->ip_list = g_list_remove (ni_interface->priv->ip_list, g->data);
|
||||||
|
|
||||||
|
/* Ahora, ya desligado, emitir la señal */
|
||||||
|
g_signal_emit (ni_interface, signals[DELETE_IP], 0, ni_ip);
|
||||||
|
|
||||||
|
g_object_unref (ni_ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean ni_interface_process_interface_response (NIClient *ni_client, unsigned char *buffer, guint size, gpointer user_data) {
|
||||||
|
NIInterface *ni_interface = (NIInterface *) user_data;
|
||||||
|
uint32_t index;
|
||||||
|
|
||||||
|
if (buffer[0] == NET_INADOR_TYPE_EVENT) {
|
||||||
|
switch (buffer[1]) {
|
||||||
|
case NET_INADOR_EVENT_IPADDR_ADDED:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (index != ni_interface->priv->index) {
|
||||||
|
/* Mensaje de IP, pero no para mí, dejar pasar */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ni_interface_process_ip_added (ni_interface, buffer, size);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_EVENT_IFACE_ADDED:
|
||||||
|
/* Mensaje de actualización de mi estado */
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (index != ni_interface->priv->index) {
|
||||||
|
/* Mensaje de la interfaz, pero no para mí, dejar pasar */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ni_interface_process_interface_update (ni_interface, buffer, size);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_EVENT_IPADDR_REMOVED:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (index != ni_interface->priv->index) {
|
||||||
|
/* Mensaje de la interfaz, pero no para mí, dejar pasar */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ni_interface_process_ip_removed (ni_interface, buffer, size);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (buffer[0] == NET_INADOR_TYPE_RESPONSE) {
|
||||||
|
switch (buffer[1]) {
|
||||||
|
case NET_INADOR_RESPONSE_IPADDR:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (index != ni_interface->priv->index) {
|
||||||
|
/* Mensaje de IP, pero no para mí, dejar pasar */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
printf ("Response IP addr sobre interfaz\n");
|
||||||
|
ni_interface_process_ip_added (ni_interface, buffer, size);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
case NET_INADOR_RESPONSE_IFACE:
|
||||||
|
memcpy (&index, &buffer[2], 4);
|
||||||
|
|
||||||
|
if (index != ni_interface->priv->index) {
|
||||||
|
/* Mensaje de la interfaz, pero no para mí, dejar pasar */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ni_interface_process_interface_update (ni_interface, buffer, size);
|
||||||
|
return TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE; /* Que se siga procesando */
|
||||||
|
}
|
||||||
|
|
||||||
|
guint ni_interface_get_index (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), 0);
|
||||||
|
return ni_interface->priv->index;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *ni_interface_get_name (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), NULL);
|
||||||
|
return ni_interface->priv->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint ni_interface_get_iface_type (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), 0);
|
||||||
|
return ni_interface->priv->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean ni_interface_is_wireless (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), FALSE);
|
||||||
|
return ni_interface->priv->is_wireless;
|
||||||
|
}
|
||||||
|
|
||||||
|
NIClient *ni_interface_get_client (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), NULL);
|
||||||
|
return ni_interface->priv->ni_client;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GList *ni_interface_get_ip_list (NIInterface *ni_interface) {
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), NULL);
|
||||||
|
return ni_interface->priv->ip_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void ni_interface_consume_values (NIInterface *ni_interface, char *name, gint arp_type, guint master_index, guint mtu, guint flags) {
|
||||||
|
g_object_freeze_notify (G_OBJECT (ni_interface));
|
||||||
|
|
||||||
|
if (ni_interface->priv->name == NULL) {
|
||||||
|
ni_interface->priv->name = g_strdup (name);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_NAME]);
|
||||||
|
} else if (strcmp (ni_interface->priv->name, name) != 0) {
|
||||||
|
g_free (ni_interface->priv->name);
|
||||||
|
|
||||||
|
ni_interface->priv->name = g_strdup (name);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_NAME]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ni_interface->priv->arp_type != arp_type) {
|
||||||
|
ni_interface->priv->arp_type = arp_type;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_ARP_TYPE]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->master_index != master_index) {
|
||||||
|
ni_interface->priv->master_index = master_index;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_MASTER_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->mtu != mtu) {
|
||||||
|
ni_interface->priv->master_index = master_index;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_MASTER_INDEX]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ni_interface->priv->flags != flags) {
|
||||||
|
ni_interface->priv->flags = flags;
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (ni_interface), obj_properties[PROP_FLAGS]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_thaw_notify (G_OBJECT (ni_interface));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void ni_interface_init (NIInterface *ni_interface) {
|
||||||
|
NIInterfacePrivate *priv = ni_interface_get_instance_private (ni_interface);
|
||||||
|
ni_interface->priv = priv;
|
||||||
|
|
||||||
|
/* initialize all public and private members to reasonable default values.
|
||||||
|
* They are all automatically initialized to 0 to begin with. */
|
||||||
|
priv->ni_client = NULL;
|
||||||
|
priv->index = 0;
|
||||||
|
priv->name = NULL;
|
||||||
|
priv->type = 0;
|
||||||
|
priv->is_wireless = FALSE;
|
||||||
|
priv->master_index = 0;
|
||||||
|
priv->mtu = 0;
|
||||||
|
priv->flags = 0;
|
||||||
|
priv->ip_list = NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* ni-interface.h
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* inclusion guard */
|
||||||
|
#ifndef __NI_INTERFACE_H__
|
||||||
|
#define __NI_INTERFACE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _NIInterfaceClass NIInterfaceClass;
|
||||||
|
typedef struct _NIInterface NIInterface;
|
||||||
|
typedef struct _NIInterfacePrivate NIInterfacePrivate;
|
||||||
|
|
||||||
|
typedef struct _NIClient NIClient;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type declaration.
|
||||||
|
*/
|
||||||
|
#define NI_TYPE_INTERFACE (ni_interface_get_type ())
|
||||||
|
#define NI_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NI_TYPE_INTERFACE, NIInterface))
|
||||||
|
#define NI_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NI_TYPE_INTERFACE, NIInterfaceClass))
|
||||||
|
#define NI_IS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NI_TYPE_INTERFACE))
|
||||||
|
#define NI_IS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NI_TYPE_INTERFACE))
|
||||||
|
#define NI_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NI_TYPE_INTERFACE, NIInterfaceClass))
|
||||||
|
|
||||||
|
GType ni_interface_get_type (void);
|
||||||
|
|
||||||
|
struct _NIInterfaceClass {
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NIInterface {
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
NIInterfacePrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
guint ni_interface_get_index (NIInterface *ni_interface);
|
||||||
|
const gchar *ni_interface_get_name (NIInterface *ni_interface);
|
||||||
|
guint ni_interface_get_iface_type (NIInterface *ni_interface);
|
||||||
|
gboolean ni_interface_is_wireless (NIInterface *ni_interface);
|
||||||
|
NIClient *ni_interface_get_client (NIInterface *ni_interface);
|
||||||
|
const GList *ni_interface_get_ip_list (NIInterface *ni_interface);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NI_INTERFACE_H__ */
|
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* ni-ip.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 "ni-interface.h"
|
||||||
|
#include "ni-ip.h"
|
||||||
|
|
||||||
|
#include "../src/network-inador-manager.h"
|
||||||
|
|
||||||
|
struct _NIIPPrivate {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
|
||||||
|
guint family;
|
||||||
|
gint family_size;
|
||||||
|
guint prefix;
|
||||||
|
|
||||||
|
struct_addr local_addr;
|
||||||
|
struct_addr addr;
|
||||||
|
struct_addr brd_addr;
|
||||||
|
|
||||||
|
gboolean has_brd;
|
||||||
|
gboolean has_local;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
unsigned char scope;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_NI_INTERFACE = 1,
|
||||||
|
|
||||||
|
N_PROPERTIES
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_PRIVATE (NIIP, ni_ip, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
|
||||||
|
|
||||||
|
static void ni_ip_dispose (GObject *obj) {
|
||||||
|
NIIP *ni_ip;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_ip = NI_IP (obj);
|
||||||
|
|
||||||
|
/* Quitar la referencia hacia el ni_interface */
|
||||||
|
g_object_unref (ni_ip->priv->ni_interface);
|
||||||
|
|
||||||
|
parent_class->dispose (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_ip_finalize (GObject *obj) {
|
||||||
|
NIIP *ni_ip;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
ni_ip = NI_IP (obj);
|
||||||
|
|
||||||
|
/* Nada que hacer, por el momento */
|
||||||
|
|
||||||
|
parent_class->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_ip_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
|
||||||
|
NIIP *ni_ip = NI_IP (object);
|
||||||
|
g_return_if_fail (NI_IS_IP (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_NI_INTERFACE:
|
||||||
|
ni_ip->priv->ni_interface = NI_INTERFACE (g_value_get_object (value));
|
||||||
|
g_object_ref (ni_ip->priv->ni_interface);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_ip_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
|
||||||
|
NIIP *ni_ip = NI_IP (object);
|
||||||
|
g_return_if_fail (NI_IS_IP (object));
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_NI_INTERFACE:
|
||||||
|
g_value_set_object (value, ni_ip->priv->ni_interface);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_ip_class_init (NIIPClass *klass) {
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->set_property = ni_ip_set_property;
|
||||||
|
object_class->get_property = ni_ip_get_property;
|
||||||
|
object_class->dispose = ni_ip_dispose;
|
||||||
|
object_class->finalize = ni_ip_finalize;
|
||||||
|
|
||||||
|
obj_properties[PROP_NI_INTERFACE] = g_param_spec_object (
|
||||||
|
"ni-interface",
|
||||||
|
"Network Inador 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ni_ip_init (NIIP *ni_ip) {
|
||||||
|
NIIPPrivate *priv = ni_ip_get_instance_private (ni_ip);
|
||||||
|
ni_ip->priv = priv;
|
||||||
|
|
||||||
|
/* initialize all public and private members to reasonable default values.
|
||||||
|
* They are all automatically initialized to 0 to begin with. */
|
||||||
|
priv->ni_interface = NULL;
|
||||||
|
priv->prefix = 0;
|
||||||
|
priv->family = AF_UNSPEC;
|
||||||
|
priv->has_brd = FALSE;
|
||||||
|
priv->has_local = FALSE;
|
||||||
|
priv->flags = 0;
|
||||||
|
priv->scope = 0;
|
||||||
|
|
||||||
|
memset (&priv->addr, 0, sizeof (priv->addr));
|
||||||
|
memset (&priv->local_addr, 0, sizeof (priv->local_addr));
|
||||||
|
memset (&priv->brd_addr, 0, sizeof (priv->brd_addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Los métodos getters */
|
||||||
|
gboolean ni_ip_has_local (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), FALSE);
|
||||||
|
|
||||||
|
return ni_ip->priv->has_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean ni_ip_has_brd (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), FALSE);
|
||||||
|
|
||||||
|
return ni_ip->priv->has_local;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint ni_ip_get_family (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
|
||||||
|
|
||||||
|
return ni_ip->priv->family;
|
||||||
|
}
|
||||||
|
|
||||||
|
guint ni_ip_get_prefix (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
|
||||||
|
|
||||||
|
return ni_ip->priv->prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ni_ip_get_flags (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
|
||||||
|
|
||||||
|
return ni_ip->priv->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char ni_ip_get_scope (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), 0);
|
||||||
|
|
||||||
|
return ni_ip->priv->scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct_addr *ni_ip_get_addr (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), NULL);
|
||||||
|
|
||||||
|
return &ni_ip->priv->addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct_addr *ni_ip_get_local_addr (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), NULL);
|
||||||
|
|
||||||
|
return &ni_ip->priv->local_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct_addr *ni_ip_get_brd_addr (NIIP *ni_ip) {
|
||||||
|
g_return_val_if_fail (NI_IS_IP (ni_ip), NULL);
|
||||||
|
|
||||||
|
return &ni_ip->priv->brd_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NIIP *ni_ip_new (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) {
|
||||||
|
NIIP *ni_ip;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NI_IS_INTERFACE (ni_interface), NULL);
|
||||||
|
|
||||||
|
ni_ip = g_object_new (NI_TYPE_IP, "ni-interface", ni_interface, NULL);
|
||||||
|
|
||||||
|
/* Establecer y copiar los valores */
|
||||||
|
ni_ip->priv->family = family;
|
||||||
|
ni_ip->priv->prefix = prefix;
|
||||||
|
ni_ip->priv->has_local = has_local;
|
||||||
|
ni_ip->priv->has_brd = has_brd;
|
||||||
|
ni_ip->priv->flags = flags;
|
||||||
|
ni_ip->priv->scope = scope;
|
||||||
|
|
||||||
|
if (family == AF_INET) {
|
||||||
|
ni_ip->priv->family_size = sizeof (struct in_addr);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
ni_ip->priv->family_size = sizeof (struct in6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (&ni_ip->priv->addr, addr, ni_ip->priv->family_size);
|
||||||
|
if (has_local) {
|
||||||
|
memcpy (&ni_ip->priv->local_addr, local_addr, ni_ip->priv->family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_brd) {
|
||||||
|
memcpy (&ni_ip->priv->brd_addr, brd_addr, ni_ip->priv->family_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ni_ip;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* ni-interface.h
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* inclusion guard */
|
||||||
|
#ifndef __NI_IP_H__
|
||||||
|
#define __NI_IP_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} struct_addr;
|
||||||
|
|
||||||
|
typedef struct _NIIPClass NIIPClass;
|
||||||
|
typedef struct _NIIP NIIP;
|
||||||
|
typedef struct _NIIPPrivate NIIPPrivate;
|
||||||
|
|
||||||
|
typedef struct _NIInterface NIInterface;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type declaration.
|
||||||
|
*/
|
||||||
|
#define NI_TYPE_IP (ni_ip_get_type ())
|
||||||
|
#define NI_IP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NI_TYPE_IP, NIIP))
|
||||||
|
#define NI_IP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NI_TYPE_IP, NIIPClass))
|
||||||
|
#define NI_IS_IP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NI_TYPE_IP))
|
||||||
|
#define NI_IS_IP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NI_TYPE_IP))
|
||||||
|
#define NI_IP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NI_TYPE_IP, NIIPClass))
|
||||||
|
|
||||||
|
GType ni_ip_get_type (void);
|
||||||
|
|
||||||
|
struct _NIIPClass {
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NIIP {
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
NIIPPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
gboolean ni_ip_has_local (NIIP *ni_ip);
|
||||||
|
gboolean ni_ip_has_brd (NIIP *ni_ip);
|
||||||
|
guint ni_ip_get_family (NIIP *ni_ip);
|
||||||
|
guint ni_ip_get_prefix (NIIP *ni_ip);
|
||||||
|
uint32_t ni_ip_get_flags (NIIP *ni_ip);
|
||||||
|
unsigned char ni_ip_get_scope (NIIP *ni_ip);
|
||||||
|
const struct_addr *ni_ip_get_addr (NIIP *ni_ip);
|
||||||
|
const struct_addr *ni_ip_get_local_addr (NIIP *ni_ip);
|
||||||
|
const struct_addr *ni_ip_get_brd_addr (NIIP *ni_ip);
|
||||||
|
|
||||||
|
NIIP *ni_ip_new (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);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NI_IP_H__ */
|
|
@ -0,0 +1 @@
|
||||||
|
BOOLEAN:POINTER,UINT
|
|
@ -0,0 +1,416 @@
|
||||||
|
/*
|
||||||
|
* 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 "ni-window-interface.h"
|
||||||
|
|
||||||
|
#include "ni-client.h"
|
||||||
|
#include "ni-interface.h"
|
||||||
|
#include "ni-ip.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IP_FAMILY,
|
||||||
|
IP_ADDR,
|
||||||
|
IP_PREFIX,
|
||||||
|
IP_LOCAL_ADDR,
|
||||||
|
|
||||||
|
IP_OBJECT,
|
||||||
|
|
||||||
|
NUM_COLS_IP
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NIWindowInterfacePrivate {
|
||||||
|
NIInterface *ni_interface;
|
||||||
|
|
||||||
|
GtkWidget *vbox, *notebook;
|
||||||
|
GtkWidget *vbox_ipv4, *vbox_ipv6;
|
||||||
|
GtkListStore *ipv4_store, *ipv6_store;
|
||||||
|
GtkWidget *tree_ipv4, *tree_ipv6;
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
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 void ni_window_interface_ip_addr_add (NIWindowInterface *window_iface, NIIP *ni_ip) {
|
||||||
|
GtkTreeIter iter;
|
||||||
|
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 (window_iface->priv->ipv4_store, &iter, -1);
|
||||||
|
gtk_list_store_set (window_iface->priv->ipv4_store, &iter, IP_STORE_COL_MAIN_IP, buffer, IP_STORE_COL_OBJECT, ni_ip, -1);
|
||||||
|
} else if (family == AF_INET6) {
|
||||||
|
gtk_list_store_insert (window_iface->priv->ipv6_store, &iter, -1);
|
||||||
|
gtk_list_store_set (window_iface->priv->ipv6_store, &iter, IP_STORE_COL_MAIN_IP, buffer, IP_STORE_COL_OBJECT, ni_ip, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_ip_add_cb (NIInterface *ni_interface, NIIP *ni_ip, gpointer data) {
|
||||||
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (data);
|
||||||
|
ni_window_interface_ip_addr_add (window_iface, ni_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_ip_del_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);
|
||||||
|
g_free (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_constructed (GObject *obj) {
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
NIWindowInterface *window_iface = NI_WINDOW_INTERFACE (obj);
|
||||||
|
const GList *ip_list, *g;
|
||||||
|
NIIP *ni_ip;
|
||||||
|
gchar *name;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* 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_ip_addr_add (window_iface, ni_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_ip_add_cb), window_iface);
|
||||||
|
g_signal_connect (window_iface->priv->ni_interface, "delete-ip", G_CALLBACK (ni_window_interface_ip_del_cb), window_iface);
|
||||||
|
g_signal_connect (window_iface->priv->ni_interface, "notify::name", G_CALLBACK (ni_window_interface_changed_name_cb), window_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_dispose (GObject *obj) {
|
||||||
|
NIWindowInterface *window_iface;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
window_iface = NI_WINDOW_INTERFACE (obj);
|
||||||
|
|
||||||
|
g_object_unref (window_iface->priv->ni_interface);
|
||||||
|
|
||||||
|
parent_class->dispose (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ni_window_interface_finalize (GObject *obj) {
|
||||||
|
NIWindowInterface *window_iface;
|
||||||
|
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
window_iface = NI_WINDOW_INTERFACE (obj);
|
||||||
|
|
||||||
|
/* Nada que hacer, por el momento */
|
||||||
|
|
||||||
|
parent_class->finalize (obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
object_class->finalize = ni_window_interface_finalize;
|
||||||
|
|
||||||
|
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 (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 ("Dirección", renderer, "text", IP_STORE_COL_MAIN_IP, NULL);
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (*tree), column);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (scrolled), *tree);
|
||||||
|
|
||||||
|
return scrolled;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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");
|
||||||
|
g_signal_connect (window, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
|
||||||
|
|
||||||
|
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 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 (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);
|
||||||
|
|
||||||
|
button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 (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);
|
||||||
|
|
||||||
|
button = gtk_button_new_from_icon_name ("list-remove", GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* ni-window-interface.h
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* inclusion guard */
|
||||||
|
#ifndef __NI_WINDOW_INTERFACE_H__
|
||||||
|
#define __NI_WINDOW_INTERFACE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include "ni-interface.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _NIWindowInterfaceClass NIWindowInterfaceClass;
|
||||||
|
typedef struct _NIWindowInterface NIWindowInterface;
|
||||||
|
typedef struct _NIWindowInterfacePrivate NIWindowInterfacePrivate;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Type declaration.
|
||||||
|
*/
|
||||||
|
#define NI_TYPE_WINDOW_INTERFACE (ni_window_interface_get_type ())
|
||||||
|
#define NI_WINDOW_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NI_TYPE_WINDOW_INTERFACE, NIWindowInterface))
|
||||||
|
#define NI_WINDOW_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NI_TYPE_WINDOW_INTERFACE, NIWindowInterfaceClass))
|
||||||
|
#define NI_IS_WINDOW_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NI_TYPE_WINDOW_INTERFACE))
|
||||||
|
#define NI_IS_WINDOW_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NI_TYPE_WINDOW_INTERFACE))
|
||||||
|
#define NI_WINDOW_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NI_TYPE_WINDOW_INTERFACE, NIWindowInterfaceClass))
|
||||||
|
|
||||||
|
GType ni_window_interface_get_type (void);
|
||||||
|
|
||||||
|
struct _NIWindowInterfaceClass {
|
||||||
|
GtkWindowClass parent_class;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NIWindowInterface {
|
||||||
|
GtkWindow parent_instance;
|
||||||
|
|
||||||
|
NIWindowInterfacePrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Method definitions.
|
||||||
|
*/
|
||||||
|
GtkWidget* ni_window_interface_new (NIInterface *ni_interface);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __NI_WINDOW_INTERFACE_H__ */
|
|
@ -36,11 +36,16 @@ esac
|
||||||
|
|
||||||
GLIB_VERSION=2.50
|
GLIB_VERSION=2.50
|
||||||
LIBNL_VERSION=0.29
|
LIBNL_VERSION=0.29
|
||||||
|
GTK3_VERSION=3.24
|
||||||
|
|
||||||
AC_MSG_CHECKING([if you have Glib installed on your system])
|
AC_MSG_CHECKING([if you have Glib installed on your system])
|
||||||
PKG_CHECK_EXISTS([glib-2.0 >= $GLIB_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([Glib not found in your system])])
|
PKG_CHECK_EXISTS([glib-2.0 >= $GLIB_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([Glib not found in your system])])
|
||||||
PKG_CHECK_MODULES(GLIB, [glib-2.0 >= $GLIB_VERSION], [], [])
|
PKG_CHECK_MODULES(GLIB, [glib-2.0 >= $GLIB_VERSION], [], [])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if you have GTK+3 installed on your system])
|
||||||
|
PKG_CHECK_EXISTS([gtk+-3.0 >= $GTK3_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([GTK+3 not found in your system])])
|
||||||
|
PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= $GTK3_VERSION], [], [])
|
||||||
|
|
||||||
AC_MSG_CHECKING([if you have libnl-3 installed on your system])
|
AC_MSG_CHECKING([if you have libnl-3 installed on your system])
|
||||||
PKG_CHECK_EXISTS([libnl-3.0 >= LIBNL_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([libnl-3 not found in your system])])
|
PKG_CHECK_EXISTS([libnl-3.0 >= LIBNL_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([libnl-3 not found in your system])])
|
||||||
PKG_CHECK_MODULES(LIBNL3, [libnl-3.0 >= $LIBNL_VERSION], [], [])
|
PKG_CHECK_MODULES(LIBNL3, [libnl-3.0 >= $LIBNL_VERSION], [], [])
|
||||||
|
@ -49,11 +54,15 @@ AC_MSG_CHECKING([if you have libnl-gen-3 installed on your system])
|
||||||
PKG_CHECK_EXISTS([libnl-genl-3.0 >= LIBNL_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([libnl-gen-3 not found in your system])])
|
PKG_CHECK_EXISTS([libnl-genl-3.0 >= LIBNL_VERSION], [AC_MSG_RESULT([yes])], [AC_MSG_FAILURE([libnl-gen-3 not found in your system])])
|
||||||
PKG_CHECK_MODULES(LIBNLGEN3, [libnl-genl-3.0 >= $LIBNL_VERSION], [], [])
|
PKG_CHECK_MODULES(LIBNLGEN3, [libnl-genl-3.0 >= $LIBNL_VERSION], [], [])
|
||||||
|
|
||||||
|
GLIB_GENMARSHAL="$($PKG_CONFIG --variable=glib_genmarshal glib-2.0)"
|
||||||
|
AC_SUBST([GLIB_GENMARSHAL])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
client-gtk/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
])
|
])
|
||||||
# src/dhcpc/Makefile
|
# src/dhcpc/Makefile
|
||||||
|
|
Loading…
Reference in New Issue