~alza/proyek-uvt/aircrack-ng

« back to all changes in this revision

Viewing changes to src/wpaclean.c

  • Committer: Raviyanto Ahmad
  • Date: 2013-09-08 01:01:56 UTC
  • Revision ID: git-v1:b6383050c4f79f8ded5bfbe9ecf393ab24773010
Komit pertama WiFi Crack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2011 Andrea Bittau <bittau@cs.stanford.edu>
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 *
 
18
 *
 
19
 *  In addition, as a special exception, the copyright holders give
 
20
 *  permission to link the code of portions of this program with the
 
21
 *  OpenSSL library under certain conditions as described in each
 
22
 *  individual source file, and distribute linked combinations
 
23
 *  including the two.
 
24
 *  You must obey the GNU General Public License in all respects
 
25
 *  for all of the code used other than OpenSSL. *  If you modify
 
26
 *  file(s) with this exception, you may extend this exception to your
 
27
 *  version of the file(s), but you are not obligated to do so. *  If you
 
28
 *  do not wish to do so, delete this exception statement from your
 
29
 *  version. *  If you delete this exception statement from all source
 
30
 *  files in the program, then also delete it here.
 
31
 */
 
32
 
 
33
#include <sys/types.h>
 
34
#include <sys/stat.h>
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
#include <assert.h>
 
39
#include <unistd.h>
 
40
#include <fcntl.h>
 
41
#include <err.h>
 
42
 
 
43
#include "aircrack-ng.h"
 
44
#include "version.h"
 
45
#include "aircrack-ptw-lib.h"
 
46
#include "osdep/osdep.h"
 
47
#include "ieee80211.h"
 
48
#include "crypto.h"
 
49
#include "pcap.h"
 
50
 
 
51
static uchar ZERO[32] =
 
52
"\x00\x00\x00\x00\x00\x00\x00\x00"
 
53
"\x00\x00\x00\x00\x00\x00\x00\x00"
 
54
"\x00\x00\x00\x00\x00\x00\x00\x00"
 
55
"\x00\x00\x00\x00\x00\x00\x00\x00";
 
56
 
 
57
struct packet {
 
58
        unsigned char   p_data[2048];
 
59
        int             p_len;
 
60
};
 
61
 
 
62
struct client {
 
63
        unsigned char   c_mac[6];
 
64
        int             c_wpa;
 
65
        int             c_wpa_got;
 
66
        struct packet   c_handshake[4];
 
67
        struct client   *c_next;
 
68
};
 
69
 
 
70
struct network {
 
71
        unsigned char   n_bssid[6];
 
72
        unsigned char   n_beacon[2048];
 
73
        int             n_beaconlen;
 
74
        char            n_ssid[256];
 
75
        struct client   n_clients;
 
76
        struct client   *n_handshake;
 
77
        struct network  *n_next;
 
78
} _networks;
 
79
 
 
80
static int _outfd;
 
81
 
 
82
static int open_pcap(char *fname)
 
83
{       
 
84
        int fd;
 
85
        struct pcap_file_header pfh;
 
86
 
 
87
        memset(&pfh, 0, sizeof(pfh));
 
88
        pfh.magic           = TCPDUMP_MAGIC;
 
89
        pfh.version_major   = PCAP_VERSION_MAJOR;
 
90
        pfh.version_minor   = PCAP_VERSION_MINOR;
 
91
        pfh.thiszone        = 0;
 
92
        pfh.sigfigs         = 0;
 
93
        pfh.snaplen         = 65535;
 
94
        pfh.linktype        = LINKTYPE_IEEE802_11;
 
95
 
 
96
        fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC,
 
97
                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
98
        if (fd == -1)
 
99
                err(1, "open(%s)", fname);
 
100
 
 
101
        if (write(fd, &pfh, sizeof(pfh)) != sizeof(pfh))
 
102
                err(1, "write()");
 
103
 
 
104
        return fd;
 
105
}
 
106
 
 
107
static void write_pcap(int fd, void *p, int len)
 
