*** empty log message ***
[mmondor.git] / mmsoftware / tap-bridge / modules / tap-logger.c
1 /* $Id: tap-logger.c,v 1.5 2007/12/24 03:16:21 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 <errno.h>
37 #include <stdarg.h>
38 #include <stdint.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41
42 #include <tap-bridge.h>
43 #include <tap-headers.h>
44
45
46 static bool mod_init(tap_t *, tap_t *);
47 static bool mod_recv_int(tap_t *, fnode_t *);
48 static bool mod_recv_ext(tap_t *, fnode_t *);
49 static void mod_exit(void);
50
51 static void logprintf(const char *, ...);
52 static void frame_log(frame_t *, int);
53
54
55 module_t module = {
56 mod_init,
57 mod_recv_int,
58 mod_recv_ext,
59 NULL,
60 mod_exit
61 };
62
63
64 static tap_t *tap_int, *tap_ext;
65 static FILE *logfh = NULL;
66
67
68 static bool
69 mod_init(tap_t *tap_i, tap_t *tap_e)
70 {
71 void **udata;
72
73 tap_int = tap_i;
74 tap_ext = tap_e;
75
76 if ((udata = key_lookup("tap_logger_file")) == NULL) {
77 if ((udata = key_create("tap_logger_file")) == NULL)
78 return false;
79 if ((logfh = fopen("/tmp/tap-filter.log", "a")) == NULL) {
80 key_destroy("tap_logger_file");
81 warning(errno, "fopen(/tmp/tap-filter.log)");
82 return false;
83 }
84 (void) setvbuf(logfh, NULL, _IOLBF, 0);
85
86 *udata = logfh;
87 } else
88 logfh = *udata;
89
90 return true;
91 }
92
93 static bool
94 mod_recv_int(tap_t *tap, fnode_t *n)
95 {
96
97 frame_log(n->frame, '<');
98 fnode_destroy(n);
99 return true;
100 }
101
102 static bool
103 mod_recv_ext(tap_t *tap, fnode_t *n)
104 {
105
106 frame_log(n->frame, '>');
107 fnode_destroy(n);
108 return true;
109 }
110
111 static void
112 mod_exit(void)
113 {
114
115 /* NOOP */
116 }
117
118
119 static void
120 logprintf(const char *fmt, ...)
121 {
122 va_list lst;
123
124 va_start(lst, fmt);
125 (void) vfprintf(logfh, fmt, lst);
126 va_end(lst);
127 }
128
129 static void
130 frame_log(frame_t *f, int d)
131 {
132 char origin[32], destination[32];
133 struct hdr_tap *hdrtap = (struct hdr_tap *)f->data;
134 void *ahdrtap = &hdrtap[1];
135
136 if (f->size < sizeof(struct hdr_tap)) {
137 logprintf("%c Short ethernet frame: size=%u\n", d, f->size);
138 return;
139 }
140
141 (void) macaddr_string(origin, 31, &f->origin);
142 (void) macaddr_string(destination, 31, &f->destination);
143 logprintf("%c src=%s, dst=%s etype=%04x size=%u\n",
144 d, origin, destination, f->type, f->size);
145
146 /*
147 * Orignally used switch/case but if proves to be cleaner because of
148 * required variables, while requireing less indentation levels.
149 */
150 if (f->type == HDR_TAP_ETYPE_ARP) {
151 struct hdr_arp *hdrarp;
152
153 if (f->size < sizeof(struct hdr_tap) +
154 sizeof(struct hdr_arp)) {
155 logprintf(" Short ARP header\n");
156 return;
157 }
158 hdrarp = ahdrtap;
159 /* XXX */
160
161 return;
162 }
163
164 if (f->type == HDR_TAP_ETYPE_IP) {
165 struct hdr_ip *hdrip;
166 uint16_t t;
167 int ver, hlen, flags, off;
168 void *ahdrip;
169
170 if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_ip)) {
171 logprintf(" Short IP header\n");
172 return;
173 }
174 hdrip = ahdrtap;
175
176 t = BYTEORDER_HOST16(hdrip->ver_hlen);
177 ver = HDR_IP_VER_GET(t);
178 hlen = HDR_IP_HLEN_GET(t);
179 if (hlen < 4) {
180 logprintf(" Short IP header length (%d)\n", hlen);
181 return;
182 }
183 ahdrip = &((uint32_t *)hdrip)[hlen];
184
185 t = BYTEORDER_HOST16(hdrip->flags_off);
186 flags = HDR_IP_FLAGS_GET(t);
187 off = HDR_IP_OFF_GET(t);
188
189 /* XXX */
190
191 if (hdrip->protocol == HDR_IP_PROTO_UDP) {
192 return;
193 }
194
195 if (hdrip->protocol == HDR_IP_PROTO_TCP) {
196 return;
197 }
198
199 if (hdrip->protocol == HDR_IP_PROTO_ICMP) {
200 return;
201 }
202
203 logprintf(" Unsupported IP protocol (0x%02x)\n",
204 hdrip->protocol);
205 return;
206 }
207
208 logprintf(" Unsupported ethertype (0x%04x)\n", f->type);
209 }