Reestructuro tipos de las interfaces.

master
Félix Arreola Rodríguez 2021-09-04 23:26:39 -05:00
parent 89570f4139
commit 9dac3ca7ed
7 changed files with 290 additions and 37 deletions

View File

@ -1,11 +1,13 @@
# Automake file for NetworkInador
bin_PROGRAMS = network-inador
network_inador_SOURCES = main.c common.h \
network_inador_SOURCES = main.c \
common.h link-types.h \
netlink-events.c netlink-events.h \
interfaces.c interfaces.h \
ip-address.c ip-address.h \
bridge.c bridge.h \
manager.c manager.h \
wireless_if.c wireless_if.h \
wireless_bss.c wireless_bss.h

View File

@ -43,6 +43,7 @@
typedef struct _NetworkInadorHandle NetworkInadorHandle;
typedef struct _NetworkInadorManager NetworkInadorManager;
typedef struct _Interface Interface;
typedef union {
struct in_addr v4;
@ -63,6 +64,8 @@ typedef struct _IPAddr {
uint32_t flags;
unsigned char scope;
Interface *iface;
} IPAddr;
#define SSID_MAX_LEN 32
@ -104,10 +107,11 @@ typedef struct _WirelessInfo {
GList *aps;
} WirelessInfo;
typedef struct _Interface {
struct _Interface {
uint32_t index;
char name[IFNAMSIZ];
uint16_t ifi_type;
uint32_t link_type;
uint16_t arp_type;
unsigned char real_hw[ETHER_ADDR_LEN * 2 + 1];
/* Para las interfaces dentro de un bridge */
@ -126,7 +130,7 @@ typedef struct _Interface {
char wireless_protocol[IFNAMSIZ];
/* Tipo */
char tipo_string[IFNAMSIZ];
char rtnl_type[IFNAMSIZ];
GList *address;
@ -134,7 +138,25 @@ typedef struct _Interface {
/* Información wireless */
WirelessInfo *wireless;
} Interface;
};
/* Para los clientes y sus respectivos eventos */
typedef struct {
int fd;
/* Los eventos que quieren ser recibidos en este cliente */
uint32_t wanted_events;
guint source;
NetworkInadorManager *manager;
} ManagerClientInfo;
struct _NetworkInadorManager {
int socket;
guint source;
GList *connected_client_list;
NetworkInadorHandle *handle;
};
/* Para vigilar eventos */
typedef struct _netlink_event_pair {
@ -142,10 +164,12 @@ typedef struct _netlink_event_pair {
guint source;
} NetlinkEventPair;
typedef struct {
struct _NetworkInadorHandle {
GList *interfaces;
//Routev4 *rtable_v4;
NetworkInadorManager *manager;
struct nl_sock * nl_sock_route;
struct nl_sock * nl_sock_nl80211;
@ -153,7 +177,7 @@ typedef struct {
NetlinkEventPair nl80211_scan;
NetlinkEventPair nl80211_scan_results;
} NetworkInadorHandle;
};
#endif /* __COMMON_H__ */

View File

@ -25,7 +25,7 @@
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <net/if_arp.h>
#include <linux/if_arp.h>
#include <gmodule.h>
@ -33,6 +33,9 @@
#include "interfaces.h"
#include "ip-address.h"
#include "wireless_if.h"
#include "manager.h"
#include "link-types.h"
static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, int first_time);
@ -44,15 +47,60 @@ int interface_receive_message_newlink (struct nl_msg *msg, void *arg) {
return _interfaces_receive_message_interface (msg, arg, FALSE);
}
static uint32_t interfaces_check_link_type (Interface *iface) {
int g;
/* Revisar primero el INFO_KIND */
for (g = 0; g < (sizeof (linktypes) / sizeof (linktypes[0])); g++) {
if (linktypes[g].rtnl_type == NULL) continue;
if (strcmp (iface->rtnl_type, linktypes[g].rtnl_type) == 0) {
return linktypes->link_type;
}
}
if (iface->arp_type == ARPHRD_LOOPBACK)
return NI_LINK_TYPE_LOOPBACK;
else if (iface->arp_type == ARPHRD_INFINIBAND)
return NI_LINK_TYPE_INFINIBAND;
else if (iface->arp_type == ARPHRD_SIT)
return NI_LINK_TYPE_SIT;
else if (iface->arp_type == ARPHRD_TUNNEL6)
return NI_LINK_TYPE_IP6TNL;
else if (iface->arp_type == ARPHRD_PPP)
return NI_LINK_TYPE_PPP;
else if (iface->arp_type == ARPHRD_IEEE802154)
return NI_LINK_TYPE_WPAN;
else if (iface->arp_type == ARPHRD_6LOWPAN)
return NI_LINK_TYPE_6LOWPAN;
if (iface->is_wireless) {
return NI_LINK_TYPE_WIFI;
}
if (iface->arp_type == ARPHRD_ETHER) {
if (strncmp (iface->name, "rmnet", 5) == 0 ||
strncmp (iface->name, "rev_rmnet", 9) == 0 ||
strncmp (iface->name, "ccmni", 5) == 0)
return NI_LINK_TYPE_WWAN_NET;
return NI_LINK_TYPE_ETHERNET;
}
return NI_LINK_TYPE_UNKNOWN;
}
static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg, int first_time) {
struct nlmsghdr *reply;
struct ifinfomsg *iface_msg;
int remaining;
struct nlattr *attr;
NetworkInadorHandle *handle = (NetworkInadorHandle *) arg;
int was_new = 0;
int was_new = 0, was_update = 0;
uint32_t new_flags;
Interface *iface;
uint32_t u32data;
char temp_name[128];
reply = nlmsg_hdr (msg);
@ -64,7 +112,8 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
if (iface == NULL) {
/* Crear esta interfaz */
iface = g_new0 (Interface, 1);
iface = malloc (sizeof (Interface));
memset (iface, 0, sizeof (Interface));
handle->interfaces = g_list_append (handle->interfaces, iface);
@ -85,25 +134,24 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
}
printf ("Interface %d agregada a la interfaz %d (bridge)\n", iface->index, iface->master_index);
/* Generar EVENTO AQUI */
/* TODO: Generar EVENTO AQUI */
return NL_SKIP;
}
printf ("Interface %d ifi_type: %d\n", iface_msg->ifi_index, iface_msg->ifi_type);
iface->ifi_type = iface_msg->ifi_type;
/* TODO: Checar aquí cambio de flags */
printf ("Interface %d ifi_flags: %d\n", iface_msg->ifi_index, iface_msg->ifi_flags);
iface->flags = iface_msg->ifi_flags;
iface->arp_type = iface_msg->ifi_type;
new_flags = iface_msg->ifi_flags;
iface->index = iface_msg->ifi_index;
nlmsg_for_each_attr(attr, reply, sizeof (struct ifinfomsg), remaining) {
switch (nla_type (attr)) {
//nla_len (Attr);
case IFLA_IFNAME:
printf ("Interface %d : %s\n", iface_msg->ifi_index, (char *) nla_data (attr));
// Actualizar el nombre de la interfaz */
/* TODO Revisar cambio de nombre aquí y generar evento */
strncpy (iface->name, nla_data (attr), IFNAMSIZ);
strncpy (temp_name, nla_data (attr), IFNAMSIZ);
if (strcmp (temp_name, iface->name) != 0) {
was_update = 1;
strncpy (iface->name, nla_data (attr), IFNAMSIZ);
}
break;
case IFLA_ADDRESS:
if (nla_len (attr) > ETHER_ADDR_LEN) {
@ -121,7 +169,7 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
if (first_time == FALSE) continue;
u32data = nla_get_u32 (attr);
iface->master_index = u32data;
printf ("Interface %d has master: %d\n", iface->index, iface->master_index);
//printf ("Interface %d has master: %d\n", iface->index, iface->master_index);
break;
case IFLA_MTU:
if (nla_len (attr) != 4) {
@ -130,22 +178,26 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
}
u32data = nla_get_u32 (attr);
/* TODO: Revisar cambio de mtu y generar EVENTO aqui */
iface->mtu = u32data;
if (iface->mtu != u32data) {
iface->mtu = u32data;
was_update = 1;
}
//printf ("Interface %d has mtu: %u\n", iface->ifi_index, new->mtu);
break;
case IFLA_LINKINFO:
{
printf ("La interfaz tiene linkinfo");
struct nlattr *sub_attr;
int sub_remaining;
nla_for_each_nested(sub_attr, attr, sub_remaining) {
printf ("\tLINK_INFO attr: %i\n", nla_type (sub_attr));
switch (nla_type (sub_attr)) {
case IFLA_INFO_KIND:
printf ("IFLA_INFO_KIND: %s\n", nla_data (sub_attr));
strncpy (iface->tipo_string, nla_data (sub_attr), sizeof (iface->tipo_string) - 1);
iface->tipo_string[sizeof (iface->tipo_string) - 1] = 0;
strncpy (iface->rtnl_type, nla_data (sub_attr), sizeof (iface->rtnl_type) - 1);
iface->rtnl_type[sizeof (iface->rtnl_type) - 1] = 0;
break;
}
}
@ -161,13 +213,28 @@ static int _interfaces_receive_message_interface (struct nl_msg *msg, void *arg,
u32data = nla_get_u32 (attr);
iface->vlan_parent = u32data;
printf ("Interface %d: tiene como padre a %d\n", iface->index, iface->vlan_parent);
//default:
//printf ("RTA Attribute \"%hu\" no procesado\n", nla_type (attr));
case IFA_FLAGS:
printf ("IFA_FLAGS: size %i\n", nla_len (attr));
new_flags = nla_get_u32 (attr);
break;
default:
printf ("RTA Attribute \"%hu\" no procesado\n", nla_type (attr));
}
}
if (iface->flags != new_flags) {
was_update = 1;
}
if (was_new) {
printf ("+++++ Interfaz nueva creada: %s\n", iface->name);
wireless_interface_check (handle, iface);
iface->link_type = interfaces_check_link_type (iface);
manager_send_event_interface_add (handle, iface);
} else if (was_update) {
manager_send_event_interface_update (handle, iface);
}
return NL_SKIP;
@ -224,7 +291,7 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) {
reply = nlmsg_hdr (msg);
if (reply->nlmsg_type != RTM_NEWLINK) return NL_SKIP;
if (reply->nlmsg_type != RTM_DELLINK) return NL_SKIP;
iface_msg = nlmsg_data (reply);
@ -254,12 +321,16 @@ int interface_receive_message_dellink (struct nl_msg *msg, void *arg) {
return NL_SKIP;
}
printf ("----- Interfaz eliminada: %s\n", iface->name);
handle->interfaces = g_list_remove (handle->interfaces, iface);
/* Antes de eliminar la interfaz, eliminar la lista ligada de todas las direcciones IP */
g_list_free_full (iface->address, g_free);
g_list_free_full (iface->address, free);
g_free (iface);
manager_send_event_interface_del (handle, iface->index);
free (iface);
}
int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void *new_mac) {
@ -278,7 +349,7 @@ int interfaces_change_mac_address (NetworkInadorHandle *handle, int index, void
}
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_type = iface->ifi_type;
iface_hdr.ifi_type = iface->arp_type;
iface_hdr.ifi_index = iface->index;
iface_hdr.ifi_flags = iface->flags;
iface_hdr.ifi_change = 0xFFFFFFFF;
@ -340,7 +411,7 @@ int interfaces_change_mtu (NetworkInadorHandle *handle, int index, uint32_t new_
}
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_type = iface->ifi_type;
iface_hdr.ifi_type = iface->arp_type;
iface_hdr.ifi_index = iface->index;
iface_hdr.ifi_flags = iface->flags;
iface_hdr.ifi_change = 0xFFFFFFFF;
@ -409,7 +480,7 @@ static int _interfaces_change_admin_up (NetworkInadorHandle *handle, int index,
}
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_type = iface->ifi_type;
iface_hdr.ifi_type = iface->arp_type;
iface_hdr.ifi_index = iface->index;
if (up) {
iface_hdr.ifi_flags = iface->flags | IFF_UP;
@ -479,7 +550,7 @@ int interfaces_change_name (NetworkInadorHandle *handle, int index, char * new_n
}
iface_hdr.ifi_family = AF_UNSPEC;
iface_hdr.ifi_type = iface->ifi_type;
iface_hdr.ifi_type = iface->arp_type;
iface_hdr.ifi_index = iface->index;
iface_hdr.ifi_flags = iface->flags;
iface_hdr.ifi_change = 0xFFFFFFFF;

View File

@ -26,6 +26,7 @@
#include <netlink/msg.h>
#include <net/if_arp.h>
#include <linux/if_addr.h>
#include <arpa/inet.h>
#include <gmodule.h>
@ -33,6 +34,8 @@
#include "common.h"
#include "ip-address.h"
#include "interfaces.h"
#include "manager.h"
static IPAddr *_ip_address_search_addr (Interface *iface, sa_family_t family, void *addr, uint32_t prefix, void *local_addr) {
GList *g;
@ -83,6 +86,7 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
int family;
int has_brd = 0, has_local = 0;
int family_size = 0;
int was_new = 0;
reply = nlmsg_hdr (msg);
@ -132,7 +136,8 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
/* Agregar los datos al objeto */
if (ip_addr == NULL) {
ip_addr = g_new0 (IPAddr, 1);
ip_addr = malloc (sizeof (IPAddr));
memset (ip_addr, 0, sizeof (*ip_addr));
iface->address = g_list_append (iface->address, ip_addr);
@ -140,6 +145,9 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
memcpy (&ip_addr->addr, &addr, family_size);
ip_addr->prefix = addr_msg->ifa_prefixlen;
ip_addr->iface = iface;
was_new = 1;
}
ip_addr->flags = flags;
@ -162,6 +170,12 @@ int ip_address_receive_message_newaddr (struct nl_msg *msg, void *arg) {
memcpy (&ip_addr->brd_addr, &brd_addr, family_size);
}
if (was_new) {
manager_send_event_ip_add (handle, ip_addr);
} else {
/* En caso contrario, enviar una actualización de IP */
}
char buffer[2048];
char buffer_2[2048];
if (ip_addr->is_p2p) {
@ -240,7 +254,10 @@ int ip_address_receive_message_deladdr (struct nl_msg *msg, void *arg) {
/* Eliminar de la lista ligada */
iface->address = g_list_remove (iface->address, ip_addr);
g_free (ip_addr);
/* Notificar del evento */
manager_send_event_ip_del (handle, ip_addr);
free (ip_addr);
return NL_SKIP;
}

138
src/link-types.h 100644
View File

@ -0,0 +1,138 @@
/*
* link-types.h
* This file is part of Network Inador
*
* Copyright (C) 2021 - Félix Arreola Rodríguez
*
* Network Inador 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.
*
* Network Inador 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 Network Inador; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef __LINK_TYPES_H__
#define __LINK_TYPES_H__
typedef enum {
/* Please don't interpret type numbers outside nm-platform and use functions
* like nm_platform_link_is_software() and nm_platform_supports_slaves().
*
* type & 0x10000 -> Software device type
* type & 0x20000 -> Type supports slaves
*/
/* No type, used as error value */
NI_LINK_TYPE_NONE,
/* Unknown type */
NI_LINK_TYPE_UNKNOWN,
/* Hardware types */
NI_LINK_TYPE_ETHERNET,
NI_LINK_TYPE_INFINIBAND,
NI_LINK_TYPE_OLPC_MESH,
NI_LINK_TYPE_WIFI,
NI_LINK_TYPE_WWAN_NET, /* WWAN kernel netdevice */
NI_LINK_TYPE_WIMAX,
NI_LINK_TYPE_WPAN,
NI_LINK_TYPE_6LOWPAN,
/* Software types */
NI_LINK_TYPE_BNEP = 0x10000, /* Bluetooth Ethernet emulation */
NI_LINK_TYPE_DUMMY,
NI_LINK_TYPE_GRE,
NI_LINK_TYPE_GRETAP,
NI_LINK_TYPE_IFB,
NI_LINK_TYPE_IP6TNL,
NI_LINK_TYPE_IP6GRE,
NI_LINK_TYPE_IP6GRETAP,
NI_LINK_TYPE_IPIP,
NI_LINK_TYPE_LOOPBACK,
NI_LINK_TYPE_MACSEC,
NI_LINK_TYPE_MACVLAN,
NI_LINK_TYPE_MACVTAP,
NI_LINK_TYPE_OPENVSWITCH,
NI_LINK_TYPE_PPP,
NI_LINK_TYPE_SIT,
NI_LINK_TYPE_TUN,
NI_LINK_TYPE_VETH,
NI_LINK_TYPE_VLAN,
NI_LINK_TYPE_VXLAN,
NI_LINK_TYPE_WIREGUARD,
/* Software types with slaves */
NI_LINK_TYPE_BRIDGE = 0x10000 | 0x20000,
NI_LINK_TYPE_BOND,
NI_LINK_TYPE_TEAM,
NI_LINK_TYPE_ANY = 0xffffffff,
} NILinkType;
typedef struct {
const NILinkType link_type;
const char *type_string;
/* IFLA_INFO_KIND / rtnl_link_get_type() where applicable; the rtnl type
* should only be specified if the device type can be created without
* additional parameters, and if the device type can be determined from
* the rtnl_type. eg, tun/tap should not be specified since both
* tun and tap devices use "tun", and InfiniBand should not be
* specified because a PKey is required at creation. Drivers set this
* value from their 'struct rtnl_link_ops' structure.
*/
const char *rtnl_type;
} LinkDesc;
static const LinkDesc linktypes[] = {
{ NI_LINK_TYPE_NONE, "none", NULL },
{ NI_LINK_TYPE_UNKNOWN, "unknown", NULL },
{ NI_LINK_TYPE_ETHERNET, "ethernet", NULL },
{ NI_LINK_TYPE_INFINIBAND, "infiniband", NULL },
{ NI_LINK_TYPE_OLPC_MESH, "olpc-mesh", NULL },
{ NI_LINK_TYPE_WIFI, "wifi", NULL },
{ NI_LINK_TYPE_WWAN_NET, "wwan", NULL },
{ NI_LINK_TYPE_WIMAX, "wimax", "wimax" },
{ NI_LINK_TYPE_WPAN, "wpan", NULL },
{ NI_LINK_TYPE_6LOWPAN, "6lowpan", NULL },
{ NI_LINK_TYPE_BNEP, "bluetooth", NULL },
{ NI_LINK_TYPE_DUMMY, "dummy", "dummy" },
{ NI_LINK_TYPE_GRE, "gre", "gre" },
{ NI_LINK_TYPE_GRETAP, "gretap", "gretap" },
{ NI_LINK_TYPE_IFB, "ifb", "ifb" },
{ NI_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl" },
{ NI_LINK_TYPE_IP6GRE, "ip6gre", "ip6gre" },
{ NI_LINK_TYPE_IP6GRETAP, "ip6gretap", "ip6gretap" },
{ NI_LINK_TYPE_IPIP, "ipip", "ipip" },
{ NI_LINK_TYPE_LOOPBACK, "loopback", NULL },
{ NI_LINK_TYPE_MACSEC, "macsec", "macsec" },
{ NI_LINK_TYPE_MACVLAN, "macvlan", "macvlan" },
{ NI_LINK_TYPE_MACVTAP, "macvtap", "macvtap" },
{ NI_LINK_TYPE_OPENVSWITCH, "openvswitch", "openvswitch" },
{ NI_LINK_TYPE_PPP, "ppp", NULL },
{ NI_LINK_TYPE_SIT, "sit", "sit" },
{ NI_LINK_TYPE_TUN, "tun", "tun" },
{ NI_LINK_TYPE_VETH, "veth", "veth" },
{ NI_LINK_TYPE_VLAN, "vlan", "vlan" },
{ NI_LINK_TYPE_VXLAN, "vxlan", "vxlan" },
{ NI_LINK_TYPE_WIREGUARD, "wireguard", "wireguard" },
{ NI_LINK_TYPE_BRIDGE, "bridge", "bridge" },
{ NI_LINK_TYPE_BOND, "bond", "bond" },
{ NI_LINK_TYPE_TEAM, "team", "team" },
};
#endif /* __LINK_TYPES_H__ */

View File

@ -37,6 +37,7 @@
#include <netlink/msg.h>
#include "common.h"
#include "manager.h"
#include "interfaces.h"
#include "netlink-events.h"
#include "ip-address.h"
@ -132,6 +133,8 @@ int main (int argc, char *argv[]) {
interfaces_init (&handle);
manager_init (&handle);
g_main_loop_run (loop);
/* Detener la llegada de eventos */

View File

@ -110,8 +110,6 @@ static void _wireless_if_process_bands (struct nlattr *list_bands, WirelessInfo
static int _wireless_if_cb_valid_is_wifi (struct nl_msg *msg, void *arg) {
struct _wireless_iface_is_wifi *is_wifi = (struct _wireless_iface_is_wifi *) arg;
printf ("%s: Argumento extra: %p\n", __func__, arg);
struct nlmsgerr *l_err;
struct nlmsghdr *reply;
struct genlmsghdr *gnlh;