*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 20 Dec 2007 01:32:19 +0000 (01:32 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 20 Dec 2007 01:32:19 +0000 (01:32 +0000)
mmsoftware/tap-bridge/GNUmakefile
mmsoftware/tap-bridge/modules/tap-logger.c
mmsoftware/tap-bridge/tap-bridge.c
mmsoftware/tap-bridge/tap-bridge.h
mmsoftware/tap-bridge/tap-endian.c [new file with mode: 0644]
mmsoftware/tap-bridge/tap-endian.h [new file with mode: 0644]
mmsoftware/tap-bridge/tap-headers.h

index 4f37af9..cad164d 100644 (file)
@@ -1,10 +1,10 @@
-# $Id: GNUmakefile,v 1.1 2007/12/17 19:56:07 mmondor Exp $
+# $Id: GNUmakefile,v 1.2 2007/12/20 01:32:19 mmondor Exp $
 
 MMLIB_PATH := ../../mmlib
 
 MMLIBS := $(addprefix $(MMLIB_PATH)/,mmpool.o mmhash.o mmlog.o)
 LIBS := -lc
-BINOBJS := tap-bridge.o
+BINOBJS := tap-bridge.o tap-endian.o
 MODULES := $(addprefix modules/,tap-logger.so tap-passthrough.so)
 CFLAGS += -Wall
 #CFLAGS += -g -DDEBUG
index d96e19a..51a8c2e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-logger.c,v 1.1 2007/12/17 19:56:07 mmondor Exp $ */
+/* $Id: tap-logger.c,v 1.2 2007/12/20 01:32:19 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
 
 #include <errno.h>
 #include <fcntl.h>
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <tap-bridge.h>
+#include <tap-headers.h>
 
 
 static bool    mod_init(tap_t *, tap_t *);
@@ -47,6 +50,7 @@ static bool   mod_recv_int(tap_t *, fnode_t *);
 static bool    mod_recv_ext(tap_t *, fnode_t *);
 static void    mod_exit(void);
 
+static void    logprintf(const char *, ...);
 static void    frame_log(frame_t *, const char *);
 
 
@@ -60,7 +64,7 @@ module_t module = {
 
 
 static tap_t   *tap_int, *tap_ext;
-static FILE    *logfh = NULL;
+static int     logfd = -1;
 
 
 static bool
@@ -74,16 +78,21 @@ mod_init(tap_t *tap_i, tap_t *tap_e)
        if ((udata = key_lookup("tap_logger_file")) == NULL) {
                if ((udata = key_create("tap_logger_file")) == NULL)
                        return false;
-               if ((logfh = fopen("/tmp/tap-filter.log", "a")) == NULL) {
+               if ((logfd = open("/tmp/tap-filter.log",
+                   O_CREAT | O_WRONLY | O_APPEND)) == -1) {
                        key_destroy("tap_logger_file");
                        warning(errno, "fopen(/tmp/tap-filter.log)");
                        return false;
                }
+               if ((*udata = malloc(sizeof(int))) == NULL) {
+                       key_destroy("tap_logger_file");
+                       warning(errno, "malloc(int)");
+                       return false;
+               }
 
-               (void) setvbuf(logfh, NULL, _IOLBF, 0);
-               *udata = logfh;
+               *((int *)*udata) = logfd;
        } else
-               logfh = *udata;
+               logfd = *((int *)*udata);
 
        return true;
 }
@@ -107,32 +116,82 @@ mod_recv_ext(tap_t *tap, fnode_t *n)
 }
 
 static void
-frame_log(frame_t *f, const char *d)
+mod_exit(void)
 {
-       char    origin[32], destination[32];
 
-       if (f->size < 14) {
-               (void) fprintf(logfh, "%s Short ethernet frame: Size: %u\n",
-                   d, f->size);
+       /* NOOP */
+}
+
+
+/*
+ * We want line buffering, and can't use stdio as it won't restart write(2) on
+ * EINTR events.
+ */
+static void
+logprintf(const char *fmt, ...)
+{
+       char    buf[1024];
+       va_list lst;
+       int     len;
+
+       va_start(lst, fmt);
+       len = vsnprintf(buf, sizeof(buf) - 1, fmt, lst);
+       va_end(lst);
+
+       while (write(logfd, buf, len) == -1 && errno == EINTR) ;
+}
+
+static void
+frame_log(frame_t *f, const char *d)
+{
+       char            origin[32], destination[32];
+       struct hdr_tap  *hdrtap = (struct hdr_tap *)f->data;
+       struct hdr_arp  *hdrarp;
+       struct hdr_ip   *hdrip;
+       void            *ahdrtap = &hdrtap[1];
+       void            *ahdrip;
+
+       if (f->size < sizeof(struct hdr_tap)) {
+               logprintf("%s Short ethernet frame: Size: %u\n", d, f->size);
                return;
        }
 
        (void) macaddr_string(origin, 31, &f->origin);
        (void) macaddr_string(destination, 31, &f->destination);
-       (void) fprintf(logfh, "%s Src: %s, Dst: %s - EType: %04x, Size: %u\n",
+       logprintf("%s Src: %s, Dst: %s - EType: %04x, Size: %u\n",
            d, origin, destination, f->type, f->size);
 
-       if (f->type == 0x0806) {
-               if (f->size < 42) {
-                       (void) fprintf(logfh, " Short ARP packet\n");
+       switch (f->type) {
+       case HDR_TAP_ETYPE_ARP:
+               if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_arp)) {
+                       logprintf(" Short ARP packet\n");
+                       return;
+               }
+               hdrarp = ahdrtap;
+               break;
+       case HDR_TAP_ETYPE_IP:
+               if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_ip)) {
+                       logprintf(" Short IP packet\n");
                        return;
                }
+               hdrip = ahdrtap;
+               /* XXX We must find pointer to location after options */
+               ahdrip = &hdrip[1];
+               switch (hdrip->protocol) {
+               case HDR_IP_PROTO_UDP:
+                       break;
+               case HDR_IP_PROTO_TCP:
+                       break;
+               case HDR_IP_PROTO_ICMP:
+                       break;
+               default:
+                       logprintf(" Unsupported IP protocol (0x%04x)\n",
+                           hdrip->protocol);
+                       break;
+               }
+               break;
+       default:
+               logprintf(" Unsupported ethertype (0x%04x)\n", f->type);
+               break;
        }
 }