108
{       
 
109
        struct pcap_pkthdr pkh;                                                                              
 
110
 
 
111
        memset(&pkh, 0, sizeof(pkh));
 
112
 
 
113
        pkh.caplen  = pkh.len = len;
 
114
        pkh.tv_sec  = 0;
 
115
        pkh.tv_usec = 0;
 
116
 
 
117
        if (write(fd, &pkh, sizeof(pkh)) != sizeof(pkh))
 
118
                err(1, "write()");
 
119
 
 
120
        if (write(fd, p, len) != len)
 
121
                err(1, "write()");
 
122
}
 
123
 
 
124
static void packet_write_pcap(int fd, struct packet *p)
 
125
{
 
126
        write_pcap(fd, p->p_data, p->p_len);
 
127
}
 
128
 
 
129
static void print_network(struct network *n)
 
130
{
 
131
        printf("Net %.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s\n",
 
132
                n->n_bssid[0],
 
133
                n->n_bssid[1],
 
134
                n->n_bssid[2],
 
135
                n->n_bssid[3],
 
136
                n->n_bssid[4],
 
137
                n->n_bssid[5],
 
138
                n->n_ssid);
 
139
}
 
140
 
 
141
static void save_network(struct network *n)
 
142
{
 
143
        int i;
 
144
 
 
145
        write_pcap(_outfd, n->n_beacon, n->n_beaconlen);
 
146
 
 
147
        for (i = 0; i < 4; i++) {
 
148
                struct packet *p = &n->n_handshake->c_handshake[i];
 
149
 
 
150
                if (p->p_len)
 
151
                        packet_write_pcap(_outfd, p);
 
152
        }
 
153
}
 
154
 
 
155
static void fix_beacon(struct network *n)
 
156
{
 
157
        unsigned char *p;
 
158
        int ssidlen;
 
159
        int origlen;
 
160
 
 
161
        /* beacon surgery */
 
162
        p = n->n_beacon + sizeof(struct ieee80211_frame) + 8 + 2 + 2;
 
163
 
 
164
        ssidlen = strlen(n->n_ssid);
 
165
        assert((n->n_beaconlen + ssidlen) <=
 
166
               (int) sizeof(n->n_beacon));
 
167
 
 
168
        assert(*p == IEEE80211_ELEMID_SSID);
 
169
        p++;
 
170
 
 
171
        if (*p != 0 && p[1] != 0)
 
172
                return;
 
173
 
 
174
        origlen = *p;
 
175
        *p++    = ssidlen;
 
176
 
 
177
        assert(origlen == 0 || p[0] == 0);
 
178
 
 
179
        memmove(p + ssidlen, p + origlen,
 
180
                n->n_beaconlen - (p + origlen - n->n_beacon));
 
181
        memcpy(p, n->n_ssid, ssidlen);
 
182
 
 
183
        n->n_beaconlen += ssidlen - origlen;
 
184
}
 
185
 
 
186
static void check_network(struct network *n)
 
187
{
 
188
        if (!n->n_beaconlen || !n->n_handshake || !n->n_ssid[0])
 
189
                return;
 
190
 
 
191
        fix_beacon(n);
 
192
 
 
193
        print_network(n);
 
194
 
 
195
        save_network(n);
 
196
}
 
197
 
 
198
static struct network *find_net(unsigned char *b)
 
199
{
 
200
        struct network *n = _networks.n_next;
 
201
 
 
202
        while (n) {
 
203
                if (memcmp(b, n->n_bssid, sizeof(n->n_bssid)) == 0)
 
204
                        return n;
 
205
 
 
206
                n = n->n_next;
 
207
        }
 
208
 
 
209
        return NULL;
 
210
}
 
211
 
 
212
static struct network *net_add(unsigned char *bssid)
 
213
{
 
214
        struct network *n = malloc(sizeof(*n));
 
215
 
 
216
        if (!n)
 
217
                err(1, "malloc()");
 
218
 
 
219
        memset(n, 0, sizeof(*n));
 
220
 
 
221
        memcpy(n->n_bssid, bssid, sizeof(n->n_bssid));
 
222
 
 
223
        n->n_next = _networks.n_next;
 
224
        _networks.n_next = n;
 
225
 
 
226
        return n;
 
227
}
 
228
 
 
229
static struct network *find_add_net(unsigned char *bssid)
 
230
{
 
231
        struct network *n;
 
232
 
 
233
        n = find_net(bssid);
 
234
        if (n)
 
235
                return n;
 
236
 
 
237
        return net_add(bssid);
 
238
}
 
