12
|
1 /*
|
|
2 Packet extension for lwwire
|
|
3
|
|
4 Talks Layer 2, Ethernet Frames, sends them to a Linux TAP/TUN device.
|
|
5
|
|
6 TODO:
|
|
7 * better (any) RXMTU and TXMTU, Queue Length handling
|
|
8
|
|
9 */
|
|
10
|
|
11 #include <stdio.h>
|
|
12 #include "lwwire.h"
|
|
13
|
|
14 #include <unistd.h>
|
|
15 #include <string.h>
|
|
16 #include <ctype.h>
|
|
17 #include <sys/ioctl.h>
|
|
18 #include <sys/types.h>
|
|
19 #include <sys/stat.h>
|
|
20 #include <fcntl.h>
|
|
21 #include <sys/socket.h>
|
|
22 #include <linux/if.h>
|
|
23 #include <linux/if_tun.h>
|
|
24
|
|
25
|
|
26 #define MAX_FRAME 1526
|
|
27 static int tunfd = -1;
|
|
28 static char tundev[10];
|
|
29 static unsigned char opacket[MAX_FRAME];
|
|
30 static unsigned char packet[MAX_FRAME];
|
|
31 static int tunz = -1;
|
|
32 static unsigned char *packet_ptr;
|
|
33 static int csize = 511;
|
|
34 static int rxmtu = 1500;
|
|
35 static int txmtu = 1500;
|
|
36 static int qlen = 10;
|
|
37
|
|
38 /*
|
|
39
|
|
40 NOTE: the __attribute__((used)) tags are there to prevent the functions
|
|
41 from being optimized out as would often be the case with functions declared
|
|
42 static. This could be avoided by removing the static declarations. However,
|
|
43 by declaring everything static except for the lwwire_register() function,
|
|
44 we avoid polluting the global namespace and possibly having conflicts with
|
|
45 other extensions.
|
|
46 */
|
|
47
|
|
48
|
|
49 /* Allocate (open) a new tap device
|
|
50 Take symbolic name of device and tap/tun flags. Returns fd, or < 0 on
|
|
51 error.
|
|
52 */
|
|
53 static int tun_alloc(char *dev, int flags)
|
|
54 {
|
|
55 struct ifreq ifr;
|
|
56 int fd, err;
|
|
57 char *clonedev = "/dev/net/tun";
|
|
58
|
|
59 /* open the clone device */
|
|
60 if ((fd = open(clonedev, O_RDWR)) < 0)
|
|
61 {
|
|
62 perror("tun_alloc");
|
|
63 return fd;
|
|
64 }
|
|
65 /* preparation of the struct ifr, of type "struct ifreq" */
|
|
66 memset(&ifr, 0, sizeof(ifr));
|
|
67 ifr.ifr_flags = flags;
|
|
68 if (*dev)
|
|
69 {
|
|
70 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
|
71 }
|
|
72 /* try to create the device */
|
|
73 if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
|
|
74 {
|
|
75 perror("tun_alloc");
|
|
76 close(fd);
|
|
77 return err;
|
|
78 }
|
|
79 /* write acquired tap device name back to struct */
|
|
80 strcpy(dev, ifr.ifr_name);
|
|
81
|
|
82 nonblock(fd);
|
|
83 return fd;
|
|
84 }
|
|
85
|
|
86
|
|
87 /* Tell client how many bytes to expect for the next read. */
|
|
88 static int tun_proto_poll()
|
|
89 {
|
|
90 unsigned char buf[2];
|
|
91 while (1)
|
|
92 {
|
|
93 if (tunz < 1)
|
|
94 tunz = read(tunfd, packet, MAX_FRAME);
|
|
95 if (tunz < rxmtu)
|
|
96 break;
|
|
97 else
|
|
98 tunz = 0;
|
|
99 }
|
|
100 buf[0] = (unsigned char)(tunz >> 8);
|
|
101 buf[1] = (unsigned char)(tunz & 0xff);
|
|
102 lwwire_write(buf,2);
|
|
103 packet_ptr = packet;
|
|
104 return 0;
|
|
105 }
|
|
106
|
|
107 /* Drop the current packet */
|
|
108 static int tun_proto_drop()
|
|
109 {
|
|
110 tunz = 0;
|
|
111 return 0;
|
|
112 }
|
|
113
|
|
114
|
|
115 /* receive *entire* frame */
|
|
116 static int tun_proto_recv()
|
|
117 {
|
|
118 if (tunz < 1)
|
|
119 return -1;
|
|
120 lwwire_write(packet, tunz);
|
|
121 tunz = 0;
|
|
122 return 0;
|
|
123 }
|
|
124
|
|
125 /* receive next chunk (upto 511 bytes) of frame */
|
|
126 static int tun_proto_recv_chunk()
|
|
127 {
|
|
128 int s;
|
|
129 if (csize < tunz)
|
|
130 s = csize;
|
|
131 else
|
|
132 s = tunz;
|
|
133 lwwire_write(packet_ptr, s);
|
|
134 packet_ptr += s;
|
|
135 tunz -= s;
|
|
136 return 0;
|
|
137 }
|
|
138
|
|
139 /* send a frame */
|
|
140 static int tun_proto_send()
|
|
141 {
|
|
142 int len;
|
|
143 unsigned char buf[2];
|
|
144 if (lwwire_read(buf, 2) < 0)
|
|
145 return -1;
|
|
146 len = (buf[0]<<8) + buf[1];
|
|
147 if (lwwire_read(opacket, len) < 0)
|
|
148 return -1;
|
|
149 if (write(tunfd, opacket, len) < 0)
|
|
150 return -1;
|
|
151 return 0;
|
|
152 }
|
|
153
|
|
154
|
|
155 /* set/return receive mtu */
|
|
156 static int tun_proto_setrxmtu()
|
|
157 {
|
14
|
158 unsigned int val;
|
12
|
159 unsigned char buf[2];
|
|
160 if (lwwire_read(buf, 2) < 0)
|
|
161 return -1;
|
14
|
162 val = (buf[0] << 8) + buf[1];
|
|
163 if (val)
|
|
164 {
|
|
165 rxmtu = val;
|
|
166 }
|
|
167 else
|
|
168 {
|
|
169 buf[0] = rxmtu >> 8;
|
|
170 buf[1] = rxmtu & 255;
|
|
171 }
|
12
|
172 lwwire_write(buf, 2);
|
|
173 return 0;
|
|
174 }
|
|
175
|
|
176 /* set/return transmit mtu */
|
|
177 static int tun_proto_settxmtu()
|
|
178 {
|
14
|
179 unsigned int val;
|
12
|
180 unsigned char buf[2];
|
|
181 if (lwwire_read(buf, 2) < 0)
|
|
182 return -1;
|
14
|
183 val = (buf[0] << 8) + buf[1];
|
|
184 if (val)
|
|
185 {
|
|
186 txmtu = val;
|
|
187 }
|
|
188 else
|
|
189 {
|
|
190 buf[0] = txmtu >> 8;
|
|
191 buf[1] = txmtu & 255;
|
|
192 }
|
12
|
193 lwwire_write(buf, 2);
|
|
194 return 0;
|
|
195 }
|
|
196
|
14
|
197 /* set/return queue length */
|
12
|
198 static int tun_proto_setqlen()
|
|
199 {
|
|
200 unsigned char buf[1];
|
|
201 if (lwwire_read(buf, 1) < 0)
|
|
202 return -1;
|
14
|
203 if (buf[0])
|
|
204 {
|
|
205 qlen = buf[0];
|
|
206 }
|
|
207 else
|
|
208 {
|
|
209 buf[0] = qlen;
|
|
210 }
|
12
|
211 lwwire_write(buf, 1);
|
|
212 return 0;
|
|
213 }
|
|
214
|
|
215
|
|
216
|
|
217 // this is called to handle an operation for this extension
|
|
218 // it should return nonzero if the operation code (op) is not
|
|
219 // supported. Otherwise, it should implement the operation codes.
|
|
220 __attribute__((used)) static int packet_handler(int op)
|
|
221 {
|
|
222 switch (op)
|
|
223 {
|
|
224 case 0:
|
|
225 return tun_proto_poll();
|
|
226 case 1:
|
|
227 return tun_proto_recv();
|
|
228 case 2:
|
|
229 return tun_proto_send();
|
|
230 case 3:
|
|
231 return tun_proto_drop();
|
|
232 case 4:
|
|
233 return tun_proto_setrxmtu();
|
|
234 case 5:
|
|
235 return tun_proto_setqlen();
|
|
236 case 6:
|
|
237 return tun_proto_settxmtu();
|
|
238 case 7:
|
|
239 return tun_proto_recv_chunk();
|
|
240 default:
|
|
241 return -1;
|
|
242 }
|
|
243 return 0;
|
|
244 }
|
|
245
|
|
246 // this will be called when the extension is enabled
|
|
247 // return nonzero if enabling the extension cannot happen for some reason
|
|
248 __attribute__((used)) static int packet_enable(void)
|
|
249 {
|
|
250 if (tunfd < 0)
|
|
251 {
|
|
252 strcpy(tundev, "tap0");
|
|
253 tunfd = tun_alloc(tundev, IFF_TAP | IFF_NO_PI);
|
|
254 if (tunfd < 0) return -1;
|
|
255 tunz = -1;
|
|
256 }
|
|
257 return 0;
|
|
258 }
|
|
259
|
|
260 // this will be called when an extension is disabled
|
|
261 // if this extension cannot be disabled after it is enabled, it should return
|
|
262 // nonzero; otherwise, this MUST succeed
|
|
263 __attribute__((used)) static int packet_disable(void)
|
|
264 {
|
|
265 close(tunfd);
|
|
266 tunfd = -1;
|
|
267 return 0;
|
|
268 }
|
|
269
|
|
270 // this call should do anything needed to disable the extension
|
|
271 // and anything special that might be needed on a protocol reset
|
|
272 // it will only be called if the extension is enabled when the
|
|
273 // reset occurs. Even if the extension isn't disablable, this call
|
|
274 // MUST disable it and reset things as if the extension was never
|
|
275 // enabled.
|
|
276 __attribute__((used)) static void packet_reset(void)
|
|
277 {
|
|
278 packet_disable();
|
|
279 }
|
|
280
|
|
281 int lwwire_register(void)
|
|
282 {
|
|
283 fprintf(stderr, "Registering PACKET extension\n");
|
|
284 return lwwire_register_extension(0x01, packet_handler, packet_enable, packet_disable, packet_reset);
|
|
285 }
|