summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2012-02-25 22:53:33 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2012-02-25 22:53:33 +0100
commit57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88 (patch)
tree081b9dc0d024f7b57dde74c6858274c3d62df9aa
parentd86a948a67c44ca1c484cfbe30261f1bf61c59ab (diff)
downloadfastd-57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88.tar
fastd-57a63fc9304e71ddd2cf434cc4c8789a1a3a3c88.zip
Init tun interface and define some structures
-rw-r--r--.gitignore2
-rw-r--r--src/Makefile10
-rw-r--r--src/fastd.c130
-rw-r--r--src/fastd.h102
-rw-r--r--src/method_null.c45
-rw-r--r--src/packet.h67
6 files changed, 356 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index b25c15b..c344a07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
*~
+*.o
+fastd
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..90619ec
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,10 @@
+all : fastd
+
+fastd : fastd.o method_null.o
+ gcc -Wall -o $@ $^
+
+fastd.o : fastd.c fastd.h packet.h
+ gcc -Wall -c -o $@ $<
+
+method_null.o : method_null.c fastd.h
+ gcc -Wall -c -o $@ $<
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;
+}
diff --git a/src/fastd.h b/src/fastd.h
new file mode 100644
index 0000000..06b69b2
--- /dev/null
+++ b/src/fastd.h
@@ -0,0 +1,102 @@
+/*
+ Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
+ Partly based on QuickTun Copyright (c) 2010, Ivo Smits <Ivo@UCIS.nl>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ 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.
+*/
+
+
+#ifndef _FASTD_FASTD_H_
+#define _FASTD_FASTD_H_
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef enum _fastd_loglevel {
+ LOG_FATAL = 0,
+ LOG_ERROR,
+ LOG_WARN,
+ LOG_INFO,
+ LOG_DEBUG,
+} fastd_loglevel;
+
+
+typedef enum _fastd_protocol {
+ PROTOCOL_ETHERNET,
+ PROTOCOL_IP,
+} fastd_protocol;
+
+typedef struct _fastd_peer_config {
+ struct _fastd_peer_config *next;
+} fastd_peer_config;
+
+
+typedef struct _fastd_peer_state {
+ struct _fastd_peer_state *next;
+
+ const fastd_peer_config *config;
+} fastd_peer_state;
+
+typedef struct _fastd_context fastd_context;
+
+typedef struct _fastd_method {
+ const char *name;
+ void (*method_init)(const fastd_context *ctx);
+
+ void (*method_recv)(const fastd_context *ctx, void *buffer, size_t len);
+ void (*method_send)(const fastd_context *ctx, void *buffer, size_t len);
+} fastd_method;
+
+typedef struct _fastd_config {
+ fastd_loglevel loglevel;
+
+ uint16_t mtu;
+ fastd_protocol protocol;
+
+ fastd_method *method;
+
+ unsigned n_peers;
+ fastd_peer_config *peers;
+} fastd_config;
+
+struct _fastd_context {
+ const fastd_config *conf;
+};
+
+
+#define pr_log(context, level, args...) if ((context)->conf == NULL || (level) <= (context)->conf->loglevel) do { fprintf(stderr, args); fputs("\n", stderr); } while(0)
+
+#define pr_fatal(context, args...) pr_log(context, LOG_FATAL, args)
+#define pr_error(context, args...) pr_log(context, LOG_ERROR, args)
+#define pr_warn(context, args...) pr_log(context, LOG_WARN, args)
+#define pr_info(context, args...) pr_log(context, LOG_INFO, args)
+#define pr_debug(context, args...) pr_log(context, LOG_DEBUG, args)
+
+#define exit_fatal(context, args...) do { pr_fatal(context, args); exit(1); } while(0)
+#define exit_fatal_bug(context, message) exit_fatal(context, "BUG: %s", message)
+#define exit_fatal_errno(context, message) exit_fatal(context, "%s: %s", message, strerror(errno))
+
+#endif /* _FASTD_FASTD_H_ */
diff --git a/src/method_null.c b/src/method_null.c
new file mode 100644
index 0000000..fd41110
--- /dev/null
+++ b/src/method_null.c
@@ -0,0 +1,45 @@
+/*
+ Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
+ Partly based on QuickTun Copyright (c) 2010, Ivo Smits <Ivo@UCIS.nl>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ 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 "fastd.h"
+
+
+static void null_init(const fastd_context *ctx) {
+}
+
+static void null_recv(const fastd_context *ctx, void *buffer, size_t len) {
+}
+
+static void null_send(const fastd_context *ctx, void *buffer, size_t len) {
+}
+
+
+const fastd_method fastd_method_null = {
+ .name = "null",
+ .method_init = null_init,
+ .method_recv = null_recv,
+ .method_send = null_send,
+};
diff --git a/src/packet.h b/src/packet.h
new file mode 100644
index 0000000..79b1984
--- /dev/null
+++ b/src/packet.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2012, Matthias Schiffer <mschiffer@universe-factory.net>
+ Partly based on QuickTun Copyright (c) 2010, Ivo Smits <Ivo@UCIS.nl>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ 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.
+*/
+
+
+#ifndef _FASTD_PACKET_H_
+#define _FASTD_PACKET_H_
+
+
+typedef struct __attribute__ ((__packed__)) _fastd_packet_any {
+ unsigned type : 8;
+ unsigned reply : 1;
+ unsigned cp : 1;
+ unsigned req_id : 6;
+ unsigned rsv : 8;
+} fastd_packet_any;
+
+typedef struct __attribute__ ((__packed__)) _fastd_packet_request {
+ unsigned type : 8;
+ unsigned reply : 1;
+ unsigned cp : 1;
+ unsigned req_id : 6;
+ unsigned rsv : 8;
+ unsigned flags : 8;
+ unsigned proto : 8;
+ unsigned method_len : 8;
+ char method_name[];
+} fastd_packet_request;
+
+typedef struct __attribute__ ((__packed__)) _fastd_packet_reply {
+ unsigned type : 8;
+ unsigned reply : 1;
+ unsigned cp : 1;
+ unsigned req_id : 6;
+ unsigned rsv : 8;
+ unsigned reply_code : 8;
+} fastd_packet_reply;
+
+typedef union _fastd_packet {
+ fastd_packet_any any;
+ fastd_packet_request request;
+ fastd_packet_reply reply;
+} fastd_packet;
+
+#endif /* _FASTD_PACKET_H_ */