-
-static void
-mod_exit(void)
-{
-
-       /* NOOP */
-}
index 8699a12..cf5b0b4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-bridge.c,v 1.1 2007/12/17 19:56:07 mmondor Exp $ */
+/* $Id: tap-bridge.c,v 1.2 2007/12/20 01:32:19 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
@@ -78,6 +78,7 @@
 #include <mmhash.h>
 
 #include <tap-bridge.h>
+#include <tap-endian.h>
 
 
 #define OUTMAX         1048576
@@ -127,8 +128,10 @@ static int         if_up(const char *);
 static int             if_down(const char *);
 static int             if_get_macaddr(uint8_t *, const char *);
 static int             if_set_macaddr(const char *, const char *);
+/*
 static int             if_get_ipaddr(in_addr_t *, in_addr_t *, in_addr_t *,
                            const char *);
+ */
 static int             if_set_ipaddr(const char *, const char *,
                            const char *);
 static int             bridge_add(const char *, const char *);
@@ -1032,6 +1035,7 @@ err:
        return -1;
 }
 
+/*
 static int
 if_get_ipaddr(in_addr_t *addr, in_addr_t *mask, in_addr_t *braddr,
     const char *iface)
@@ -1068,6 +1072,7 @@ err:
        warning(errno, "if_get_ipaddr(%s)", iface);
        return -1;
 }
+*/
 
 static int
 if_set_ipaddr(const char *iface, const char *netmask, const char *address)
@@ -1231,7 +1236,7 @@ frame_receive(tap_t *tap)
                macaddr_align16(&f->origin, &((uint16_t *)f->data)[3]);
                f->received = time_current;
                f->size = len + 2;
