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 {
|
|
158 unsigned char buf[2];
|
|
159 if (lwwire_read(buf, 2) < 0)
|
|
160 return -1;
|
|
161 rxmtu = (buf[0]<<8) + buf[1];
|
|
162 lwwire_write(buf, 2);
|
|
163 return 0;
|
|
164 }
|
|
165
|
|
166 /* set/return transmit mtu */
|
|
167 static int tun_proto_settxmtu()
|
|
168 {
|
|
169 unsigned char buf[2];
|
|
170 if (lwwire_read(buf, 2) < 0)
|
|
171 return -1;
|
|
172 txmtu = (buf[0]<<8) + buf[1];
|
|
173 lwwire_write(buf, 2);
|
|
174 return 0;
|
|
175 }
|
|
176
|
|
177 /* set/return receive mtu */
|
|
178 static int tun_proto_setqlen()
|
|
179 {
|
|
180 unsigned char buf[1];
|
|
181 if (lwwire_read(buf, 1) < 0)
|
|
182 return -1;
|
|
183 qlen = buf[0];
|
|
184 lwwire_write(buf, 1);
|
|
185 return 0;
|
|
186 }
|
|
187
|
|
188
|
|
189
|
|
190 // this is called to handle an operation for this extension
|
|
191 // it should return nonzero if the operation code (op) is not
|
|
192 // supported. Otherwise, it should implement the operation codes.
|
|
193 __attribute__((used)) static int packet_handler(int op)
|
|
194 {
|
|
195 switch (op)
|
|
196 {
|
|
197 case 0:
|
|
198 return tun_proto_poll();
|
|
199 case 1:
|
|
200 return tun_proto_recv();
|
|
201 case 2:
|
|
202 return tun_proto_send();
|
|
203 case 3:
|
|
204 return tun_proto_drop();
|
|
205 case 4:
|
|
206 return tun_proto_setrxmtu();
|
|
207 case 5:
|
|
208 return tun_proto_setqlen();
|
|
209 case 6:
|
|
210 return tun_proto_settxmtu();
|
|
211 case 7:
|
|
212 return tun_proto_recv_chunk();
|
|
213 default:
|
|
214 return -1;
|
|
215 }
|
|
216 return 0;
|
|
217 }
|
|
218
|
|
219 // this will be called when the extension is enabled
|
|
220 // return nonzero if enabling the extension cannot happen for some reason
|
|
221 __attribute__((used)) static int packet_enable(void)
|
|
222 {
|
|
223 if (tunfd < 0)
|
|
224 {
|
|
225 strcpy(tundev, "tap0");
|
|
226 tunfd = tun_alloc(tundev, IFF_TAP | IFF_NO_PI);
|
|
227 if (tunfd < 0) return -1;
|
|
228 tunz = -1;
|
|
229 }
|
|
230 return 0;
|
|
231 }
|
|
232
|
|
233 // this will be called when an extension is disabled
|
|
234 // if this extension cannot be disabled after it is enabled, it should return
|
|
235 // nonzero; otherwise, this MUST succeed
|
|
236 __attribute__((used)) static int packet_disable(void)
|
|
237 {
|
|
238 close(tunfd);
|
|
239 tunfd = -1;
|
|
240 return 0;
|
|
241 }
|
|
242
|
|
243 // this call should do anything needed to disable the extension
|
|
244 // and anything special that might be needed on a protocol reset
|
|
245 // it will only be called if the extension is enabled when the
|
|
246 // reset occurs. Even if the extension isn't disablable, this call
|
|
247 // MUST disable it and reset things as if the extension was never
|
|
248 // enabled.
|
|
249 __attribute__((used)) static void packet_reset(void)
|
|
250 {
|
|
251 packet_disable();
|
|
252 }
|
|
253
|
|
254 int lwwire_register(void)
|
|
255 {
|
|
256 fprintf(stderr, "Registering PACKET extension\n");
|
|
257 return lwwire_register_extension(0x01, packet_handler, packet_enable, packet_disable, packet_reset);
|
|
258 }
|