239
 
 
240
static struct client *find_client(struct network *n, unsigned char *mac)
 
241
{
 
242
        struct client *c = n->n_clients.c_next;
 
243
 
 
244
        while (c) {
 
245
                if (memcmp(c->c_mac, mac, sizeof(c->c_mac)) == 0)
 
246
                        return c;
 
247
 
 
248
                c = c->c_next;
 
249
        }
 
250
 
 
251
        return NULL;
 
252
}
 
253
 
 
254
static struct client *find_add_client(struct network *n, unsigned char *mac)
 
255
{
 
256
        struct client *c;
 
257
 
 
258
        c = find_client(n, mac);
 
259
        if (c)
 
260
                return c;
 
261
 
 
262
        c = malloc(sizeof(*c));
 
263
        if (!c)
 
264
                err(1, "malloc()");
 
265
 
 
266
        memset(c, 0, sizeof(*c));
 
267
 
 
268
        memcpy(c->c_mac, mac, sizeof(c->c_mac));
 
269
 
 
270
        c->c_next = n->n_clients.c_next;
 
271
        n->n_clients.c_next = c;
 
272
 
 
273
        return c;
 
274
}
 
275
 
 
276
#if 0
 
277
static void hexdump(void *p, int len)
 
278
{
 
279
        unsigned char *x = p;
 
280
        
 
281
        while (len--)
 
282
                printf("%.2x ", *x++);
 
283
 
 
284
        printf("\n");
 
285
}
 
286
#endif
 
287
 
 
288
static int parse_rsn(unsigned char *p, int l, int rsn)
 
289
{
 
290
        int c;
 
291
        unsigned char *start = p;
 
292
        int psk = 0;
 
293
        int wpa = 0;
 
294
           
 
295
        if (l < 2)
 
296
                return 0;
 
297
 
 
298
        if (memcmp(p, "\x01\x00", 2) != 0)
 
299
                return 0;
 
300
 
 
301
        wpa = 1;
 
302
 
 
303
        if (l < 8)
 
304
                return -1;
 
305
 
 
306
        p += 2;
 
307
        p += 4;
 
308
 
 
309
        /* cipher */
 
310
        c = le16toh(*((uint16_t*) p));
 
311
 
 
312
        p += 2 + 4 * c;
 
313
 
 
314
        if (l < ((p - start) + 2))
 
315
                return -1;
 
316
 
 
317
        /* auth */
 
318
        c = le16toh(*((uint16_t*) p));
 
319
        p += 2;
 
320
        
 
321
        if (l < ((p - start) + c * 4))
 
322
                return -1;
 
323
 
 
324
        while (c--) {
 
325
                if (rsn && memcmp(p, "\x00\x0f\xac\x02", 4) == 0)
 
326
                        psk++;
 
327
                
 
328
                if (!rsn && memcmp(p, "\x00\x50\xf2\x02", 4) == 0)
 
329
                        psk++;
 
330
                
 
331
                p += 4;
 
332
        }
 
333
        
 
334
        assert(l >= (p - start));
 
335
 
 
336
        if (!psk)
 
337
                wpa = 0;
 
338
 
 
339
        return wpa;
 
340
}                                                                                                            
 
341
 
 
342
 
 
343
static int parse_elem_vendor(unsigned char *e, int l)
 
344
{       
 
345
        struct ieee80211_ie_wpa *wpa = (struct ieee80211_ie_wpa*) e;
 
346
 
 
347
        if (l < 5)
 
348
                return 0;
 
349
 
 
350
        if (memcmp(wpa->wpa_oui, "\x00\x50\xf2", 3) != 0)
 
351
                return 0;
 
352
 
 
353
        if (l < 8)
 
354
                return 0;
 
355
 
 
356
        if (wpa->wpa_type != WPA_OUI_TYPE)
 
357
                return 0;
 
358
 
 
359
        return parse_rsn((unsigned char*) &wpa->wpa_version, l - 6, 0);
 
360
}
 
361
 
 
362
static void process_beacon(struct ieee80211_frame *wh, int totlen)
 
