nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /*
2 * Copyright (c) 2007, 2008, Andrea Bittau <a.bittau@cs.ucl.ac.uk>
3 *
4 * OS dependent API for using card via network.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20  
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <assert.h>
30 #include <sys/select.h>
31 #include <errno.h>
32  
33 #include "osdep.h"
34 #include "network.h"
35  
36 #define QUEUE_MAX 666
37  
38 struct netqueue {
39 unsigned char q_buf[2048];
40 int q_len;
41  
42 struct netqueue *q_next;
43 struct netqueue *q_prev;
44 };
45  
46 struct priv_net {
47 int pn_s;
48 struct netqueue pn_queue;
49 struct netqueue pn_queue_free;
50 int pn_queue_len;
51 };
52  
53 int net_send(int s, int command, void *arg, int len)
54 {
55 struct net_hdr *pnh;
56 char *pktbuf;
57 size_t pktlen;
58  
59 pktlen = sizeof(struct net_hdr) + len;
60  
61 pktbuf = (char*)calloc(sizeof(char), pktlen);
62 if (pktbuf == NULL) {
63 perror("calloc");
64 goto net_send_error;
65 }
66  
67 pnh = (struct net_hdr*)pktbuf;
68 pnh->nh_type = command;
69 pnh->nh_len = htonl(len);
70  
71 memcpy(pktbuf + sizeof(struct net_hdr), arg, len);
72  
73 for (;;) {
74 ssize_t rc = send(s, pktbuf, pktlen, 0);
75  
76 if ((size_t)rc == pktlen)
77 break;
78  
79 if (rc == EAGAIN || rc == EWOULDBLOCK || rc == EINTR)
80 continue;
81  
82 if (rc == ECONNRESET)
83 printf("Connection reset while sending packet!\n");
84  
85 goto net_send_error;
86 }
87  
88 free(pktbuf);
89 return 0;
90  
91 net_send_error:
92 free(pktbuf);
93 return -1;
94 }
95  
96 int net_read_exact(int s, void *arg, int len)
97 {
98 ssize_t rc;
99 int rlen = 0;
100 char *buf = (char*)arg;
101 while (rlen < len) {
102 rc = recv(s, buf, (len - rlen), 0);
103  
104 if (rc < 1) {
105 if (rc == -1 && (errno == EAGAIN || errno == EINTR)) {
106 usleep(100);
107 continue;
108 }
109  
110 return -1;
111 }
112  
113 buf += rc;
114 rlen += rc;
115 }
116  
117 return 0;
118 }
119  
120 int net_get(int s, void *arg, int *len)
121 {
122 struct net_hdr nh;
123 int plen;
124  
125 if (net_read_exact(s, &nh, sizeof(nh)) == -1)
126 {
127 return -1;
128 }
129  
130 plen = ntohl(nh.nh_len);
131 if (!(plen <= *len))
132 printf("PLEN %d type %d len %d\n",
133 plen, nh.nh_type, *len);
134 assert(plen <= *len && plen >= 0);
135  
136 *len = plen;
137 if ((*len) && (net_read_exact(s, arg, *len) == -1))
138 {
139 return -1;
140 }
141  
142 return nh.nh_type;
143 }
144  
145 static void queue_del(struct netqueue *q)
146 {
147 q->q_prev->q_next = q->q_next;
148 q->q_next->q_prev = q->q_prev;
149 }
150  
151 static void queue_add(struct netqueue *head, struct netqueue *q)
152 {
153 struct netqueue *pos = head->q_prev;
154  
155 q->q_prev = pos;
156 q->q_next = pos->q_next;
157 q->q_next->q_prev = q;
158 pos->q_next = q;
159 }
160  
161 #if 0
162 static int queue_len(struct netqueue *head)
163 {
164 struct netqueue *q = head->q_next;
165 int i = 0;
166  
167 while (q != head) {
168 i++;
169 q = q->q_next;
170 }
171  
172 return i;
173 }
174 #endif
175  
176 static struct netqueue *queue_get_slot(struct priv_net *pn)
177 {
178 struct netqueue *q = pn->pn_queue_free.q_next;
179  
180 if (q != &pn->pn_queue_free) {
181 queue_del(q);
182 return q;
183 }
184  
185 if (pn->pn_queue_len++ > QUEUE_MAX)
186 return NULL;
187  
188 return malloc(sizeof(*q));
189 }
190  
191 static void net_enque(struct priv_net *pn, void *buf, int len)
192 {
193 struct netqueue *q;
194  
195 q = queue_get_slot(pn);
196 if (!q)
197 return;
198  
199 q->q_len = len;
200 assert((int) sizeof(q->q_buf) >= q->q_len);
201 memcpy(q->q_buf, buf, q->q_len);
202 queue_add(&pn->pn_queue, q);
203 }
204  
205 static int net_get_nopacket(struct priv_net *pn, void *arg, int *len)
206 {
207 unsigned char buf[2048];
208 int l = sizeof(buf);
209 int c;
210  
211 while (1) {
212 l = sizeof(buf);
213 c = net_get(pn->pn_s, buf, &l);
214 if (c < 0)
215 return c;
216  
217 if (c != NET_PACKET && c > 0)
218 break;
219  
220 if(c > 0)
221 net_enque(pn, buf, l);
222 }
223  
224 assert(l <= *len);
225 memcpy(arg, buf, l);
226 *len = l;
227  
228 return c;
229 }
230  
231 static int net_cmd(struct priv_net *pn, int command, void *arg, int alen)
232 {
233 uint32_t rc;
234 int len;
235 int cmd;
236  
237 if (net_send(pn->pn_s, command, arg, alen) == -1)
238 {
239 return -1;
240 }
241  
242 len = sizeof(rc);
243 cmd = net_get_nopacket(pn, &rc, &len);
244 if (cmd == -1)
245 {
246 return -1;
247 }
248 assert(cmd == NET_RC);
249 assert(len == sizeof(rc));
250  
251 return ntohl(rc);
252 }
253  
254 static int queue_get(struct priv_net *pn, void *buf, int len)
255 {
256 struct netqueue *head = &pn->pn_queue;
257 struct netqueue *q = head->q_next;
258  
259 if (q == head)
260 return 0;
261  
262 assert(q->q_len <= len);
263 memcpy(buf, q->q_buf, q->q_len);
264  
265 queue_del(q);
266 queue_add(&pn->pn_queue_free, q);
267  
268 return q->q_len;
269 }
270  
271 static int net_read(struct wif *wi, unsigned char *h80211, int len,
272 struct rx_info *ri)
273 {
274 struct priv_net *pn = wi_priv(wi);
275 uint32_t buf[512]; // 512 * 4 = 2048
276 unsigned char *bufc = (unsigned char*)buf;
277 int cmd;
278 int sz = sizeof(*ri);
279 int l;
280 int ret;
281  
282 /* try queue */
283 l = queue_get(pn, buf, sizeof(buf));
284 if (!l) {
285 /* try reading form net */
286 l = sizeof(buf);
287 cmd = net_get(pn->pn_s, buf, &l);
288  
289 if (cmd == -1)
290 return -1;
291 if (cmd == NET_RC)
292 {
293 ret = ntohl((buf[0]));
294 return ret;
295 }
296 assert(cmd == NET_PACKET);
297 }
298  
299 /* XXX */
300 if (ri) {
301 // re-assemble 64-bit integer
302 ri->ri_mactime = __be64_to_cpu(((uint64_t)buf[0] << 32 || buf[1] ));
303 ri->ri_power = __be32_to_cpu(buf[2]);
304 ri->ri_noise = __be32_to_cpu(buf[3]);
305 ri->ri_channel = __be32_to_cpu(buf[4]);
306 ri->ri_freq = __be32_to_cpu(buf[5]);
307 ri->ri_rate = __be32_to_cpu(buf[6]);
308 ri->ri_antenna = __be32_to_cpu(buf[7]);
309 }
310 l -= sz;
311 assert(l > 0);
312 if (l > len)
313 l = len;
314 memcpy(h80211, &bufc[sz], l);
315  
316 return l;
317 }
318  
319 static int net_get_mac(struct wif *wi, unsigned char *mac)
320 {
321 struct priv_net *pn = wi_priv(wi);
322 uint32_t buf[2]; // only need 6 bytes, this provides 8
323 int cmd;
324 int sz = 6;
325  
326 if (net_send(pn->pn_s, NET_GET_MAC, NULL, 0) == -1)
327 return -1;
328  
329 cmd = net_get_nopacket(pn, buf, &sz);
330 if (cmd == -1)
331 return -1;
332 if (cmd == NET_RC)
333 return ntohl(buf[0]);
334 assert(cmd == NET_MAC);
335 assert(sz == 6);
336  
337 memcpy(mac, buf, 6);
338  
339 return 0;
340 }
341  
342 static int net_write(struct wif *wi, unsigned char *h80211, int len,
343 struct tx_info *ti)
344 {
345 struct priv_net *pn = wi_priv(wi);
346 int sz = sizeof(*ti);
347 unsigned char buf[2048];
348 unsigned char *ptr = buf;
349  
350 /* XXX */
351 if (ti)
352 memcpy(ptr, ti, sz);
353 else
354 memset(ptr, 0, sizeof(*ti));
355  
356 ptr += sz;
357 memcpy(ptr, h80211, len);
358 sz += len;
359  
360 return net_cmd(pn, NET_WRITE, buf, sz);
361 }
362  
363 static int net_set_channel(struct wif *wi, int chan)
364 {
365 uint32_t c = htonl(chan);
366  
367 return net_cmd(wi_priv(wi), NET_SET_CHAN, &c, sizeof(c));
368 }
369  
370 static int net_get_channel(struct wif *wi)
371 {
372 struct priv_net *pn = wi_priv(wi);
373  
374 return net_cmd(pn, NET_GET_CHAN, NULL, 0);
375 }
376  
377 static int net_set_rate(struct wif *wi, int rate)
378 {
379 uint32_t c = htonl(rate);
380  
381 return net_cmd(wi_priv(wi), NET_SET_RATE, &c, sizeof(c));
382 }
383  
384 static int net_get_rate(struct wif *wi)
385 {
386 struct priv_net *pn = wi_priv(wi);
387  
388 return net_cmd(pn, NET_GET_RATE, NULL, 0);
389 }
390  
391 static int net_get_monitor(struct wif *wi)
392 {
393 return net_cmd(wi_priv(wi), NET_GET_MONITOR, NULL, 0);
394 }
395  
396 static void do_net_free(struct wif *wi)
397 {
398 assert(wi->wi_priv);
399 free(wi->wi_priv);
400 wi->wi_priv = 0;
401 free(wi);
402 }
403  
404 static void net_close(struct wif *wi)
405 {
406 struct priv_net *pn = wi_priv(wi);
407  
408 close(pn->pn_s);
409 do_net_free(wi);
410 }
411  
412 static int get_ip_port(char *iface, char *ip, const int ipsize)
413 {
414 char *host;
415 char *ptr;
416 int port = -1;
417 struct in_addr addr;
418  
419 host = strdup(iface);
420 if (!host)
421 return -1;
422  
423 ptr = strchr(host, ':');
424 if (!ptr)
425 goto out;
426  
427 *ptr++ = 0;
428  
429 if (!inet_aton(host, &addr))
430 goto out; /* XXX resolve hostname */
431  
432 assert(strlen(host) <= 15);
433 strncpy(ip, host, ipsize);
434 port = atoi(ptr);
435  
436 out:
437 free(host);
438 return port;
439 }
440  
441 static int handshake(int s)
442 {
443 if (s) {} /* XXX unused */
444 /* XXX do a handshake */
445 return 0;
446 }
447  
448 static int do_net_open(char *iface)
449 {
450 int s, port;
451 char ip[16];
452 struct sockaddr_in s_in;
453  
454 port = get_ip_port(iface, ip, sizeof(ip)-1);
455 if (port == -1)
456 return -1;
457  
458 s_in.sin_family = PF_INET;
459 s_in.sin_port = htons(port);
460 if (!inet_aton(ip, &s_in.sin_addr))
461 return -1;
462  
463 if ((s = socket(s_in.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
464 return -1;
465  
466 printf("Connecting to %s port %d...\n", ip, port);
467  
468 if (connect(s, (struct sockaddr*) &s_in, sizeof(s_in)) == -1) {
469 close(s);
470  
471 printf("Failed to connect\n");
472  
473 return -1;
474 }
475  
476 if (handshake(s) == -1) {
477 close(s);
478  
479 printf("Failed to connect - handshake failed\n");
480  
481 return -1;
482 }
483  
484 printf("Connection successful\n");
485  
486 return s;
487 }
488  
489 static int net_fd(struct wif *wi)
490 {
491 struct priv_net *pn = wi_priv(wi);
492  
493 return pn->pn_s;
494 }
495  
496 struct wif *net_open(char *iface)
497 {
498 struct wif *wi;
499 struct priv_net *pn;
500 int s;
501  
502 /* setup wi struct */
503 wi = wi_alloc(sizeof(*pn));
504 if (!wi)
505 return NULL;
506 wi->wi_read = net_read;
507 wi->wi_write = net_write;
508 wi->wi_set_channel = net_set_channel;
509 wi->wi_get_channel = net_get_channel;
510 wi->wi_set_rate = net_set_rate;
511 wi->wi_get_rate = net_get_rate;
512 wi->wi_close = net_close;
513 wi->wi_fd = net_fd;
514 wi->wi_get_mac = net_get_mac;
515 wi->wi_get_monitor = net_get_monitor;
516  
517 /* setup iface */
518 s = do_net_open(iface);
519 if (s == -1) {
520 do_net_free(wi);
521 return NULL;
522 }
523  
524 /* setup private state */
525 pn = wi_priv(wi);
526 pn->pn_s = s;
527 pn->pn_queue.q_next = pn->pn_queue.q_prev = &pn->pn_queue;
528 pn->pn_queue_free.q_next = pn->pn_queue_free.q_prev
529 = &pn->pn_queue_free;
530  
531 return wi;
532 }