Keep track of interfaces

This commit is contained in:
Matthias Schiffer 2012-09-26 19:16:53 +02:00
parent 9eeec649fb
commit c5a1d00fc4
5 changed files with 111 additions and 56 deletions

View file

@ -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);

View file

@ -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_ */

View file

@ -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");
}

View file

@ -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);

View file

@ -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);