-               f->type = ntohs(((uint16_t *)f->data)[6]);
+               f->type = BYTEORDER_HOST16(((uint16_t *)f->data)[6]);
 
                /*
                 * To every module receive function we pass a new fnode_t
index db68e76..4e1f693 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-bridge.h,v 1.1 2007/12/17 19:56:07 mmondor Exp $ */
+/* $Id: tap-bridge.h,v 1.2 2007/12/20 01:32:19 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef TAP_BRIDGE_H
+#define TAP_BRIDGE_H
+
+
 #include <time.h>
 
 #include <mmlist.h>
@@ -147,3 +151,6 @@ extern void         **key_create(const char *);
 extern void            **key_lookup(const char *);
 extern void            key_destroy(const char *);
 extern void            warning(int, const char *, ...);
+
+
+#endif
diff --git a/mmsoftware/tap-bridge/tap-endian.c b/mmsoftware/tap-bridge/tap-endian.c
new file mode 100644 (file)
index 0000000..3c7a04c
--- /dev/null
@@ -0,0 +1,69 @@
+/* $Id: tap-endian.c,v 1.1 2007/12/20 01:32:19 mmondor Exp $ */
+
+/*
+ * Copyright (C) 2004, 2007, Matthew Mondor
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Matthew Mondor.
+ * 4. The name of Matthew Mondor may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ * 5. Redistribution of source code may not be released under the terms of
+ *    any GNU Public License derivate.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``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 MATTHEW MONDOR 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 <stdint.h>
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+uint16_t
+byteorder_bswap16(uint16_t w)
+{
+       register uint16_t       wr = w;
+
+       return ((wr & 0xff00) >> 8 | (wr & 0x00ff) << 8);
+}
+
+uint32_t
+byteorder_bswap32(uint32_t w)
+{
+       register uint32_t       wr = w;
+
+       return ((wr & 0xff000000) >> 24 | (wr & 0x00ff0000) >> 8 |
+           (wr & 0x0000ff00) << 8 | (wr & 0x000000ff) << 24);
+}
+
+uint64_t
+byteorder_bswap64(uint64_t w)
+{
+       uint32_t        w1, w2;
+
+       w1 = byteorder_bswap32((w & 0xffffffff00000000LL) >> 32);
+       w2 = byteorder_bswap32((w & 0x00000000ffffffffLL));
+
+       return ((w2 & 0x00000000ffffffffLL) << 32 |
+           (w1 & 0x00000000ffffffffLL)); 
+}
+
+#endif
diff --git a/mmsoftware/tap-bridge/tap-endian.h b/mmsoftware/tap-bridge/tap-endian.h
new file mode 100644 (file)
index 0000000..c24f237
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id: tap-endian.h,v 1.1 2007/12/20 01:32:19 mmondor Exp $ */
+
+/*
+ * Copyright (C) 2004, 2007, Matthew Mondor
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Matthew Mondor.
+ * 4. The name of Matthew Mondor may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ * 5. Redistribution of source code may not be released under the terms of
+ *    any GNU Public License derivate.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``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 MATTHEW MONDOR 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 TAP_ENDIAN_H
+#define TAP_ENDIAN_H
+
+
+#include <stdint.h>
+
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+/* Little endian is not network order, we need conversions */
+#define BYTEORDER_NETWORK16    byteorder_bswap16
+#define BYTEORDER_HOST16       byteorder_bswap16
+#define BYTEORDER_NETWORK32    byteorder_bswap32
+#define BYTEORDER_HOST32       byteorder_bswap32
+#define BYTEORDER_NETWORK64    byteorder_bswap64
+#define BYTEORDER_HOST64       byteorder_bswap64
+
+extern uint16_t                byteorder_bswap16(uint16_t);
+extern uint32_t                byteorder_bswap32(uint32_t);
+extern uint64_t                byteorder_bswap64(uint64_t);
+
+#elif BYTE_ORDER == BIG_ENDIAN
+
+/* Big endian is network order, no need to do anything */
+#define BYTEORDER_NETWORK16(w) (w)
+#define BYTEORDER_HOST16(w)    (w)
+#define BYTEORDER_NETWORK32(w) (w)
+#define BYTEORDER_HOST32(w)    (w)
+#define BYTEORDER_NETWORK64(w) (w)
+#define BYTEORDER_HOST64(w)    (w)
+
+#else
+error "Undefined byte order (BYTE_ORDER)";
+#endif
+
+
+#endif
index 8e342ac..9b2fc62 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-headers.h,v 1.1 2007/12/17 19:56:07 mmondor Exp $ */
+/* $Id: tap-headers.h,v 1.2 2007/12/20 01:32:19 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * TODO:
+ * - Add DHCP
+ * - Add flags definitions
+ * - Add IP options definitions
+ * - Add TCP options structure/definitions
+ */
+
+#ifndef TAP_HEADERS_H
+#define TAP_HEADERS_H
+
+
 #include <stdint.h>
 
+#include <tap-endian.h>
+
+
+/*
+ * Frame
+ */
+
+/* A frame as presented by tap(4) and 32-bit padded by tap-bridge */
+struct hdr_tap {
+       uint8_t                 dstaddr[6];
+       uint8_t                 srcaddr[6];
+       uint16_t                ethertype;
+       uint16_t                unused;
+       /* Followed by protocol-specific header */
+} __attribute__((__packed__));
+
+#define HDR_TAP_ETYPE_IP       0x0800
+#define HDR_TAP_ETYPE_ARP      0x0806
+
 
 /*
  * ARP
  */
 