363
{
 
364
        unsigned char *p = (unsigned char*) (wh + 1);
 
365
        int bhlen = 8 + 2 + 2;
 
366
        int len = totlen;
 
367
        char ssid[256];
 
368
        int wpa = 0;
 
369
        int rc;
 
370
        int ssids = 0;
 
371
        int hidden = 0;
 
372
        struct network *n;
 
373
 
 
374
        totlen -= sizeof(*wh);
 
375
 
 
376
        if (totlen < bhlen)
 
377
                goto __bad;
 
378
 
 
379
        if (!(IEEE80211_BEACON_CAPABILITY(p) & IEEE80211_CAPINFO_PRIVACY))
 
380
                return;
 
381
 
 
382
        p      += bhlen;
 
383
        totlen -= bhlen;
 
384
 
 
385
        ssid[0] = 0;
 
386
 
 
387
        while (totlen > 2) {
 
388
                int id = *p++;
 
389
                int l  = *p++;
 
390
                
 
391
                totlen -= 2;
 
392
                
 
393
                if (totlen < l)
 
394
                        goto __bad;
 
395
 
 
396
                switch (id) {
 
397
                case IEEE80211_ELEMID_SSID:
 
398
                        if (++ssids > 1)
 
399
                                break;
 
400
                        
 
401
                        if (l == 0 || p[0] == 0)
 
402
                                hidden = 1;
 
403
                        else {
 
404
                                memcpy(ssid, p, l);
 
405
                                ssid[l] = 0;
 
406
                        }
 
407
                        break;
 
408
                
 
409
                case IEEE80211_ELEMID_VENDOR:
 
410
                        if ((rc = parse_elem_vendor(&p[-2], l + 2)) == -1)
 
411
                                goto __bad;
 
412
 
 
413
                        if (rc)
 
414
                                wpa = 1;
 
415
                        break;
 
416
                
 
417
                case IEEE80211_ELEMID_RSN:                                                                      
 
418
                        if ((rc = parse_rsn(p, l, 1)) == -1)                                                        
 
419
                                goto __bad;
 
420
 
 
421
                        if (rc)
 
422
                                wpa = 1;
 
423
                        break;
 
424
                }
 
425
 
 
426
                p      += l;
 
427
                totlen -= l;
 
428
        }
 
429
 
 
430
        if (!wpa)
 
431
                return;
 
432
#if 0
 
433
        if (hidden) {
 
434
                printf("Hidden SSID\n");
 
435
                return;
 
436
        }
 
437
#endif
 
438
        n = find_add_net(wh->i_addr3);
 
439
 
 
440
        if (n->n_beaconlen)
 
441
                return;
 
442
 
 
443
        n->n_beaconlen = len;
 
444
        assert(n->n_beaconlen <= (int) sizeof(n->n_beacon));
 
445
        memcpy(n->n_beacon, wh, n->n_beaconlen);
 
446
        strcpy(n->n_ssid, ssid);
 
447
 
 
448
#if 0
 
449
        printf("got beacon [%s]\n", n->n_ssid);
 
450
#endif
 
451
 
 
452
        check_network(n);
 
453
        return;
 
454
__bad:
 
455
        printf("bad beacon\n");
 
456
}
 
457
 
 
458
static int eapol_handshake_step(unsigned char *eapol, int len)
 
459
{       
 
460
        int eapol_size = 4 + 1 + 2 + 2 + 8 + 32 + 16 + 8 + 8 + 16 + 2;
 
461
 
 
462
        if (len < eapol_size)
 
463
                return 0;
 
464
 
 
465
        /* not pairwise */
 
466
        if ((eapol[6] & 0x08) == 0)
 
467
                return 0;
 
468
 
 
469
        /* 1: has no mic */
 
470
        if ((eapol[5] & 1) == 0)
 
471
                return 1;
 
472
 
 
473
        /* 3: has ack */
 
474
        if ((eapol[6] & 0x80) != 0)
 
475
                return 3;
 
476
 
 
477
        if (*((uint16_t*) &eapol[eapol_size - 2]) == 0)
 
478
                return 4;
 
479
 
 
480
        return 2;
 
481
}
 
482
 
 
483
static void packet_copy(struct packet *p, void *d, int len)
 
484
{       
 
485
        assert(len <= (int) sizeof(p->p_data));
 
486
 
 
487
        p->p_len = len;
 
488
        memcpy(p->p_data, d, len);
 
489
}
 
