diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-02-25 22:53:33 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2012-02-25 22:53:33 +0100 |
commit | 57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88 (patch) | |
tree | 081b9dc0d024f7b57dde74c6858274c3d62df9aa /src/fastd.c | |
parent | d86a948a67c44ca1c484cfbe30261f1bf61c59ab (diff) | |
download | fastd-57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88.tar fastd-57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88.zip |
Init tun interface and define some structures
Diffstat (limited to 'src/fastd.c')
-rw-r--r-- | src/fastd.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/fastd.c b/src/fastd.c index f500090..42478b2 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -23,3 +23,133 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + +#include <fcntl.h> +#include <linux/if_ether.h> +#include <linux/if_tun.h> +#include <net/if.h> +#include <poll.h> +#include <stdio.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <unistd.h> + +#include "fastd.h" +#include "packet.h" + + +extern fastd_method fastd_method_null; + + +static int init_tuntap(const fastd_context *ctx) { + int tunfd; + struct ifreq ifr; + + pr_debug(ctx, "Initializing tun/tap device..."); + + if ((tunfd = open("/dev/net/tun", O_RDWR)) < 0) + exit_fatal_errno(ctx, "Could not open tun/tap device file"); + + memset(&ifr, 0, sizeof(ifr)); + // strcpy(ifr.ifr_name, name); + ifr.ifr_flags = IFF_TAP; + ifr.ifr_flags |= IFF_NO_PI; + if (ioctl(tunfd, TUNSETIFF, (void *)&ifr) < 0) + exit_fatal_errno(ctx, "TUNSETIFF ioctl failed"); + + return tunfd; +} + +static void configure(fastd_context *ctx, fastd_config *conf) { + conf->loglevel = LOG_DEBUG; + conf->mtu = 1500; + conf->protocol = PROTOCOL_ETHERNET; + conf->method = &fastd_method_null; + conf->n_peers = 0; + conf->peers = NULL; +} + +static size_t get_max_packet_size(const fastd_context *ctx) { + switch (ctx->conf->protocol) { + case PROTOCOL_ETHERNET: + return ctx->conf->mtu+ETH_HLEN; + case PROTOCOL_IP: + return ctx->conf->mtu; + default: + exit_fatal_bug(ctx, "invalid protocol"); + } +} + +static void *get_source_address(const fastd_context *ctx, void *buffer) { + switch (ctx->conf->protocol) { + case PROTOCOL_ETHERNET: + return &((struct ethhdr*)buffer)->h_source; + case PROTOCOL_IP: + return NULL; + default: + exit_fatal_bug(ctx, "invalid protocol"); + } +} + +static void *get_dest_address(const fastd_context *ctx, void *buffer) { + switch (ctx->conf->protocol) { + case PROTOCOL_ETHERNET: + return &((struct ethhdr*)buffer)->h_dest; + case PROTOCOL_IP: + return NULL; + default: + exit_fatal_bug(ctx, "invalid protocol"); + } +} + +static void run(const fastd_context *ctx) { + int tunfd; + + tunfd = init_tuntap(ctx); + + struct pollfd fds[ctx->conf->n_peers+1]; + fds[0].fd = tunfd; + fds[0].events = POLLIN; + + while (1) { + int ret = poll(fds, 1, -1); + if (ret < 0) + exit_fatal_errno(ctx, "poll error"); + + if (fds[0].revents & POLLIN) { + size_t max_len = get_max_packet_size(ctx); + char buffer[max_len]; + + unsigned len = read(tunfd, buffer, max_len); + if (len < 0) + exit_fatal_errno(ctx, "read"); + + uint8_t *src_addr = get_source_address(ctx, buffer); + uint8_t *dest_addr = get_dest_address(ctx, buffer); + + pr_debug(ctx, "A packet with length %u was received from %02x:%02x:%02x:%02x:%02x:%02x to %02x:%02x:%02x:%02x:%02x:%02x", + len, src_addr[0], src_addr[1], src_addr[2], src_addr[3], src_addr[4], src_addr[5], + dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3], dest_addr[4], dest_addr[5]); + + ctx->conf->method->method_send(ctx, buffer, len); + } + } +} + + +int main() +{ + fastd_context ctx = { + .conf = NULL, + }; + + fastd_config conf; + configure(&ctx, &conf); + ctx.conf = &conf; + + run(&ctx); + + return 0; +} |