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 struct timespec now;
|
||||
|
||||
static ffd_iface_t *iface_list = NULL;
|
||||
|
||||
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 */
|
||||
//static ffd_neigh_t *neigh_data = NULL;
|
||||
|
@ -92,12 +94,12 @@ static bool init_self() {
|
|||
return false;
|
||||
|
||||
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(&own_data.rev, sizeof(own_data.rev));
|
||||
//random_bytes(&self.rev, sizeof(self.rev));
|
||||
//random_bytes(&own_data.rev, sizeof(own_data.rev));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -112,10 +114,11 @@ static bool init_socket() {
|
|||
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))
|
||||
return;
|
||||
|
||||
/* join multicast group */
|
||||
struct packet_mreq mr;
|
||||
memset(&mr, 0, sizeof(mr));
|
||||
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);
|
||||
if (setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) && errno != EADDRINUSE)
|
||||
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) {
|
||||
|
@ -158,21 +203,8 @@ static bool send_eth(const eth_addr_t *addr, unsigned ifindex, void *buf, size_t
|
|||
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() {
|
||||
/*if (!orig_data)
|
||||
return;*/
|
||||
static uint16_t seqno = 0;
|
||||
|
||||
ffd_packet_t *packet = alloca(sizeof(ffd_packet_t)+PACKET_MAX);
|
||||
|
||||
packet->version_magic = htons(FFD_VERSION_MAGIC);
|
||||
|
@ -182,11 +214,16 @@ static void send_hellos() {
|
|||
if (!hello)
|
||||
return;
|
||||
|
||||
memset(hello, 0, sizeof(ffd_tlv_hello_t));
|
||||
hello->seqno = htons(seqno++);
|
||||
hello->reserved = 0;
|
||||
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() {
|
||||
|
@ -219,7 +256,7 @@ int main() {
|
|||
struct timespec next_hello = now;
|
||||
|
||||
while (true) {
|
||||
netif_foreach(join_mcast, NULL);
|
||||
update_netifs();
|
||||
|
||||
int timeout = timespec_diff(&next_hello, &now);
|
||||
|
||||
|
|
51
ffd/ffd.h
51
ffd/ffd.h
|
@ -28,46 +28,35 @@
|
|||
#define _FFD_FFD_H_
|
||||
|
||||
#include "util.h"
|
||||
#include "netif.h"
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
|
||||
typedef enum _ffd_msg_type_t {
|
||||
MSG_UNSPEC = 0,
|
||||
MSG_SERVICE,
|
||||
MSG_ROUTE4,
|
||||
MSG_ROUTE6,
|
||||
} ffd_msg_type_t;
|
||||
typedef struct _ffd_announce_t {
|
||||
struct _ffd_announce_t *next;
|
||||
|
||||
typedef struct _ffd_msg_head_t {
|
||||
struct _ffd_msg_head_t *next;
|
||||
|
||||
/* 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 type;
|
||||
uint8_t len;
|
||||
uint8_t data[];
|
||||
} ffd_msg_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;
|
||||
} ffd_announce_head_t;
|
||||
|
||||
typedef struct _ffd_neigh_t {
|
||||
struct _ffd_neigh_t *next;
|
||||
|
||||
uint64_t rev;
|
||||
eth_addr_t addr;
|
||||
} 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_ */
|
||||
|
|
19
ffd/netif.c
19
ffd/netif.c
|
@ -36,6 +36,7 @@
|
|||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#include <sys/stat.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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return netif_file_exists(ifname, "mesh");
|
||||
}
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
|
||||
|
||||
typedef enum _netif_type_t {
|
||||
IF_UNKNOWN = 0,
|
||||
IF_UNSPEC = 0,
|
||||
IF_UNKNOWN,
|
||||
IF_WIRED,
|
||||
IF_WIRELESS,
|
||||
IF_VIRTUAL,
|
||||
|
@ -45,6 +46,7 @@ typedef enum _netif_type_t {
|
|||
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);
|
||||
char* netif_get_mesh(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_RESERVED,
|
||||
TLV_UPDATE,
|
||||
TLV_INFO_REQ,
|
||||
TLV_ANNOUNCE_REQ,
|
||||
TLV_SEQNO_REQ,
|
||||
} 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);
|
||||
|
||||
|
|
Reference in a new issue