490
 
 
491
static void process_eapol(struct network *n, struct client *c, unsigned char *p,
 
492
                          int len, struct ieee80211_frame *wh, int totlen)
 
493
{       
 
494
        int num, i;
 
495
 
 
496
        num = eapol_handshake_step(p, len);
 
497
        if (num == 0)
 
498
                return;
 
499
 
 
500
        /* reset... should use time, too.  XXX conservative - check retry */
 
501
        if (c->c_wpa == 0 || num <= c->c_wpa) {
 
502
                for (i = 0; i < 4; i++)
 
503
                        c->c_handshake[i].p_len = 0;
 
504
                
 
505
                c->c_wpa_got = 0;
 
506
        }
 
507
        
 
508
        c->c_wpa = num;
 
509
 
 
510
        switch (num) {
 
511
        case 1: 
 
512
                c->c_wpa_got |= 1;
 
513
                break;
 
514
 
 
515
        case 2: 
 
516
                c->c_wpa_got |= 2;
 
517
                c->c_wpa_got |= 4;
 
518
                break;
 
519
 
 
520
        case 3: 
 
521
                if (memcmp(&p[17], ZERO, 32) != 0)
 
522
                        c->c_wpa_got |= 1;
 
523
                
 
524
                c->c_wpa_got |= 4;
 
525
                break;                                                                                       
 
526
 
 
527
        case 4: 
 
528
                if (memcmp(&p[17], ZERO, 32) != 0)
 
529
                        c->c_wpa_got |= 2;
 
530
                
 
531
                c->c_wpa_got |= 4;
 
532
                break;
 
533
 
 
534
        default:
 
535
                abort();
 
536
        }
 
537
        
 
538
        packet_copy(&c->c_handshake[num - 1], wh, totlen);
 
539
 
 
540
        if (c->c_wpa_got == 7)
 
541
                n->n_handshake = c;                                                                   
 
542
}
 
543
 
 
544
static void process_data(struct ieee80211_frame *wh, int len)
 
545
{
 
546
        unsigned char *p = (unsigned char*) (wh + 1);
 
547
        struct llc* llc;
 
548
        int wep = wh->i_fc[1] & IEEE80211_FC1_WEP;
 
549
        int eapol = 0;
 
550
        struct client *c;
 
551
        int stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 
552
        int orig = len;
 
553
        unsigned char *bssid, *clientaddr;
 
554
        struct network *n;
 
555
 
 
556
        len -= sizeof(*wh);
 
557
 
 
558
        if (stype == IEEE80211_FC0_SUBTYPE_QOS) {
 
559
                p   += 2;
 
560
                len -= 2;
 
561
        }
 
562
                                                                                                                
 
563
        if (!wep && len >= 8) {                                                                                 
 
564
                llc = (struct llc*) p;
 
565
 
 
566
                eapol = memcmp(llc, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8) == 0;
 
567
 
 
568
                p   += 8;
 
569
                len -= 8;
 
570
        }
 
571
 
 
572
        if (!eapol)
 
573
                return;
 
574
 
 
575
        if (len < 5)
 
576
                return;
 
577
 
 
578
        /* type == key */
 
579
        if (p[1] != 0x03)
 
580
                return;
 
581
 
 
582
        /* desc == WPA or RSN */
 
583
        if (p[4] != 0xFE && p[4] != 0x02)
 
584
                return;
 
585
 
 
586
        bssid      = wh->i_addr1;
 
587
        clientaddr = wh->i_addr2;
 
588
 
 
589
        if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) {
 
590
                bssid      = wh->i_addr2;
 
591
                clientaddr = wh->i_addr1;
 
592
        } else if (!(wh->i_fc[1] & IEEE80211_FC1_DIR_TODS))
 
593
                bssid = wh->i_addr3; /* IBSS */
 
594
 
 
595
        n = find_add_net(bssid);
 
596
 
 
597
        if (n->n_handshake)
 
598
                return;
 
599
 
 
600
        c = find_add_client(n, clientaddr);
 
601
 
 
602
        process_eapol(n, c, p, len, wh, orig);
 
603
 
 
604
        if (n->n_handshake)
 
605
                check_network(n);
 
606
}
 
607
 
 
608
static void grab_hidden_ssid(unsigned char *bssid, struct ieee80211_frame *wh,
 
609
                             int len, int off)
 
