From c5a1d00fc40a9c55024cfc7f92b0a455975ba503 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 26 Sep 2012 19:16:53 +0200 Subject: Keep track of interfaces --- ffd/ffd.c | 83 ++++++++++++++++++++++++++++++++++++++++++++----------------- ffd/ffd.h | 49 ++++++++++++++---------------------- ffd/netif.c | 19 ++++++++++++++ ffd/netif.h | 4 ++- ffd/tlv.h | 10 +++++++- 5 files changed, 110 insertions(+), 55 deletions(-) diff --git a/ffd/ffd.c b/ffd/ffd.c index 27e5c29..e729a43 100644 --- a/ffd/ffd.c +++ b/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); diff --git a/ffd/ffd.h b/ffd/ffd.h index 90fefb6..c78c4a4 100644 --- a/ffd/ffd.h +++ b/ffd/ffd.h @@ -28,46 +28,35 @@ #define _FFD_FFD_H_ #include "util.h" +#include "netif.h" +#include -typedef enum _ffd_msg_type_t { - MSG_UNSPEC = 0, - MSG_SERVICE, - MSG_ROUTE4, - MSG_ROUTE6, -} ffd_msg_type_t; -typedef struct _ffd_msg_head_t { - struct _ffd_msg_head_t *next; +typedef struct _ffd_announce_t { + struct _ffd_announce_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_ */ diff --git a/ffd/netif.c b/ffd/netif.c index d521a12..45b4e58 100644 --- a/ffd/netif.c +++ b/ffd/netif.c @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -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"); } diff --git a/ffd/netif.h b/ffd/netif.h index 8dc5b94..cc723ba 100644 --- a/ffd/netif.h +++ b/ffd/netif.h @@ -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); diff --git a/ffd/tlv.h b/ffd/tlv.h index 287c5c6..4bdb633 100644 --- a/ffd/tlv.h +++ b/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); -- cgit v1.2.3