+/* General header */
 struct hdr_arp {
-       uint16_t        htype;
-       uint16_t        ptype;
-       uint8_t         hlen;
-       uint8_t         plen;
-       uint16_t        oper;
-};
+       uint16_t                htype;
+       uint16_t                ptype;
+       uint8_t                 hlen;
+       uint8_t                 plen;
+       uint16_t                oper;
+} __attribute__((__packed__));
 
 /* IPv4 -> MAC address resolution */
 struct hdr_arp_p4h {
-       struct hdr_arp  hdr;
-       uint8_t         sha[6];
-       uint32_t        spa;
-       uint8_t         tha[6];
-       uint32_t        tpa;
+       struct hdr_arp          hdr;
+       uint8_t                 sha[6];
+       uint32_t                spa;
+       uint8_t                 tha[6];
+       uint32_t                tpa;
 } __attribute__((__packed__));
 
 /* MAC -> IPv4 address resolution */
 struct hdr_arp_hp4 {
-       struct hdr_arp  hdr;
-       uint32_t        sha;
-       uint8_t         spa[6];
-       uint32_t        tha;
-       uint8_t         tpa[6];
+       struct hdr_arp          hdr;
+       uint32_t                sha;
+       uint8_t                 spa[6];
+       uint32_t                tha;
+       uint8_t                 tpa[6];
+} __attribute__((__packed__));
+
+
+/*
+ * IP
+ */
+
+/* Base structure without options */
+struct hdr_ip {
+/*     uint8_t                 ver:4, len:4; */
+       uint8_t                 ver_hlen;
+#define HDR_IP_VER_HLEN_SET(ver, hlen) \
+    (((ver) & 0x0f) << 4 | ((hlen) & 0x0f) & 0xff)
+#define HDR_IP_VER_GET(v)      (((v) & 0xf0) >> 4)
+#define HDR_IP_HLEN_GET(v)     ((v) & 0x0f)
+       uint8_t                 tos;
+       uint16_t                len;
+       uint16_t                id;
+/*     uint16_t                flags:3, off:13; */
+       uint16_t                flags_off;
+#define HDR_IP_FLAGS_OFF_SET(flags, off) \
+    (((flags) & 0x0007) << 12 | ((off) & 0x8fff) & 0xffff)
+#define HDR_IP_FLAGS_GET(v)    (((v) & 0x7000) >> 12)
+#define HDR_IP_OFF_GET(v)      ((v) & 0x8fff)
+       uint8_t                 ttl;
+       uint8_t                 protocol;
+       uint16_t                hsum;
+       uint32_t                srcaddr;
+       uint32_t                dstaddr;
+       /* Followed with options if any then by protocol-specific header */
+} __attribute__((__packed__));
+
+#define HDR_IP_PROTO_UDP       0x01
+#define HDR_IP_PROTO_TCP       0x06
+#define HDR_IP_PROTO_ICMP      0x11
+
+/* Options are 32-bit padded but have an 16-bit header */
+struct hdr_ip_opt {
+/*     uint8_t                 copy:1, class:2, number:5; */
+       uint8_t                 type;
+#define HDR_IPOPT_TYPE_SET(copy, class, number) \
+    (((copy) & 0x01) << 7 | ((class) & 0x03) << 5 | ((number) & 0x1f) & 0xff);
+#define HDR_IPOPT_COPY_GET(v)  (((v) & 0x80) >> 7)
+#define HDR_IPOPT_CLASS_GET(v) (((v) & 0x60) >> 5)
+#define HDR_IPOPT_NUMBER_GET(v)        ((v) & 0x1f)
+       uint8_t                 len;
+       /* Followed by 32-bit padded variable size data */
+} __attribute__((__packed__));
+
+/* ICMP, after hdr_ip and options */
+struct hdr_icmp {
+       uint8_t                 type;
+       uint8_t                 code;
+       uint16_t                hsum;
+       uint16_t                id;
+       uint16_t                seq;
+       /* Followed with arbitrary data */
+} __attribute__((__packed__));
+
+/* UDP, after hdr_ip and options */
+struct hdr_udp {
+       uint16_t                srcport;
+       uint16_t                dstport;
+       uint16_t                len;
+       uint16_t                hsum;
+} __attribute__((__packed__));
+
+/* TCP, after hdr_ip and options */
+struct hdr_tcp {
+       uint16_t                srcport;
+       uint16_t                dstport;
+       uint32_t                seq;
+       uint32_t                ack;
+/*     uint8_t                 doff:4, reserved:4; */
+       uint8_t                 doff_res;
+#define HDR_TCP_DOFF_RES_SET(doff, res) \
+    (((doff) & 0x0f) << 4 | ((res) & 0x0f) & 0xff)
+#define HDR_TCP_DOFF_GET(v)    (((v) & 0xf0) >> 4)
+#define HDR_TCP_RES_GET(v)     ((v) & 0x0f)
+       uint8_t                 flags;
+       uint16_t                window;
+       uint16_t                hsum;
+       uint16_t                urgptr;
+       /* Followed with options if any then data */
+} __attribute__((__packed__));
+
+struct hdr_tcp_opt {
+       /* XXX */
 } __attribute__((__packed__));
 
 
+#endif