Keep track of interfaces
This commit is contained in:
parent
9eeec649fb
commit
c5a1d00fc4
5 changed files with 111 additions and 56 deletions
83
ffd/ffd.c
83
ffd/ffd.c
|
@ -57,8 +57,10 @@ static unsigned mtu = 1528;
|
||||||
static int sockfd;
|
static int sockfd;
|
||||||
static struct timespec now;
|
static struct timespec now;
|
||||||
|
|
||||||
|
static ffd_iface_t *iface_list = NULL;
|
||||||
|
|
||||||
static ffd_neigh_t self;
|
static ffd_neigh_t self;
|
||||||
static ffd_orig_t own_data;
|
//static ffd_orig_t own_data;
|
||||||
|
|
||||||
/* neighs and origs that have been changed must be moved to front */
|
/* neighs and origs that have been changed must be moved to front */
|
||||||
//static ffd_neigh_t *neigh_data = NULL;
|
//static ffd_neigh_t *neigh_data = NULL;
|
||||||
|
@ -92,12 +94,12 @@ static bool init_self() {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memset(&self, 0, sizeof(self));
|
memset(&self, 0, sizeof(self));
|
||||||
memset(&own_data, 0, sizeof(own_data));
|
//memset(&own_data, 0, sizeof(own_data));
|
||||||
|
|
||||||
self.addr = own_data.addr = primary_addr;
|
//self.addr = own_data.addr = primary_addr;
|
||||||
|
|
||||||
random_bytes(&self.rev, sizeof(self.rev));
|
//random_bytes(&self.rev, sizeof(self.rev));
|
||||||
random_bytes(&own_data.rev, sizeof(own_data.rev));
|
//random_bytes(&own_data.rev, sizeof(own_data.rev));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -112,10 +114,11 @@ static bool init_socket() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void join_mcast(const char *ifname, unsigned ifindex, void *arg) {
|
static void update_netif(const char *ifname, unsigned ifindex, void *arg) {
|
||||||
if (!use_netif(ifname))
|
if (!use_netif(ifname))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* join multicast group */
|
||||||
struct packet_mreq mr;
|
struct packet_mreq mr;
|
||||||
memset(&mr, 0, sizeof(mr));
|
memset(&mr, 0, sizeof(mr));
|
||||||
mr.mr_ifindex = ifindex;
|
mr.mr_ifindex = ifindex;
|
||||||
|
@ -124,6 +127,48 @@ static void join_mcast(const char *ifname, unsigned ifindex, void *arg) {
|
||||||
memcpy(mr.mr_address, ffd_addr.d, ETH_ALEN);
|
memcpy(mr.mr_address, ffd_addr.d, ETH_ALEN);
|
||||||
if (setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) && errno != EADDRINUSE)
|
if (setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) && errno != EADDRINUSE)
|
||||||
fprintf(stderr, "warning: setsockopt: %m\n");
|
fprintf(stderr, "warning: setsockopt: %m\n");
|
||||||
|
|
||||||
|
ffd_iface_t *iface;
|
||||||
|
for (iface = iface_list; iface; iface = iface->next) {
|
||||||
|
if (iface->ifindex == ifindex)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iface) {
|
||||||
|
/* new iface */
|
||||||
|
iface = malloc(sizeof(ffd_iface_t));
|
||||||
|
iface->next = iface_list;
|
||||||
|
iface_list = iface;
|
||||||
|
|
||||||
|
iface->seqno = 0;
|
||||||
|
iface->neighs = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iface->ifindex = ifindex;
|
||||||
|
strncpy(iface->name, ifname, IF_NAMESIZE);
|
||||||
|
iface->type = netif_get_type(ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_netifs() {
|
||||||
|
ffd_iface_t *iface, **cur;
|
||||||
|
|
||||||
|
for (iface = iface_list; iface; iface = iface->next)
|
||||||
|
iface->type = IF_UNSPEC;
|
||||||
|
|
||||||
|
netif_foreach(update_netif, NULL);
|
||||||
|
|
||||||
|
cur = &iface_list;
|
||||||
|
while (*cur) {
|
||||||
|
iface = *cur;
|
||||||
|
|
||||||
|
if (iface->type == IF_UNSPEC) {
|
||||||
|
*cur = iface->next;
|
||||||
|
free(iface);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cur = &iface->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t len) {
|
static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t len) {
|
||||||
|
@ -158,21 +203,8 @@ static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_hello(const char *ifname, unsigned ifindex, void *arg) {
|
|
||||||
if (!use_netif(ifname))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ffd_packet_t *packet = arg;
|
|
||||||
|
|
||||||
if (!send_eth(&ffd_addr, ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
|
||||||
fprintf(stderr, "send_eth: %m\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_hellos() {
|
static void send_hellos() {
|
||||||
/*if (!orig_data)
|
|
||||||
return;*/
|
|
||||||
static uint16_t seqno = 0;
|
|
||||||
|
|
||||||
ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+PACKET_MAX);
|
ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+PACKET_MAX);
|
||||||
|
|
||||||
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||||
|
@ -182,11 +214,16 @@ static void send_hellos() {
|
||||||
if (!hello)
|
if (!hello)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(hello, 0, sizeof(ffd_tlv_hello_t));
|
hello->reserved = 0;
|
||||||
hello->seqno = htons(seqno++);
|
|
||||||
hello->interval = htons(HELLO_INTERVAL*100);
|
hello->interval = htons(HELLO_INTERVAL*100);
|
||||||
|
|
||||||
netif_foreach(send_hello, packet);
|
ffd_iface_t *iface;
|
||||||
|
for (iface = iface_list; iface; iface = iface->next) {
|
||||||
|
hello->seqno = htons(iface->seqno++);
|
||||||
|
|
||||||
|
if (!send_eth(&ffd_addr, iface->ifindex, packet, sizeof(ffd_packet_t)+ntohs(packet->len)))
|
||||||
|
fprintf(stderr, "send_eth: %m\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void receive_packet() {
|
static void receive_packet() {
|
||||||
|
@ -219,7 +256,7 @@ int main() {
|
||||||
struct timespec next_hello = now;
|
struct timespec next_hello = now;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
netif_foreach(join_mcast, NULL);
|
update_netifs();
|
||||||
|
|
||||||
int timeout = timespec_diff(&next_hello, &now);
|
int timeout = timespec_diff(&next_hello, &now);
|
||||||
|
|
||||||
|
|
51
ffd/ffd.h
51
ffd/ffd.h
|
@ -28,46 +28,35 @@
|
||||||
#define _FFD_FFD_H_
|
#define _FFD_FFD_H_
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "netif.h"
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
|
||||||
typedef enum _ffd_msg_type_t {
|
typedef struct _ffd_announce_t {
|
||||||
MSG_UNSPEC = 0,
|
struct _ffd_announce_t *next;
|
||||||
MSG_SERVICE,
|
|
||||||
MSG_ROUTE4,
|
|
||||||
MSG_ROUTE6,
|
|
||||||
} ffd_msg_type_t;
|
|
||||||
|
|
||||||
typedef struct _ffd_msg_head_t {
|
uint8_t type;
|
||||||
struct _ffd_msg_head_t *next;
|
uint8_t len;
|
||||||
|
|
||||||
/* orig rev this message was added or removed last */
|
|
||||||
uint64_t changed_rev;
|
|
||||||
bool deleted;
|
|
||||||
|
|
||||||
ffd_msg_type_t type;
|
|
||||||
uint16_t len;
|
|
||||||
uint8_t data[];
|
uint8_t data[];
|
||||||
} ffd_msg_head_t;
|
} ffd_announce_head_t;
|
||||||
|
|
||||||
typedef struct _ffd_orig_t {
|
|
||||||
struct _ffd_orig_t *next;
|
|
||||||
|
|
||||||
/* neigh rev this orig has changed last */
|
|
||||||
uint64_t changed_rev;
|
|
||||||
struct timespec changed_time;
|
|
||||||
|
|
||||||
uint64_t rev;
|
|
||||||
eth_addr_t addr;
|
|
||||||
uint16_t orig_interval;
|
|
||||||
|
|
||||||
ffd_msg_head_t *messages;
|
|
||||||
} ffd_orig_t;
|
|
||||||
|
|
||||||
typedef struct _ffd_neigh_t {
|
typedef struct _ffd_neigh_t {
|
||||||
struct _ffd_neigh_t *next;
|
struct _ffd_neigh_t *next;
|
||||||
|
|
||||||
uint64_t rev;
|
|
||||||
eth_addr_t addr;
|
eth_addr_t addr;
|
||||||
} ffd_neigh_t;
|
} ffd_neigh_t;
|
||||||
|
|
||||||
|
typedef struct _ffd_iface_t {
|
||||||
|
struct _ffd_iface_t *next;
|
||||||
|
|
||||||
|
unsigned ifindex;
|
||||||
|
char name[IF_NAMESIZE];
|
||||||
|
|
||||||
|
netif_type_t type;
|
||||||
|
uint16_t seqno;
|
||||||
|
|
||||||
|
ffd_neigh_t *neighs;
|
||||||
|
} ffd_iface_t;
|
||||||
|
|
||||||
#endif /* _FFD_FFD_H_ */
|
#endif /* _FFD_FFD_H_ */
|
||||||
|
|
19
ffd/netif.c
19
ffd/netif.c
|
@ -36,6 +36,7 @@
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -81,6 +82,24 @@ static bool batadv_file_read(const char *ifname, const char *file, const char *f
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
netif_type_t netif_get_type(const char *ifname) {
|
||||||
|
int type;
|
||||||
|
if (netif_file_read(ifname, "type", "%i", &type) && type == ARPHRD_ETHER) {
|
||||||
|
if(netif_file_exists(ifname, "mesh"))
|
||||||
|
return IF_MESH;
|
||||||
|
else if(netif_file_exists(ifname, "bridge"))
|
||||||
|
return IF_BRIDGE;
|
||||||
|
else if(netif_file_exists(ifname, "tun_flags"))
|
||||||
|
return IF_VIRTUAL;
|
||||||
|
else if(netif_file_exists(ifname, "wireless"))
|
||||||
|
return IF_WIRELESS;
|
||||||
|
else
|
||||||
|
return IF_WIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IF_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
bool netif_is_mesh(const char *ifname) {
|
bool netif_is_mesh(const char *ifname) {
|
||||||
return netif_file_exists(ifname, "mesh");
|
return netif_file_exists(ifname, "mesh");
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
|
|
||||||
|
|
||||||
typedef enum _netif_type_t {
|
typedef enum _netif_type_t {
|
||||||
IF_UNKNOWN = 0,
|
IF_UNSPEC = 0,
|
||||||
|
IF_UNKNOWN,
|
||||||
IF_WIRED,
|
IF_WIRED,
|
||||||
IF_WIRELESS,
|
IF_WIRELESS,
|
||||||
IF_VIRTUAL,
|
IF_VIRTUAL,
|
||||||
|
@ -45,6 +46,7 @@ typedef enum _netif_type_t {
|
||||||
typedef void (*netif_cb)(const char *ifname, unsigned ifindex, void *arg);
|
typedef void (*netif_cb)(const char *ifname, unsigned ifindex, void *arg);
|
||||||
|
|
||||||
|
|
||||||
|
netif_type_t netif_get_type(const char *ifname);
|
||||||
bool netif_is_mesh(const char *ifname);
|
bool netif_is_mesh(const char *ifname);
|
||||||
char* netif_get_mesh(const char *ifname);
|
char* netif_get_mesh(const char *ifname);
|
||||||
char* netif_get_bridge(const char *ifname);
|
char* netif_get_bridge(const char *ifname);
|
||||||
|
|
10
ffd/tlv.h
10
ffd/tlv.h
|
@ -40,10 +40,18 @@ typedef enum _ffd_tlv_type_t {
|
||||||
TLV_NODE_ID,
|
TLV_NODE_ID,
|
||||||
TLV_RESERVED,
|
TLV_RESERVED,
|
||||||
TLV_UPDATE,
|
TLV_UPDATE,
|
||||||
TLV_INFO_REQ,
|
TLV_ANNOUNCE_REQ,
|
||||||
TLV_SEQNO_REQ,
|
TLV_SEQNO_REQ,
|
||||||
} ffd_tlv_type_t;
|
} ffd_tlv_type_t;
|
||||||
|
|
||||||
|
typedef enum _ffd_addr_enc_t {
|
||||||
|
ADDR_ENC_UNSPEC = 0,
|
||||||
|
ADDR_ENC_IPV4,
|
||||||
|
ADDR_ENC_IPV6,
|
||||||
|
ADDR_ENC_IPV6LL,
|
||||||
|
ADDR_ENC_ETH,
|
||||||
|
} ffd_addr_enc_t;
|
||||||
|
|
||||||
|
|
||||||
typedef void (*ffd_tlv_cb)(ffd_tlv_type_t type, const void *data, size_t len, void *arg);
|
typedef void (*ffd_tlv_cb)(ffd_tlv_type_t type, const void *data, size_t len, void *arg);
|
||||||
|
|
||||||
|
|
Reference in a new issue