airdecap.c
上传用户:fubang
上传日期:2009-06-18
资源大小:2071k
文件大小:33k
源码类别:

其他

开发平台:

Unix_Linux

  1. /*
  2.  *  802.11 to Ethernet pcap translator
  3.  *
  4.  *  Copyright (C) 2004,2005  Christophe Devine
  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. #include <windows.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <time.h>
  25. #include "console.h"
  26. #include "crctable.h"
  27. #include "crypto.h"
  28. #include "pcap.h"
  29. #define CRYPT_NONE 0
  30. #define CRYPT_WEP  1
  31. #define CRYPT_WPA  2
  32. unsigned short Sbox[2][256]=
  33. {
  34.     {
  35.         0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
  36.         0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
  37.         0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
  38.         0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
  39.         0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
  40.         0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
  41.         0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
  42.         0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
  43.         0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
  44.         0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
  45.         0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
  46.         0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
  47.         0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
  48.         0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
  49.         0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
  50.         0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
  51.         0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
  52.         0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
  53.         0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
  54.         0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
  55.         0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
  56.         0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
  57.         0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
  58.         0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
  59.         0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
  60.         0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
  61.         0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
  62.         0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
  63.         0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
  64.         0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
  65.         0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
  66.         0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A
  67.     },
  68.     {
  69.         0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
  70.         0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
  71.         0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
  72.         0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
  73.         0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
  74.         0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
  75.         0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
  76.         0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
  77.         0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
  78.         0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
  79.         0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
  80.         0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
  81.         0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
  82.         0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
  83.         0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
  84.         0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
  85.         0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
  86.         0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
  87.         0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
  88.         0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
  89.         0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
  90.         0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
  91.         0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
  92.         0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
  93.         0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
  94.         0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
  95.         0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
  96.         0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
  97.         0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
  98.         0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
  99.         0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
  100.         0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C
  101.     }
  102. };
  103. /* derive the PMK from the passphrase and the essid */
  104. void calc_pmk( uchar *key, uchar *essid, uchar pmk[40] )
  105. {
  106.     int i, j, slen;
  107.     uchar buffer[64];
  108.     sha1_context ctx_ipad;
  109.     sha1_context ctx_opad;
  110.     sha1_context sha1_ctx;
  111.     slen = strlen( essid ) + 4;
  112.     /* setup the inner and outer contexts */
  113.     memset( buffer, 0, 64 );
  114.     strcpy( buffer, key );
  115.     for( i = 0; i < 64; i++ )
  116.         buffer[i] ^= 0x36;
  117.     sha1_starts( &ctx_ipad );
  118.     sha1_update( &ctx_ipad, buffer, 64 );
  119.     for( i = 0; i < 64; i++ )
  120.         buffer[i] ^= 0x6A;
  121.     sha1_starts( &ctx_opad );
  122.     sha1_update( &ctx_opad, buffer, 64 );
  123.     /* iterate HMAC-SHA1 over itself 8192 times */
  124.     essid[slen - 1] = '1';
  125.     hmac_sha1( key, strlen( key ), essid, slen, pmk );
  126.     memcpy( buffer, pmk, 20 );
  127.     for( i = 1; i < 4096; i++ )
  128.     {
  129.         memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) );
  130.         sha1_update( &sha1_ctx, buffer, 20 );
  131.         sha1_finish( &sha1_ctx, buffer );
  132.         memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) );
  133.         sha1_update( &sha1_ctx, buffer, 20 );
  134.         sha1_finish( &sha1_ctx, buffer );
  135.         for( j = 0; j < 20; j++ )
  136.             pmk[j] ^= buffer[j];
  137.     }
  138.     essid[slen - 1] = '2';
  139.     hmac_sha1( key, strlen( key ), essid, slen, pmk + 20 );
  140.     memcpy( buffer, pmk + 20, 20 );
  141.     for( i = 1; i < 4096; i++ )
  142.     {
  143.         memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) );
  144.         sha1_update( &sha1_ctx, buffer, 20 );
  145.         sha1_finish( &sha1_ctx, buffer );
  146.         memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) );
  147.         sha1_update( &sha1_ctx, buffer, 20 );
  148.         sha1_finish( &sha1_ctx, buffer );
  149.         for( j = 0; j < 20; j++ )
  150.             pmk[j + 20] ^= buffer[j];
  151.     }
  152. }
  153. struct ST_info
  154. {
  155.     struct ST_info *next;       /* next supplicant              */
  156.     uchar stmac[6];             /* supplicant MAC               */
  157.     uchar bssid[6];             /* authenticator MAC            */
  158.     uchar snonce[32];           /* supplicant nonce             */
  159.     uchar anonce[32];           /* authenticator nonce          */
  160.     uchar keymic[20];           /* eapol frame MIC              */
  161.     uchar eapol[256];           /* eapol frame contents         */
  162.     uchar ptk[80];              /* pairwise transcient key      */
  163.     int eapol_size;             /* eapol frame size             */
  164.     unsigned long t_crc;        /* last ToDS   frame CRC        */
  165.     unsigned long f_crc;        /* last FromDS frame CRC        */
  166.     int keyver, valid_ptk;
  167. };
  168. /* derive the pairwise transcient keys from a bunch of stuff */
  169. int calc_ptk( struct ST_info *wpa, uchar pmk[32] )
  170. {
  171.     int i;
  172.     uchar pke[100];
  173.     uchar mic[20];
  174.     memcpy( pke, "Pairwise key expansion", 23 );
  175.     if( memcmp( wpa->stmac, wpa->bssid, 6 ) < 0 )
  176.     {
  177.         memcpy( pke + 23, wpa->stmac, 6 );
  178.         memcpy( pke + 29, wpa->bssid, 6 );
  179.     }
  180.     else
  181.     {
  182.         memcpy( pke + 23, wpa->bssid, 6 );
  183.         memcpy( pke + 29, wpa->stmac, 6 );
  184.     }
  185.     if( memcmp( wpa->snonce, wpa->anonce, 32 ) < 0 )
  186.     {
  187.         memcpy( pke + 35, wpa->snonce, 32 );
  188.         memcpy( pke + 67, wpa->anonce, 32 );
  189.     }
  190.     else
  191.     {
  192.         memcpy( pke + 35, wpa->anonce, 32 );
  193.         memcpy( pke + 67, wpa->snonce, 32 );
  194.     }
  195.     for( i = 0; i < 4; i++ )
  196.     {
  197.         pke[99] = i;
  198.         hmac_sha1( pmk, 32, pke, 100, wpa->ptk + i * 20 );
  199.     }
  200.     /* check the EAPOL frame MIC */
  201.     if( ( wpa->keyver & 0x07 ) == 1 )
  202.         hmac_md5(  wpa->ptk, 16, wpa->eapol, wpa->eapol_size, mic );
  203.     else
  204.         hmac_sha1( wpa->ptk, 16, wpa->eapol, wpa->eapol_size, mic );
  205.     return( memcmp( mic, wpa->keymic, 16 ) == 0 );
  206. }
  207. /* CRC checksum calculation routine */
  208. int calc_crc_buf( unsigned char *buf, int len )
  209. {
  210.     unsigned long crc = 0xFFFFFFFF;
  211.     for( ; len > 0; len--, buf++ )
  212.         crc = crc_tbl[(crc ^ *buf) & 0xFF] ^ ( crc >> 8 );
  213.     return( ~crc );
  214. }
  215. /* CRC checksum verification routine */
  216. int check_crc_buf( unsigned char *buf, int len )
  217. {
  218.     unsigned long crc = 0xFFFFFFFF;
  219.     for( ; len > 0; len--, buf++ )
  220.         crc = crc_tbl[(crc ^ *buf) & 0xFF] ^ ( crc >> 8 );
  221.     crc = ~crc;
  222.     return( ( ( crc       ) & 0xFF ) == buf[0] &&
  223.             ( ( crc >>  8 ) & 0xFF ) == buf[1] &&
  224.             ( ( crc >> 16 ) & 0xFF ) == buf[2] &&
  225.             ( ( crc >> 24 ) & 0xFF ) == buf[3] );
  226. }
  227. /* WEP (barebone RC4) decryption routine */
  228. int decrypt_wep( uchar *data, int len, uchar *key, int keylen )
  229. {
  230.     struct rc4_state S;
  231.     rc4_setup( &S, key, keylen );
  232.     rc4_crypt( &S, data, len );
  233.     return( check_crc_buf( data, len - 4 ) );
  234. }
  235. /* TKIP (RC4 + key mixing) decryption routine */
  236. #define ROTR1(x)      ((((x) >> 1) & 0x7FFF) ^ (((x) & 1) << 15))
  237. #define LO8(x)        ( (x) & 0x00FF )
  238. #define LO16(x)       ( (x) & 0xFFFF )
  239. #define HI8(x)        ( ((x) >>  8) & 0x00FF )
  240. #define HI16(x)       ( ((x) >> 16) & 0xFFFF )
  241. #define MK16(hi,lo)   ( (lo) ^ ( LO8(hi) << 8 ) )
  242. #define TK16(N)       MK16(TK1[2*(N)+1],TK1[2*(N)])
  243. #define _S_(x)        (Sbox[0][LO8(x)] ^ Sbox[1][HI8(x)])
  244. int decrypt_tkip( uchar *h80211, int caplen, uchar TK1[16] )
  245. {
  246.     int i, z;
  247.     uint IV32;
  248.     ushort IV16;
  249.     ushort PPK[6];
  250.     uchar K[16];
  251.     z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30;
  252.     IV16 = MK16( h80211[z], h80211[z + 2] );
  253.     IV32 = ( h80211[z + 4]       ) | ( h80211[z + 5] <<  8 ) |
  254.            ( h80211[z + 6] << 16 ) | ( h80211[z + 7] << 24 );
  255.     PPK[0] = LO16( IV32 );
  256.     PPK[1] = HI16( IV32 );
  257.     PPK[2] = MK16( h80211[11], h80211[10] );
  258.     PPK[3] = MK16( h80211[13], h80211[12] );
  259.     PPK[4] = MK16( h80211[15], h80211[14] );
  260.     for( i = 0; i < 8; i++ )
  261.     {
  262.         PPK[0] += _S_( PPK[4] ^ TK16( (i & 1) + 0 ) );
  263.         PPK[1] += _S_( PPK[0] ^ TK16( (i & 1) + 2 ) );
  264.         PPK[2] += _S_( PPK[1] ^ TK16( (i & 1) + 4 ) );
  265.         PPK[3] += _S_( PPK[2] ^ TK16( (i & 1) + 6 ) );
  266.         PPK[4] += _S_( PPK[3] ^ TK16( (i & 1) + 0 ) ) + i;
  267.     }
  268.     PPK[5] = PPK[4] + IV16;
  269.     PPK[0] += _S_( PPK[5] ^ TK16(0) );
  270.     PPK[1] += _S_( PPK[0] ^ TK16(1) );
  271.     PPK[2] += _S_( PPK[1] ^ TK16(2) );
  272.     PPK[3] += _S_( PPK[2] ^ TK16(3) );
  273.     PPK[4] += _S_( PPK[3] ^ TK16(4) );
  274.     PPK[5] += _S_( PPK[4] ^ TK16(5) );
  275.     PPK[0] += ROTR1( PPK[5] ^ TK16(6) );
  276.     PPK[1] += ROTR1( PPK[0] ^ TK16(7) );
  277.     PPK[2] += ROTR1( PPK[1] );
  278.     PPK[3] += ROTR1( PPK[2] );
  279.     PPK[4] += ROTR1( PPK[3] );
  280.     PPK[5] += ROTR1( PPK[4] );
  281.     K[0] =   HI8( IV16 );
  282.     K[1] = ( HI8( IV16 ) | 0x20 ) & 0x7F;
  283.     K[2] =   LO8( IV16 );
  284.     K[3] =   LO8( (PPK[5] ^ TK16(0) ) >> 1);
  285.     for( i = 0; i < 6; i++ )
  286.     {
  287.         K[4 + ( 2 * i)] = LO8( PPK[i] );
  288.         K[5 + ( 2 * i)] = HI8( PPK[i] );
  289.     }
  290.     return( decrypt_wep( h80211 + z + 8, caplen - z - 8, K, 16 ) );
  291. }
  292. /* CCMP (AES-CTR-MAC) decryption routine */
  293. void XOR( uchar *dst, uchar *src, int len )
  294. {
  295.     int i;
  296.     for( i = 0; i < len; i++ )
  297.         dst[i] ^= src[i];
  298. }
  299. int decrypt_ccmp( uchar *h80211, int caplen, uchar TK1[16] )
  300. {
  301.     int is_a4, i, n, z, blocks;
  302.     int data_len, last, offset;
  303.     uchar B0[16], B[16], MIC[16];
  304.     uchar PN[6], AAD[32];
  305.     aes_context aes_ctx;
  306.     is_a4 = ( h80211[0] & 3 ) == 3;
  307.     z = 24 + 6 * is_a4;
  308.     PN[0] = h80211[z + 7];
  309.     PN[1] = h80211[z + 6];
  310.     PN[2] = h80211[z + 5];
  311.     PN[3] = h80211[z + 4];
  312.     PN[4] = h80211[z + 1];
  313.     PN[5] = h80211[z + 0];
  314.     data_len = caplen - z - 8 - 8;
  315.     B0[0] = 0x59;
  316.     B0[1] = 0;
  317.     memcpy( B0 + 2, h80211 + 10, 6 );
  318.     memcpy( B0 + 8, PN, 6 );
  319.     B0[14] = ( data_len >> 8 ) & 0xFF;
  320.     B0[15] = ( data_len & 0xFF );
  321.     memset( AAD, 0, sizeof( AAD ) );
  322.     AAD[1] = 22 + 6 * is_a4;
  323.     AAD[2] = h80211[0] & 0x8F;
  324.     AAD[3] = h80211[1] & 0xC7;
  325.     memcpy( AAD + 4, h80211 + 4, 3 * 6 );
  326.     AAD[22] = h80211[22] & 0x0F;
  327.     if( is_a4 )
  328.         memcpy( AAD + 24, h80211 + 24, 6 );
  329.     aes_set_key( &aes_ctx, TK1, 128 );
  330.     aes_encrypt( &aes_ctx, B0, MIC );
  331.     XOR( MIC, AAD, 16 );
  332.     aes_encrypt( &aes_ctx, MIC, MIC );
  333.     XOR( MIC, AAD + 16, 16 );
  334.     aes_encrypt( &aes_ctx, MIC, MIC );
  335.     B0[0] &= 0x07;
  336.     B0[14] = B0[15] = 0;
  337.     aes_encrypt( &aes_ctx, B0, B );
  338.     XOR( h80211 + caplen - 8, B, 8 );
  339.     blocks = ( data_len + 16 - 1 ) / 16;
  340.     last = data_len % 16;
  341.     offset = z + 8;
  342.     for( i = 1; i <= blocks; i++ )
  343.     {
  344.         n = ( last > 0 && i == blocks ) ? last : 16;
  345.         B0[14] = ( i >> 8 ) & 0xFF;
  346.         B0[15] =   i & 0xFF;
  347.         aes_encrypt( &aes_ctx, B0, B );
  348.         XOR( h80211 + offset, B, n );
  349.         XOR( MIC, h80211 + offset, n );
  350.         aes_encrypt( &aes_ctx, MIC, MIC );
  351.         offset += n;
  352.     }
  353.     return( memcmp( h80211 + offset, MIC, 8 ) == 0 );
  354. }
  355. struct decap_stats
  356. {
  357.     unsigned long nb_read;      /* # of packets read       */
  358.     unsigned long nb_wep;       /* # of WEP data packets   */
  359.     unsigned long nb_wpa;       /* # of WPA data packets   */
  360.     unsigned long nb_plain;     /* # of plaintext packets  */
  361.     unsigned long nb_unwep;     /* # of decrypted WEP pkt  */
  362.     unsigned long nb_unwpa;     /* # of decrypted WPA pkt  */
  363. }
  364. stats;
  365. struct options
  366. {
  367.     int no_convert;
  368.     uchar bssid[6];
  369.     uchar pmk[40];
  370.     uchar essid[36];
  371.     uchar passphrase[65];
  372.     uchar wepkey[64];
  373.     int weplen, crypt;
  374. }
  375. opt;
  376. uchar buffer[65536];
  377. uchar tmpbuf[65536];
  378. int prompt_exit( int retval )
  379. {
  380.     int i;
  381.     printf( "n  Press Ctrl-C to exit.n" );
  382.     scanf( "%d", &i );
  383.     exit( retval );
  384. }
  385. /* this routine handles to 802.11 to Ethernet translation */
  386. int write_packet( FILE *f_out, struct pcap_pkthdr *pkh, uchar *h80211 )
  387. {
  388.     int n;
  389.     uchar arphdr[12];
  390.     if( opt.no_convert )
  391.     {
  392.         if( buffer != h80211 )
  393.             memcpy( buffer, h80211, pkh->caplen );
  394.     }
  395.     else
  396.     {
  397.         /* create the Ethernet link layer (MAC dst+src) */
  398.         switch( h80211[1] & 3 )
  399.         {
  400.             case  0:    /* To DS = 0, From DS = 0: DA, SA, BSSID */
  401.                 memcpy( arphdr + 0, h80211 +  4, 6 );
  402.                 memcpy( arphdr + 6, h80211 + 10, 6 );
  403.                 break;
  404.             case  1:    /* To DS = 1, From DS = 0: BSSID, SA, DA */
  405.                 memcpy( arphdr + 0, h80211 + 16, 6 );
  406.                 memcpy( arphdr + 6, h80211 + 10, 6 );
  407.                 break;
  408.             case  2:    /* To DS = 0, From DS = 1: DA, BSSID, SA */
  409.                 memcpy( arphdr + 0, h80211 +  4, 6 );
  410.                 memcpy( arphdr + 6, h80211 + 16, 6 );
  411.                 break;
  412.             default:    /* To DS = 1, From DS = 1: RA, TA, DA, SA */
  413.                 memcpy( arphdr + 0, h80211 + 16, 6 );
  414.                 memcpy( arphdr + 6, h80211 + 24, 6 );
  415.                 break;
  416.         }
  417.         /* remove the 802.11 + LLC header */
  418.         if( ( h80211[1] & 3 ) != 3 )
  419.         {
  420.             pkh->len    -= 24 + 6;
  421.             pkh->caplen -= 24 + 6;
  422.             memcpy( buffer + 12, h80211 + 30, pkh->caplen );
  423.         }
  424.         else
  425.         {
  426.             pkh->len    -= 30 + 6;
  427.             pkh->caplen -= 30 + 6;
  428.             memcpy( buffer + 12, h80211 + 36, pkh->caplen );
  429.         }
  430.         memcpy( buffer, arphdr, 12 );
  431.         pkh->len    += 12;
  432.         pkh->caplen += 12;
  433.     }
  434.     n = sizeof( struct pcap_pkthdr );
  435.     if( fwrite( pkh, 1, n, f_out ) != (size_t) n )
  436.     {
  437.         perror( "  fwrite(packet header) failed" );
  438.         prompt_exit( 1 );
  439.     }
  440.     n = pkh->caplen;
  441.     if( fwrite( buffer, 1, n, f_out ) != (size_t) n )
  442.     {
  443.         perror( "  fwrite(packet data) failed" );
  444.         prompt_exit( 1 );
  445.     }
  446.     return( 0 );
  447. }
  448. int main( int argc, char *argv[] )
  449. {
  450.     time_t tt;
  451.     uint magic;
  452.     FILE *f_in, *f_out;
  453.     unsigned long crc;
  454.     int i = 0, n, z, linktype;
  455.     uchar ZERO[32], *s, *h80211;
  456.     uchar bssid[6], stmac[6];
  457.     struct ST_info *st_1st;
  458.     struct ST_info *st_cur;
  459.     struct ST_info *st_prv;
  460.     struct pcap_file_header pfh;
  461.     struct pcap_pkthdr pkh;    
  462.     /* parse the arguments */
  463.     memset( ZERO, 0, sizeof( ZERO ) );
  464.     memset( &opt, 0, sizeof( opt  ) );
  465.     /* init some stuff */
  466.     GetModuleFileName( GetModuleHandle( NULL ),
  467.                        buffer, sizeof( buffer ) );
  468.     i = strlen( buffer ) - 1;
  469.     while( i > 0 )
  470.     {
  471.         if( buffer[i] == '\' )
  472.         {
  473.             buffer[i] =  '';
  474.             break;
  475.         }
  476.         i--;
  477.     }
  478.     SetCurrentDirectory( buffer );
  479.     set_console_icon( " airdecap 2.3 " );
  480.     set_console_size( 38, 80 );
  481.     printf( "nnntt" );
  482.     set_text_color( BLUE_WHITE );
  483.     printf( "airdecap 2.3 - (C) 2004,2005 Christophe Devine" );
  484.     set_text_color( TEXTATTR );
  485.     printf( "nnn" );
  486.     /* ask the arguments */
  487. ask_infile:
  488.     if( argc < 2 )
  489.     {
  490.         printf( "n  Input .cap file -> " );
  491.         scanf( "%s", buffer );
  492.         argv[1] = buffer;
  493.     }
  494.     if( ( f_in = fopen( argv[1], "rb" ) ) == NULL )
  495.     {
  496.         printf( "n  Could not open "%s".n", argv[1] );
  497.         goto ask_infile;
  498.     }
  499.     n = strlen( argv[1] );
  500.     if( n > 4 && argv[1][n - 4] == '.' )
  501.     {
  502.         memcpy( tmpbuf, argv[1], n - 4 );
  503.         memcpy( tmpbuf + n - 4, "-dec", 4 );
  504.         memcpy( tmpbuf + n, argv[1] + n - 4, 5 );
  505.     }
  506.     else
  507.     {
  508.         if( n > 5 && argv[1][n - 5] == '.' )
  509.         {
  510.             memcpy( tmpbuf, argv[1], n - 5 );
  511.             memcpy( tmpbuf + n - 5, "-dec", 4 );
  512.             memcpy( tmpbuf + n - 1, argv[1] + n - 5, 6 );
  513.         }
  514.         else
  515.             sprintf( tmpbuf, "%s-dec", argv[1] );
  516.     }
  517.     if( ( f_out = fopen( tmpbuf, "wb+" ) ) == NULL )
  518.     {
  519.         printf( "n  Could not create "%s".n", tmpbuf );
  520.         prompt_exit( 1 );
  521.     }
  522.     printf( "n" );
  523. ask_bssid:
  524.     printf( "  BSSID ('.' = no MAC filter) -> " );
  525.     scanf( "%s", buffer );
  526.     memset( opt.bssid, 0, 6 );
  527.     if( buffer[0] != '.' )
  528.     {
  529.         i = 0;
  530.         s = buffer;
  531.         while( sscanf( s, "%x", &n ) == 1 )
  532.         {
  533.             if( n < 0 || n > 255 )
  534.                 goto ask_bssid;
  535.             opt.bssid[i] = n;
  536.             if( ++i > 6 ) break;
  537.             if( ! ( s = strchr( s, ':' ) ) )
  538.                 break;
  539.             s++;
  540.         }
  541.         if( i != 6 )
  542.             goto ask_bssid;
  543.     }
  544.     printf( "n  Mode: 1 = convert unencryptedn"
  545.             "        2 = decrypt static WEPn"
  546.             "        3 = decrypt WPA-PSKnn" );
  547. ask_mode:
  548.     printf( "     -> " );
  549.     scanf( "%s", buffer );
  550.     opt.crypt = atoi( buffer );
  551.     if( opt.crypt < 1 || opt.crypt > 3 )
  552.         goto ask_mode;
  553.     opt.crypt--;
  554.     if( opt.crypt == CRYPT_WEP )
  555.     {
  556.         printf( "n" );
  557. ask_wepkey:
  558.         printf( "  WEP key in hex. -> " );
  559.         scanf( "%s", buffer );
  560.         i = 0;
  561.         s = buffer;
  562.         tmpbuf[0] = s[0];
  563.         tmpbuf[1] = s[1];
  564.         tmpbuf[2] = '';
  565.         while( sscanf( tmpbuf, "%x", &n ) == 1 )
  566.         {
  567.             if( n < 0 || n > 255 )
  568.                 goto ask_wepkey;
  569.             opt.wepkey[i++] = n;
  570.             if( i >= 64 ) break;
  571.             s += 2;
  572.             if( s[0] == ':' || s[0] == '-' )
  573.                 s++;
  574.             if( s[0] == '' || s[1] == '' )
  575.                 break;
  576.             tmpbuf[0] = s[0];
  577.             tmpbuf[1] = s[1];
  578.         }
  579.         if( i != 5 && i != 13 && i != 29 && i != 61 )
  580.             goto ask_wepkey;
  581.         opt.weplen = i;
  582.     }
  583.     if( opt.crypt == CRYPT_WPA )
  584.     {
  585.         int wpamode;
  586.         printf( "n  WPA:  1 = specify 256-bit PMKn"
  587.                 "        2 = specify ESSID & passphrasenn" );
  588. ask_wpamode:
  589.         printf( "     -> " );
  590.         scanf( "%s", buffer );
  591.         wpamode = atoi( buffer );
  592.         if( wpamode < 1 || wpamode > 2 )
  593.             goto ask_wpamode;
  594.         printf( "n" );
  595.         if( wpamode == 1 )
  596.         {
  597. ask_pmk:
  598.             printf( "  PMK (256-bit hex value) -> " );
  599.             scanf( "%s", buffer );
  600.             i = 0;
  601.             s = buffer;
  602.             tmpbuf[0] = s[0];
  603.             tmpbuf[1] = s[1];
  604.             tmpbuf[2] = '';
  605.             while( sscanf( tmpbuf, "%x", &n ) == 1 )
  606.             {
  607.                 if( n < 0 || n > 255 )
  608.                     goto ask_pmk;
  609.                 opt.pmk[i++] = n;
  610.                 if( i >= 32 ) break;
  611.                 s += 2;
  612.                 if( s[0] == ':' || s[0] == '-' )
  613.                     s++;
  614.                 if( s[0] == '' || s[1] == '' )
  615.                     break;
  616.                 tmpbuf[0] = s[0];
  617.                 tmpbuf[1] = s[1];
  618.             }
  619.             if( i != 32 )
  620.                 goto ask_pmk;
  621.         }
  622.         if( wpamode == 2 )
  623.         {
  624.             printf( "  Network ESSID  -> " );
  625.             scanf( "%s", buffer );
  626.             buffer[33] = '';
  627.             strcpy( opt.essid, buffer );
  628.             printf( "  Passphrase     -> " );
  629.             scanf( "%s", buffer );
  630.             buffer[65] = '';
  631.             strcpy( opt.passphrase, buffer );
  632.             calc_pmk( opt.passphrase, opt.essid, opt.pmk );
  633.         }
  634.     }
  635.     opt.no_convert = 1;
  636.     printf( "n  Remove the 802.11 layer (y/n) ? " );
  637.     scanf( "%s", buffer );
  638.     if( buffer[0] == 'y' || buffer[0] == 'Y' )
  639.         opt.no_convert = 0;
  640.     printf( "n" );
  641.     n = sizeof( pfh );
  642.     if( fread( &pfh, 1, n, f_in ) != (size_t) n )
  643.     {
  644.         perror( "  fread(pcap file header) failed" );
  645.         prompt_exit( 1 );
  646.     }
  647.     if( pfh.magic != TCPDUMP_MAGIC &&
  648.         pfh.magic != TCPDUMP_CIGAM )
  649.     {
  650.         printf( "  "%s" isn't a pcap file (expected "
  651.                 "TCPDUMP_MAGIC).n", argv[1] );
  652.         prompt_exit( 1 );
  653.     }
  654.     if( ( magic = pfh.magic ) == TCPDUMP_CIGAM )
  655.         SWAP32( pfh.linktype );
  656.     if( pfh.linktype != LINKTYPE_IEEE802_11 &&
  657.         pfh.linktype != LINKTYPE_PRISM_HEADER )
  658.     {
  659.         printf( "  "%s" isn't a regular 802.11 "
  660.                 "(wireless) capture.n", argv[1] );
  661.         prompt_exit( 1 );
  662.     }
  663.     linktype = pfh.linktype;
  664.     pfh.magic           = TCPDUMP_MAGIC;
  665.     pfh.version_major   = PCAP_VERSION_MAJOR;
  666.     pfh.version_minor   = PCAP_VERSION_MINOR;
  667.     pfh.thiszone        = 0;
  668.     pfh.sigfigs         = 0;
  669.     pfh.snaplen         = 65535;
  670.     pfh.linktype        = ( opt.no_convert ) ? 
  671.                             LINKTYPE_IEEE802_11 :
  672.                             LINKTYPE_ETHERNET;
  673.     if( fwrite( &pfh, 1, n, f_out ) != (size_t) n )
  674.     {
  675.         perror( "  fwrite(pcap file header) failed" );
  676.         prompt_exit( 1 );
  677.     }
  678.     /* loop reading and deciphering the packets */
  679.     memset( &stats, 0, sizeof( stats ) );
  680.     tt = time( NULL );
  681.     st_1st = NULL;
  682.     while( 1 )
  683.     {
  684.         if( time( NULL ) - tt > 0 )
  685.         {
  686.             /* update the status line every second */
  687.             printf( "  Read %ld packets...r", stats.nb_read );
  688.             fflush( stdout );
  689.             tt = time( NULL );
  690.         }
  691.         /* read one packet */
  692.         n = sizeof( pkh );
  693.         if( fread( &pkh, 1, n, f_in ) != (size_t) n )
  694.             break;
  695.         if( magic == TCPDUMP_CIGAM )
  696.             SWAP32( pkh.caplen );
  697.         n = pkh.caplen;
  698.         if( n <= 0 || n > 65535 )
  699.         {
  700.             printf( "  Corrupted file? Invalid packet length %d.n", n );
  701.             break;
  702.         }
  703.         if( fread( buffer, 1, n, f_in ) != (size_t) n )
  704.             break;
  705.         stats.nb_read++;
  706.         h80211 = buffer;
  707.         if( linktype == LINKTYPE_PRISM_HEADER )
  708.         {
  709.             /* remove the prism header */
  710.             if( h80211[7] == 0x40 )
  711.                 n = 64; /* prism54 */
  712.             else
  713.             {
  714.                 n = *(int *)( h80211 + 4 );
  715.                 if( magic == TCPDUMP_CIGAM )
  716.                     SWAP32( n );
  717.             }
  718.             if( n < 8 || n >= (int) pkh.caplen )
  719.                 continue;
  720.             h80211 += n; pkh.caplen -= n;
  721.         }
  722.         /* remove the FCS if present (madwifi) */
  723.         if( check_crc_buf( h80211, pkh.caplen - 4 ) == 1 )
  724.         {
  725.             pkh.len    -= 4;
  726.             pkh.caplen -= 4;
  727.         }
  728.         /* check if data */
  729.         if( ( h80211[0] & 0x0C ) != 0x08 )
  730.             continue;
  731.         /* check minimum size */
  732.         z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30;
  733.         if( z + 16 > (int) pkh.caplen )
  734.             continue;
  735.         /* check the BSSID */
  736.         switch( h80211[0] & 3 )
  737.         {
  738.             case  0: memcpy( bssid, h80211 + 16, 6 ); break;
  739.             case  1: memcpy( bssid, h80211 +  4, 6 ); break;
  740.             case  2: memcpy( bssid, h80211 + 10, 6 ); break;
  741.             default: memcpy( bssid, h80211 +  4, 6 ); break;
  742.         }
  743.         if( memcmp( opt.bssid, ZERO, 6 ) != 0 )
  744.             if( memcmp( opt.bssid, bssid, 6 ) != 0 )
  745.                 continue;    
  746.         /* locate the station's MAC address */
  747.         switch( h80211[1] & 3 )
  748.         {
  749.             case  1: memcpy( stmac, h80211 + 10, 6 ); break;
  750.             case  2: memcpy( stmac, h80211 +  4, 6 ); break;
  751.             case  3: memcpy( stmac, h80211 + 10, 6 ); break;
  752.             default: continue;
  753.         }
  754.         st_prv = NULL;
  755.         st_cur = st_1st;
  756.         while( st_cur != NULL )
  757.         {
  758.             if( ! memcmp( st_cur->stmac, stmac, 6 ) )
  759.                 break;
  760.             st_prv = st_cur;
  761.             st_cur = st_cur->next;
  762.         }
  763.         /* if it's a new station, add it */
  764.         if( st_cur == NULL )
  765.         {
  766.             if( ! ( st_cur = (struct ST_info *) malloc(
  767.                              sizeof( struct ST_info ) ) ) )
  768.             {
  769.                 perror( "  malloc failed" );
  770.                 break;
  771.             }
  772.             memset( st_cur, 0, sizeof( struct ST_info ) );
  773.             if( st_1st == NULL )
  774.                 st_1st = st_cur;
  775.             else
  776.                 st_prv->next = st_cur;
  777.             memcpy( st_cur->stmac, stmac, 6 );
  778.             memcpy( st_cur->bssid, bssid, 6 );
  779.         }
  780.         /* check if we haven't already processed this packet */
  781.         crc = calc_crc_buf( h80211 + z, pkh.caplen - z );
  782.         if( ( h80211[1] & 3 ) == 2 )
  783.         {
  784.             if( st_cur->t_crc == crc )
  785.                 continue;
  786.             st_cur->t_crc = crc;
  787.         }
  788.         else
  789.         {
  790.             if( st_cur->f_crc == crc )
  791.                 continue;
  792.             st_cur->f_crc = crc;
  793.         }
  794.         /* check the SNAP header to see if data is encrypted *
  795.          * as unencrypted data begins with AA AA 03 00 00 00 */
  796.         if( h80211[z] != h80211[z + 1] || h80211[z + 2] != 0x03 )
  797.         {
  798.             /* check the extended IV flag */
  799.             if( ( h80211[z + 3] & 0x20 ) == 0 )
  800.             {
  801.                 uchar K[64];
  802.                 stats.nb_wep++;
  803.                 if( opt.crypt != CRYPT_WEP )
  804.                     continue;
  805.                 memcpy( K, h80211 + z, 3 );
  806.                 memcpy( K + 3, opt.wepkey, opt.weplen );
  807.                 if( decrypt_wep( h80211 + z + 4, pkh.caplen - z - 4,
  808.                                  K, 3 + opt.weplen ) == 0 )
  809.                     continue;
  810.                 /* WEP data packet was successfully decrypted, *
  811.                  * remove the WEP IV & ICV and write the data  */
  812.                 pkh.len    -= 8;
  813.                 pkh.caplen -= 8;
  814.                 memcpy( h80211 + z, h80211 + z + 4, pkh.caplen - z );
  815.                 stats.nb_unwep++;
  816.                 h80211[1] &= 0xBF;
  817.                 if( write_packet( f_out, &pkh, h80211 ) != 0 )
  818.                     break;
  819.             }
  820.             else
  821.             {
  822.                 stats.nb_wpa++;
  823.                 if( opt.crypt != CRYPT_WPA )
  824.                     continue;
  825.                 /* if the PTK is valid, try to decrypt */
  826.                 if( st_cur == NULL || ! st_cur->valid_ptk )
  827.                     continue;
  828.                 if( st_cur->keyver == 1 )
  829.                 {
  830.                     if( decrypt_tkip( h80211, pkh.caplen,
  831.                                       st_cur->ptk + 32 ) == 0 )
  832.                         continue;
  833.                     pkh.len    -= 20;
  834.                     pkh.caplen -= 20;
  835.                 }
  836.                 else
  837.                 {
  838.                     if( decrypt_ccmp( h80211, pkh.caplen,
  839.                                       st_cur->ptk + 32 ) == 0 )
  840.                         continue;
  841.                     pkh.len    -= 16;
  842.                     pkh.caplen -= 16;
  843.                 }
  844.                 /* WPA data packet was successfully decrypted, *
  845.                  * remove the WPA Ext.IV & MIC, write the data */
  846.                 memcpy( h80211 + z, h80211 + z + 8, pkh.caplen - z );
  847.                 stats.nb_unwpa++;
  848.                 h80211[1] &= 0xBF;
  849.                 if( write_packet( f_out, &pkh, h80211 ) != 0 )
  850.                     break;
  851.             }
  852.         }
  853.         else
  854.         {
  855.             /* check ethertype == EAPOL */
  856.             z += 6;
  857.             if( h80211[z] != 0x88 || h80211[z + 1] != 0x8E )
  858.             {
  859.                 stats.nb_plain++;
  860.                 if( opt.crypt != CRYPT_NONE )
  861.                     continue;
  862.                 if( write_packet( f_out, &pkh, h80211 ) != 0 )
  863.                     break;
  864.             }
  865.             z += 2;
  866.             /* type == 3 (key), desc. == 254 (WPA) or 2 (RSN) */
  867.             if( h80211[z + 1] != 0x03 ||
  868.                 ( h80211[z + 4] != 0xFE && h80211[z + 4] != 0x02 ) )
  869.                 continue;
  870.             /* frame 1: Pairwise == 1, Install == 0, Ack == 1, MIC == 0 */
  871.             if( ( h80211[z + 6] & 0x08 ) != 0 &&
  872.                 ( h80211[z + 6] & 0x40 ) == 0 &&
  873.                 ( h80211[z + 6] & 0x80 ) != 0 &&
  874.                 ( h80211[z + 5] & 0x01 ) == 0 )
  875.             {
  876.                 /* set authenticator nonce */
  877.                 memcpy( st_cur->anonce, &h80211[z + 17], 32 );
  878.             }
  879.             /* frame 2 or 4: Pairwise == 1, Install == 0, Ack == 0, MIC == 1 */
  880.             if( ( h80211[z + 6] & 0x08 ) != 0 &&
  881.                 ( h80211[z + 6] & 0x40 ) == 0 &&
  882.                 ( h80211[z + 6] & 0x80 ) == 0 &&
  883.                 ( h80211[z + 5] & 0x01 ) != 0 )
  884.             {
  885.                 if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 )
  886.                 {
  887.                     /* set supplicant nonce */
  888.                     memcpy( st_cur->snonce, &h80211[z + 17], 32 );
  889.                 }
  890.             }
  891.             /* frame 3: Pairwise == 1, Install == 1, Ack == 1, MIC == 1 */
  892.             if( ( h80211[z + 6] & 0x08 ) != 0 &&
  893.                 ( h80211[z + 6] & 0x40 ) != 0 &&
  894.                 ( h80211[z + 6] & 0x80 ) != 0 &&
  895.                 ( h80211[z + 5] & 0x01 ) != 0 )
  896.             {
  897.                 if( memcmp( &h80211[z + 17], ZERO, 32 ) != 0 )
  898.                 {
  899.                     /* set authenticator nonce */
  900.                     memcpy( st_cur->anonce, &h80211[z + 17], 32 );
  901.                 }
  902.                 /* copy the MIC & eapol frame */
  903.                 st_cur->eapol_size = ( h80211[z + 2] << 8 )
  904.                                    +   h80211[z + 3] + 4;
  905.                 memcpy( st_cur->keymic, &h80211[z + 81], 16 );
  906.                 memcpy( st_cur->eapol, &h80211[z], st_cur->eapol_size );
  907.                 memset( st_cur->eapol + 81, 0, 16 );
  908.                 /* copy the key descriptor version */
  909.                 st_cur->keyver = h80211[z + 6] & 7;
  910.             }
  911.             st_cur->valid_ptk = calc_ptk( st_cur, opt.pmk );
  912.         }
  913.     }
  914.     fclose( f_in  );
  915.     fclose( f_out );
  916.     /* write some statistics */
  917.     printf( "  Total number of packets read      % 8ldn"
  918.             "  Total number of WEP data packets  % 8ldn"
  919.             "  Total number of WPA data packets  % 8ldn"
  920.             "  Number of plaintext data packets  % 8ldn"
  921.             "  Number of decrypted WEP  packets  % 8ldn"
  922.             "  Number of decrypted WPA  packets  % 8ldn",
  923.             stats.nb_read, stats.nb_wep, stats.nb_wpa,
  924.             stats.nb_plain, stats.nb_unwep, stats.nb_unwpa );
  925.     prompt_exit( 0 );
  926.     /* not reached */
  927.     return( 0 );
  928. }