610
{
 
611
        struct network *n;
 
612
        unsigned char *p = ((unsigned char *)(wh + 1)) + off;
 
613
        int l;
 
614
 
 
615
        n = find_net(bssid);
 
616
        if (n && n->n_ssid[0])
 
617
                return;
 
618
 
 
619
        len -= sizeof(*wh) + off + 2;
 
620
 
 
621
        if (len < 0)
 
622
                goto __bad;
 
623
 
 
624
        if (*p++ != IEEE80211_ELEMID_SSID)
 
625
                goto __bad;
 
626
 
 
627
        l = *p++;
 
628
        if (l > len)
 
629
                goto __bad;
 
630
 
 
631
        if (l == 0)
 
632
                return;
 
633
 
 
634
        if (!n)
 
635
                n = net_add(bssid);
 
636
 
 
637
        memcpy(n->n_ssid, p, l);
 
638
        n->n_ssid[l] = 0;
 
639
 
 
640
        check_network(n);
 
641
        return;
 
642
 
 
643
__bad:  
 
644
        printf("bad grab_hidden_ssid\n");
 
645
        return;
 
646
}
 
647
 
 
648
static void process_packet(void *packet, int len)
 
649
{
 
650
        struct ieee80211_frame *wh = (struct ieee80211_frame*) packet;
 
651
 
 
652
#if 0
 
653
        printf("GOT %d\n", len);
 
654
        hexdump(packet, len);
 
655
#endif
 
656
 
 
657
        if (len < (int) sizeof(*wh))
 
658
                return;
 
659
 
 
660
        switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
 
661
        case IEEE80211_FC0_TYPE_MGT:
 
662
                switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
 
663
                case IEEE80211_FC0_SUBTYPE_BEACON:
 
664
                        process_beacon(wh, len);
 
665
                        break;
 
666
 
 
667
                case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 
668
                        grab_hidden_ssid(wh->i_addr3, wh, len, 2 + 2);
 
669
                        break;
 
670
 
 
671
                case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 
672
                        grab_hidden_ssid(wh->i_addr3, wh, len, 2 + 2 + 6);
 
673
                        break;
 
674
 
 
675
                case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 
676
                        grab_hidden_ssid(wh->i_addr3, wh, len, 8 + 2 + 2);
 
677
                        break;
 
678
                }
 
679
                break;
 
680
 
 
681
        case IEEE80211_FC0_TYPE_DATA:
 
682
                process_data(wh, len);
 
683
                break;
 
684
        }
 
685
}
 
686
 
 
687
static void pwn(char *fname)
 
688
{
 
689
        struct wif *wi;
 
690
        char crap[2048];
 
691
        int rc;
 
692
 
 
693
        snprintf(crap, sizeof(crap), "file://%s", fname);
 
694
 
 
695
        wi = wi_open(crap);
 
696
        if (!wi) {
 
697
                printf("Bad file - skipping %s\n", fname);
 
698
                return;
 
699
        }
 
700
 
 
701
        while ((rc = wi_read(wi, (unsigned char*) crap, sizeof(crap), NULL)) > 0)
 
702
                process_packet(crap, rc);
 
703
 
 
704
        wi_close(wi);
 
705
}
 
706
 
 
707
int main(int argc, char *argv[])
 
708
{
 
709
        char *out;
 
710
        int i;
 
711
 
 
712
        if (argc < 3) {
 
713
                printf("Usage: %s <out.cap> <in.cap> [in2.cap] [...]\n", argv[0]);
 
714
                exit(1);
 
715
        }
 
716
 
 
717
        out = argv[1];
 
718
        _outfd = open_pcap(out);
 
719
 
 
720
        for (i = 2; i < argc; i++) {
 
721
                char *in = argv[i];
 
722
                int prog = (int) (((double) (i - 1)) / ((double)(argc - 2)) 
 
723
                                   * 100.0);
 
724
 
 
725
                printf("Pwning %s (%d/%d %d%%)\n", in, i - 1, argc - 2, prog);
 
726
                fflush(stdout);
 
727
 
 
728
                pwn(in);
 
729
        }
 
730
 
 
731
        printf("Done\n");
 
732
        exit(0);
 
733
}