Initial import of tap-bridge
[mmondor.git] / mmsoftware / tap-bridge / tap-bridge.h
CommitLineData
12f87502
MM
1/* $Id: tap-bridge.h,v 1.1 2007/12/17 19:56:07 mmondor Exp $ */
2
3/*
4 * Copyright (C) 2007, Matthew Mondor
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Matthew Mondor.
18 * 4. The name of Matthew Mondor may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 * 5. Redistribution of source code may not be released under the terms of
22 * any GNU Public License derivate.
23 *
24 * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include <time.h>
37
38#include <mmlist.h>
39#include <mmpool.h>
40
41
42#define MTU 1500
43/*
44 * tap(4) provides us with the ethernet header but not the checksum
45 * Bytes 0-5 dstmac, 6-11 srcmac, 12-13 ethertype, and we add our header
46 * 14-15 32-bit padding bytes.
47 */
48#define FRAMESIZE (MTU + 14 + 2)
49#define TIMER_HZ 10
50
51
52typedef uint64_t macaddr_t;
53typedef struct tap tap_t;
54typedef struct frame frame_t;
55typedef struct fnode fnode_t;
56typedef struct module module_t;
57typedef struct modnode modnode_t;
58
59/*
60 * Represents a tap(4) interface.
61 */
62struct tap {
63 char *name;
64 int fd;
65 macaddr_t mac;
66 list_t sendq, schedq;
67};
68
69/*
70 * Holds an ethernet frame. A reference count allows multiple fnode_t objects
71 * to represent this frame_t object.
72 */
73struct frame {
74 pnode_t node;
75 macaddr_t origin, destination;
76 struct timeval received;
77 size_t size;
78 uint16_t type;
79 uint8_t *data;
80 int refcount;
81};
82
83/*
84 * Passed to module receive callback functions so that each may have its own
85 * copy it can queue or discard as it wishes.
86 */
87struct fnode {
88 pnode_t node;
89 frame_t *frame;
90 struct timeval scheduled;
91};
92
93/*
94 * Every filter module must provide this structure, named "module".
95 * <init> must hold the module's initialization code and will be called at
96 * module loading time.
97 * <recv> will we passed an fnode_t representing a frame_t for every received
98 * frame from the tap(4) interface. The module may defer any
99 * processing by destroying the node and returning true. It may drop
100 * the frame_t by destroying the node and returning false. It may
101 * use frame_send() to send it on a tap_t. It also may queue its
102 * fnode_t as wanted via its pnode_t's node_t. The underlaying frame_t
103 * will only ever be destroyed when all fnode_t representing it are
104 * destroyed.
105 * <tick> is optional and may be NULL. If a function is provided it will get
106 * called every tap-bridge scheduling round (at a frequency of
107 * TIMER_HZ).
108 * <exit> invoked when the module is unloaded. Should free any resources it
109 * holds.
110 * XXX I should provide a means for module to be able to keep persistent
111 * resources. For instance, the logging module may want to keep its opened
112 * fifo file open as it doesn't want the reader to receive an EOF.
113 * However, the only safe way to do this using a decent API might be to
114 * provide named keys looked up in a hash table for modules to use.
115 * If every module has a unique persistent identifier this could also be
116 * done... we could use the module name as a key for instance, and provide a
117 * void ** to the init function which it may use however it wishes.
118 * If doing this, we perhaps also want to provide an application global shared
119 * pointer to modules as well which might be good for particular applications.
120 * A general purpose named keys system would allow them to do both...
121 */
122struct module {
123 bool (*init)(tap_t *, tap_t *);
124 bool (*recv_int)(tap_t *, fnode_t *);
125 bool (*recv_ext)(tap_t *, fnode_t *);
126 void (*tick)(struct timeval *);
127 void (*exit)(void);
128};
129
130struct modnode {
131 pnode_t node;
132 void *handle;
133 module_t *module;
134};
135
136extern frame_t *frame_new(void);
137extern fnode_t *fnode_new(frame_t *);
138extern void fnode_destroy(fnode_t *);
139extern size_t macaddr_string(char *, size_t, macaddr_t *);
140extern void frame_send(tap_t *, fnode_t *);
141extern void frame_schedule(tap_t *, fnode_t *,
142 const struct timeval *);
143extern void *time_setcallback(void (*)(const struct timeval *));
144extern void *recv_setcallback(tap_t *,
145 void (*)(tap_t *, frame_t *));
146extern void **key_create(const char *);
147extern void **key_lookup(const char *);
148extern void key_destroy(const char *);
149extern void warning(int, const char *, ...);