wlandump files.
This commit is contained in:
parent
1b350c127c
commit
fec24b3669
23
src/wlandump/Makefile
Normal file
23
src/wlandump/Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
# makefile for the PRISM/AMD79C930 wlandump utility
|
||||
|
||||
include ../config.mk
|
||||
|
||||
ifndef CFLAGS
|
||||
CFLAGS = -O2 -Wall -Wstrict-prototypes -Winline -pipe -D__LINUX_WLAN__ -D__I386__
|
||||
endif
|
||||
|
||||
CPPFLAGS = -I../include -I$(LINUX)/include
|
||||
|
||||
|
||||
wlandump: wlandump.o prframe.o p80211.o wep.o
|
||||
cc -o wlandump wlandump.o prframe.o p80211.o wep.o
|
||||
|
||||
p80211.o: ../p80211/p80211.c
|
||||
cc -c $(CFLAGS) $(CPPFLAGS) -o ./p80211.o ../p80211/p80211.c
|
||||
|
||||
install:
|
||||
cp -p wlandump $(INST_EXEDIR)
|
||||
|
||||
clean:
|
||||
rm -f core core.* *.o .*.o *.s *.a .depend tmp_make *~
|
||||
|
1613
src/wlandump/prframe.c
Normal file
1613
src/wlandump/prframe.c
Normal file
File diff suppressed because it is too large
Load diff
339
src/wlandump/wep.c
Normal file
339
src/wlandump/wep.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
/* wep.c: handles decryption for wlandump
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* Linux WLAN
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The initial developer of the original code is Mark S. Mathews
|
||||
* <mark@absoval.com>. Portions created by Mark S. Mathews
|
||||
* are Copyright (C) 1998 AbsoluteValue Software, Inc. All Rights Reserved.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* The author may be reached as mark@absoval.com, or C/O AbsoluteValue
|
||||
* Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149
|
||||
*
|
||||
* Thanks to David Hinds, Donald Becker, and the rest of the Linux
|
||||
* developers worldwide for making all of this possible.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wlan/wlan_compat.h>
|
||||
#include <wlan/version.h>
|
||||
#include <wlan/p80211hdr.h>
|
||||
#include <wlan/p80211mgmt.h>
|
||||
#include <wlan/am930mib.h>
|
||||
#include <wlan/wlan_ioctl.h>
|
||||
#include "wlandump.h"
|
||||
|
||||
|
||||
#define WLAN_CRC32_POLY_LE (0xedb88320UL)
|
||||
#define WLAN_CRC32_POLY_BE (0x04c11db7UL)
|
||||
|
||||
#define WLAN_WEP_FULLKEYLEN 8
|
||||
#define WLAN_WEP_SBOXLEN 256
|
||||
#define WLAN_WEP_SWAP(a,b) { UINT8 c; c = (a); (a) = (b); (b) = (c); }
|
||||
|
||||
|
||||
typedef struct wlan_wepprng
|
||||
{
|
||||
UINT8 s[WLAN_WEP_SBOXLEN];
|
||||
UINT i;
|
||||
UINT j;
|
||||
} wlan_wepprng_t;
|
||||
|
||||
|
||||
UINT32 crc32_table[256];
|
||||
|
||||
static UINT32 wlandump_crc32_block(UINT32 reg, UINT8 *p, UINT len);
|
||||
static UINT32 wlandump_crc32_blockfinish(UINT32 reg);
|
||||
|
||||
static void wlandump_wep_initprng( wlan_wepprng_t *prng, UINT8 *k, UINT klen);
|
||||
static void wlandump_wep_block( wlan_wepprng_t *prng, UINT8 *d, UINT dlen);
|
||||
|
||||
#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */
|
||||
static UINT8 wlandump_wep_nextprn( wlan_wepprng_t *prng);
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_wep_initprng
|
||||
*
|
||||
* Initializes the WEP Psuedo-Random number generator using a
|
||||
* given seed. The seed is usually the private key.
|
||||
* Arguments:
|
||||
* prng - a structure, allocated by the caller, that will
|
||||
* maintain state information during the use of this
|
||||
* prng.
|
||||
* k - an array of bytes containing the seed
|
||||
* klen - length of seed
|
||||
*
|
||||
* returns: nothing
|
||||
----------------------------------------------------------------*/
|
||||
void wlandump_wep_initprng( wlan_wepprng_t *prng, UINT8 *k, UINT klen)
|
||||
{
|
||||
UINT i;
|
||||
UINT j;
|
||||
|
||||
for ( i = 0; i < WLAN_WEP_SBOXLEN; i++ )
|
||||
{
|
||||
prng->s[i] = i;
|
||||
}
|
||||
|
||||
prng->i = prng->j = 0;
|
||||
|
||||
j = 0;
|
||||
for ( i = 0; i < WLAN_WEP_SBOXLEN; i++)
|
||||
{
|
||||
j = (j + prng->s[i] + k[i % klen]) % WLAN_WEP_SBOXLEN;
|
||||
WLAN_WEP_SWAP( prng->s[i], prng->s[j] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_wep_nextprn
|
||||
*
|
||||
* Retrieves the next value from a prng initialized with
|
||||
* wep_prng.
|
||||
* Arguments:
|
||||
* prng - a prng structure previosly initialized with
|
||||
* wep_initprng.
|
||||
*
|
||||
* returns: next psuedo-random number
|
||||
----------------------------------------------------------------*/
|
||||
#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */
|
||||
UINT8 wlandump_wep_nextprn( wlan_wepprng_t *prng)
|
||||
{
|
||||
UINT i;
|
||||
UINT j;
|
||||
UINT t;
|
||||
UINT8 *s;
|
||||
s = prng->s;
|
||||
i = (prng->i + 1) % WLAN_WEP_SBOXLEN;
|
||||
j = (prng->j + s[i]) % WLAN_WEP_SBOXLEN;
|
||||
WLAN_WEP_SWAP( s[i], s[j] );
|
||||
t = (s[i] + s[j]) % WLAN_WEP_SBOXLEN;
|
||||
prng->i = i;
|
||||
prng->j = j;
|
||||
return s[t];
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_wep_block
|
||||
*
|
||||
* WEP encrypts a block of bytes in place.
|
||||
* Arguments:
|
||||
* prng - a prng structure previosly initialized with
|
||||
* wep_initprng.
|
||||
* d - ptr to the block of bytes to be encrypted.
|
||||
* dlen - length of the block
|
||||
*
|
||||
* returns: nothing
|
||||
----------------------------------------------------------------*/
|
||||
void wlandump_wep_block( wlan_wepprng_t *prng, UINT8 *d, UINT dlen)
|
||||
{
|
||||
UINT i;
|
||||
UINT j;
|
||||
UINT t;
|
||||
UINT8 *s;
|
||||
UINT index = dlen;
|
||||
UINT8 *data = d;
|
||||
|
||||
WLAN_LOG_DEBUG2(3,"d=0x%lx dlen=%u\n", (UINT32)d, dlen);
|
||||
|
||||
s = prng->s;
|
||||
i = prng->i;
|
||||
j = prng->j;
|
||||
|
||||
WLAN_HEX_DUMP(3, "prewep (payload only):", d, dlen);
|
||||
|
||||
while( index )
|
||||
{
|
||||
i = (i + 1) % WLAN_WEP_SBOXLEN;
|
||||
j = (j + s[i]) % WLAN_WEP_SBOXLEN;
|
||||
WLAN_WEP_SWAP( s[i], s[j] );
|
||||
t = (s[i] + s[j]) % WLAN_WEP_SBOXLEN;
|
||||
*data ^= s[t];
|
||||
data++;
|
||||
index--;
|
||||
}
|
||||
|
||||
prng->i = i;
|
||||
prng->j = j;
|
||||
WLAN_HEX_DUMP(3, "postwep (payload only):", d, dlen);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_wep_decrypt
|
||||
*
|
||||
* Inspects the given frame, if it doesn't require decryption
|
||||
* leave it along. If the frame does require decryption, check
|
||||
* to see that we set up for decryption. If we're not set up
|
||||
* for decryption, print an error. If the frame
|
||||
* needs decryption _and_ we support and are configured for it,
|
||||
* decrypt the frame inside the given buffer and return it to the
|
||||
* caller.
|
||||
* Arguments:
|
||||
* f - frame buffer
|
||||
* len - length of frame in buffer
|
||||
*
|
||||
* returns:
|
||||
* nothing
|
||||
----------------------------------------------------------------*/
|
||||
void wlandump_wep_decrypt( UINT8 *f, UINT16 len)
|
||||
{
|
||||
UINT8 key[WLAN_WEP_FULLKEYLEN];
|
||||
wlan_wepprng_t prng;
|
||||
UINT32 crc32 = 0xffffffffUL;
|
||||
UINT8 keyid;
|
||||
p80211_hdr_t *phdr;
|
||||
|
||||
DBFENTER;
|
||||
|
||||
if ( !opt_wepkeyset )
|
||||
{
|
||||
fprintf(stderr, "%s: trying to decrypt frame but no keys set!\n", appname);
|
||||
return;
|
||||
}
|
||||
|
||||
phdr = (p80211_hdr_t*)f;
|
||||
|
||||
if ( !WLAN_GET_FC_ISWEP(phdr->a3.fc) ) /* frame not encrypted, do nothing */
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* make the key and init the prng */
|
||||
keyid = (f + WLAN_HDR_A3_LEN)[3];
|
||||
keyid = keyid >> 6;
|
||||
memcpy(key, f + WLAN_HDR_A3_LEN, 3);
|
||||
|
||||
/* TODO: change this so the decryption is done in a separate buffer */
|
||||
/* decrypt the body and the icv */
|
||||
memcpy(key+3, wep_key[keyid], WLAN_WEP_KEYLEN);
|
||||
wlandump_wep_initprng( &prng, key, WLAN_WEP_FULLKEYLEN);
|
||||
wlandump_wep_block( &prng,
|
||||
f + WLAN_HDR_A3_LEN + WLAN_WEP_IV_LEN,
|
||||
len - WLAN_HDR_A3_LEN - WLAN_WEP_IV_LEN - WLAN_FCS_LEN);
|
||||
|
||||
/* check for undecryptable */
|
||||
crc32 = wlandump_crc32_block(
|
||||
crc32,
|
||||
f + WLAN_HDR_A3_LEN + WLAN_WEP_IV_LEN,
|
||||
len - WLAN_HDR_A3_LEN - WLAN_WEP_IV_LEN - WLAN_WEP_ICV_LEN - WLAN_FCS_LEN);
|
||||
crc32 = wlandump_crc32_blockfinish(crc32);
|
||||
|
||||
if ( crc32 !=
|
||||
ieee2host32(*((UINT32*)(f + len - WLAN_WEP_ICV_LEN - WLAN_FCS_LEN))) )
|
||||
{
|
||||
printf("Undecryptable ");
|
||||
}
|
||||
|
||||
DBFEXIT;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_crc32_block
|
||||
*
|
||||
* Calculate the crc over a block of bytes. To get the final crc value,
|
||||
* don't forget to call crc32_blockfinish.
|
||||
* Arguments:
|
||||
* reg initial accumulator value, passing it in allows us to
|
||||
* crc non-contiguous blocks. On the first call to this
|
||||
* function for a given crc calculation, reg should be
|
||||
* 0xffffffffUL.
|
||||
* p ptr to the block
|
||||
* len size of block
|
||||
* returns:
|
||||
* crc32 value
|
||||
----------------------------------------------------------------*/
|
||||
UINT32 wlandump_crc32_block(UINT32 reg, UINT8 *p, UINT len)
|
||||
{
|
||||
while(len)
|
||||
{
|
||||
reg = crc32_table[(reg ^ *p) & 0x000000ffUL] ^ (reg >> 8);
|
||||
len--;
|
||||
p++;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
UINT32 wlandump_crc32_blockfinish(UINT32 reg)
|
||||
{
|
||||
return reg ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_crc32_accum
|
||||
*
|
||||
* Accumulates, in a given register, the crc of a series of bytes
|
||||
* passed to this function.
|
||||
* Arguments:
|
||||
* reg current accumulated crc value
|
||||
* d next byte in series
|
||||
* returns:
|
||||
* new accumulated crc32 value
|
||||
----------------------------------------------------------------*/
|
||||
#ifdef NOTUSED /* we're not using it right now, ifdef'd to stop warning */
|
||||
UINT32 wlandump_crc32_accum(UINT32 reg, UINT8 d)
|
||||
{
|
||||
reg = crc32_table[(reg ^ d) & 0x000000ffUL] ^ (reg >> 8);
|
||||
return reg;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* wlandump_crc32_mktable
|
||||
*
|
||||
* Constructs the table used for the crc32 calculation.
|
||||
* Arguments: none
|
||||
* returns: nothing
|
||||
----------------------------------------------------------------*/
|
||||
void wlandump_crc32_mktable(void)
|
||||
{
|
||||
UINT i;
|
||||
UINT k;
|
||||
UINT32 c;
|
||||
|
||||
crc32_table[0] = 0;
|
||||
for ( i = 1; i < 256; i++)
|
||||
{
|
||||
c = 0;
|
||||
for ( k = i | 256; k != 1; k >>= 1)
|
||||
{
|
||||
c = (c & 1) ?
|
||||
((c >> 1) ^ WLAN_CRC32_POLY_LE) :
|
||||
(c >> 1);
|
||||
if ( k & 1 )
|
||||
{
|
||||
c ^= WLAN_CRC32_POLY_LE;
|
||||
}
|
||||
}
|
||||
crc32_table[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
458
src/wlandump/wlandump.c
Normal file
458
src/wlandump/wlandump.c
Normal file
|
@ -0,0 +1,458 @@
|
|||
/* wlandump.c: Entry point to frame 'snif' and dump program
|
||||
* ----------------------------------------------------------------
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The initial developer of the original code is Jo-Ellen F. Mathews
|
||||
* <joellen@absoval.com>. Portions were created by Jo-Ellen F.
|
||||
* Mathews and Mark S. Mathews and are Copyright (C) 1998
|
||||
* AbsoluteValue Software, Inc. All Rights Reserved.
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Ugly hack for LinuxPPC R4, don't have time to figure it out right now */
|
||||
#if defined(_ARCH_PPC)
|
||||
#undef __GLIBC__
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <asm-i386/types.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#include <wlan/version.h>
|
||||
#include <wlan/wlan_compat.h>
|
||||
#include <wlan/am930mib.h>
|
||||
#include <wlan/wlan_ioctl.h>
|
||||
#include "wlandump.h"
|
||||
|
||||
|
||||
#define APPNAME "wlandump"
|
||||
|
||||
|
||||
int read_frames_from_file( char *filename );
|
||||
void usage(void);
|
||||
void handlesig(int signo);
|
||||
int get_ioctl_socket(char *ifname);
|
||||
void sniff_interface(int ioctlfd);
|
||||
void strtoUINT40( UINT8 *a, char *s );
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* Global Variables
|
||||
----------------------------------------------------------------*/
|
||||
char appname[APPNAME_MAX + 1];
|
||||
char *fullname;
|
||||
wlan_sniffercmd_t cmd;
|
||||
char ifname[16];
|
||||
int ioctlfd;
|
||||
int nlfd;
|
||||
|
||||
/* option flags */
|
||||
int opt_nobeacon = 0; /* -b => don't show beacons */
|
||||
int opt_showrx = 1; /* -r => don't show rx'd frames (on by default) */
|
||||
int opt_showtx = 0; /* -t => show tx'd frames */
|
||||
int opt_noshowctl = 0; /* -c => don't show ctl frames */
|
||||
int opt_noshowmgmt = 0; /* -m => don't show mgmt frames */
|
||||
int opt_noshowdata = 0; /* -d => don't show data frames */
|
||||
int opt_showdatalen = 2312; /* -s <len> => show, at most, this many data bytes */
|
||||
int opt_showraw = 0; /* -x => show the whole frame as raw bytes */
|
||||
int opt_nodecrypt = 0; /* -w => don't decrypt data frame contents */
|
||||
int opt_nodefrag = 0; /* -u => don't unfragment */
|
||||
int opt_showfrags = 0; /* -f => show fragments as well as defragged frm */
|
||||
int opt_wepkeyset = 0; /* -k <keyindex(0-3)>-xx:xx:xx:xx:xx */
|
||||
UINT8 wep_key[WLAN_WEP_NKEYS][WLAN_WEP_KEYLEN];
|
||||
|
||||
char opts[] = "brtcmdxwufs:k:";
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* Main
|
||||
----------------------------------------------------------------*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int result = 0;
|
||||
int optch;
|
||||
|
||||
strcpy( appname, APPNAME );
|
||||
fullname = argv[0];
|
||||
|
||||
/* if no args, print the usage msg */
|
||||
if ( argc < 2 )
|
||||
{
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initialize the command */
|
||||
cmd.cmd = SNIFFERCMD_REG;
|
||||
cmd.pid = getpid();
|
||||
cmd.flags = SNIFFLAG_SNIFRX;
|
||||
cmd.result = 0;
|
||||
|
||||
/* collect the args */
|
||||
while ( ((optch = getopt(argc, argv, opts)) != EOF) && (result == 0) )
|
||||
{
|
||||
switch (optch)
|
||||
{
|
||||
case 'b':
|
||||
opt_nobeacon = 1;
|
||||
break;
|
||||
case 'r':
|
||||
opt_showrx = 0;
|
||||
cmd.flags &= ~SNIFFLAG_SNIFRX;
|
||||
break;
|
||||
case 't':
|
||||
opt_showtx = 0;
|
||||
cmd.flags |= SNIFFLAG_SNIFTX;
|
||||
break;
|
||||
case 'c':
|
||||
opt_noshowctl = 1;
|
||||
break;
|
||||
case 'm':
|
||||
opt_noshowmgmt = 1;
|
||||
break;
|
||||
case 'd':
|
||||
opt_noshowdata = 1;
|
||||
break;
|
||||
case 's':
|
||||
opt_showdatalen = atoi(optarg);
|
||||
break;
|
||||
case 'x':
|
||||
opt_showraw = 1;
|
||||
break;
|
||||
case 'w':
|
||||
opt_nodecrypt = 1;
|
||||
break;
|
||||
case 'u':
|
||||
opt_nodefrag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
opt_showfrags = 1;
|
||||
break;
|
||||
case 'k':
|
||||
opt_wepkeyset = 1;
|
||||
strtoUINT40( wep_key[optarg[0] - '0'], optarg + 2);
|
||||
break;
|
||||
case 'v':
|
||||
printf("%s utility version %s\n", appname, WLAN_RELEASE);
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we made it this far, the options must be pretty much OK */
|
||||
if ( optind >= argc )
|
||||
{
|
||||
/* we're missing the interface argument */
|
||||
fprintf(stderr, "%s: missing argument - interface\n", fullname);
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make the crc table for wep to use */
|
||||
wlandump_crc32_mktable();
|
||||
|
||||
/* save the interface name */
|
||||
strcpy( ifname, argv[optind] );
|
||||
if ( (ioctlfd = get_ioctl_socket(ifname)) != -1)
|
||||
{
|
||||
sniff_interface(ioctlfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we reach here, something went wrong in sniff_interface, return error */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* get_ioctl_socket
|
||||
*
|
||||
* Opens a socket and issues the WLAN_TEST ioctl to make sure
|
||||
* the named device is, in fact, a wireless interface.
|
||||
*
|
||||
* Arguments:
|
||||
* ifname - e.g. "eth0"
|
||||
*
|
||||
* returns: 0 if successful, not 0 otherwise
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
int get_ioctl_socket(char *ifname)
|
||||
{
|
||||
wlan_req_t req;
|
||||
int result = 0;
|
||||
|
||||
/* get a socket */
|
||||
ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if ( ioctlfd != -1 )
|
||||
{
|
||||
/* Test that there is a card */
|
||||
strcpy( req.name, ifname);
|
||||
req.result = 0;
|
||||
req.data = NULL;
|
||||
req.len = 0;
|
||||
result = ioctl( ioctlfd, WLAN_TEST, &req);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: ioctl WLAN_TEST failed. \'%s\'\n", appname, ifname);
|
||||
fprintf(stderr, "interface \'%s\' is probably an ", ifname);
|
||||
fprintf(stderr, "invalid wireless network interface name.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( req.result == 0xf0f0 )
|
||||
{
|
||||
result = ioctlfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perror(appname);
|
||||
result = ioctlfd;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* sniff_interface
|
||||
*
|
||||
* Sends the SNIFFERCMD:SNIFFERCMD_REG message to the driver,
|
||||
* hooks the signals, opens the netlink socket and loops forever
|
||||
* reading and printing frames.
|
||||
*
|
||||
* Arguments:
|
||||
* ioctlfd - the socket file descriptor for ioctl commands
|
||||
*
|
||||
* returns: should never return. Program terminates via signal
|
||||
* handler.
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void sniff_interface(int ioctlfd)
|
||||
{
|
||||
/* wlan_sniffercmd_t cmd; uses global */
|
||||
/* char ifname[]; uses global */
|
||||
int result;
|
||||
int i;
|
||||
wlan_req_t req;
|
||||
UINT8 snifbuf[WLAN_A3FR_MAXLEN + sizeof(wlan_sniffer_t)];
|
||||
UINT8 *frame;
|
||||
wlan_sniffer_t *snif;
|
||||
struct sockaddr_nl nlskaddr;
|
||||
int recvlen;
|
||||
|
||||
|
||||
|
||||
|
||||
/* send the CMD_REG ioctl */
|
||||
strcpy( req.name, ifname);
|
||||
req.result = 0;
|
||||
req.data = &cmd;
|
||||
req.len = sizeof(cmd);
|
||||
|
||||
/* cmd values were setup from argv in main */
|
||||
result = ioctl( ioctlfd, WLAN_SNIFFERCMD, &req);
|
||||
|
||||
if ( result != 0 )
|
||||
{
|
||||
if ( result == -ENOSYS )
|
||||
{
|
||||
fprintf(stderr, "%s: error - the driver wasn't compiled for sniffing.\n", fullname);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror(fullname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( req.result == 0 )
|
||||
{
|
||||
/* set up the signal handler */
|
||||
for ( i = 1; i < _NSIG; i++)
|
||||
{
|
||||
signal( i, handlesig);
|
||||
}
|
||||
|
||||
/* open the netlink socket */
|
||||
if ( (nlfd = socket( PF_NETLINK, SOCK_RAW, NETLINK_WLAN )) == -1 )
|
||||
{
|
||||
perror(fullname);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset ( &nlskaddr, 0 , sizeof( nlskaddr ));
|
||||
nlskaddr.nl_family = (sa_family_t)PF_NETLINK;
|
||||
nlskaddr.nl_pid = (__u32)getpid();
|
||||
nlskaddr.nl_groups = 0;
|
||||
|
||||
if ((bind( nlfd, (struct sockaddr*)&nlskaddr, sizeof(nlskaddr))) == -1 )
|
||||
{
|
||||
perror(fullname);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* loop forever */
|
||||
while(1)
|
||||
{
|
||||
recvlen = recv( nlfd, snifbuf, sizeof(snifbuf), 0 );
|
||||
|
||||
if ( recvlen > -1 )
|
||||
{
|
||||
snif = (wlan_sniffer_t*)snifbuf;
|
||||
frame = snifbuf + sizeof(wlan_sniffer_t);
|
||||
print_80211_frame( snif, frame, snif->len );
|
||||
}
|
||||
else
|
||||
{
|
||||
perror(fullname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* something is _still_ hosed from the ioctl */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* handlesig
|
||||
*
|
||||
* Cleans up after the sniffer.
|
||||
*
|
||||
* Arguments:
|
||||
* signo - signal number
|
||||
*
|
||||
* returns: function doesn't return anything
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void handlesig(int signo)
|
||||
{
|
||||
wlan_req_t req;
|
||||
|
||||
/* send the CMD_UNREG ioctl */
|
||||
strcpy( req.name, ifname);
|
||||
req.result = 0;
|
||||
req.data = &cmd;
|
||||
req.len = sizeof(cmd);
|
||||
cmd.cmd = SNIFFERCMD_UNREG;
|
||||
|
||||
/* we don't really care about returns at this point */
|
||||
ioctl( ioctlfd, WLAN_SNIFFERCMD, &req);
|
||||
|
||||
close(ioctlfd);
|
||||
close(nlfd);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* strtoUINT40
|
||||
*
|
||||
* This function converts a character string that represents an
|
||||
* a 40 bit quantity.
|
||||
*
|
||||
* Arguments:
|
||||
* a - 40 bit buffer
|
||||
* s - character string representing a 40 key quantity
|
||||
*
|
||||
* returns: function doesn't return anything
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void strtoUINT40( UINT8 *a, char *s )
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
UINT val;
|
||||
|
||||
for ( i = 0; i < 4; i++)
|
||||
{
|
||||
p = strchr( s, ':');
|
||||
if ( p == NULL )
|
||||
{
|
||||
fprintf(stderr, "%s: UINT48 format error!\n", appname);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = '\0';
|
||||
sscanf( s, "%x", &val);
|
||||
a[i] = (UINT8)val;
|
||||
s = p+1;
|
||||
}
|
||||
}
|
||||
sscanf( s, "%x", &val);
|
||||
a[i] = (UINT8)val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
* usage
|
||||
*
|
||||
* This function displays the proper syntax of the frdumper utility.
|
||||
*
|
||||
* Arguments:
|
||||
* no arguments
|
||||
*
|
||||
* returns: function doesn't return anything
|
||||
*
|
||||
----------------------------------------------------------------*/
|
||||
void usage(void)
|
||||
{
|
||||
printf("\n%s : 802.11 frame dump utility\n", appname);
|
||||
printf(" usage: %s [option ...] interface\n\n", appname);
|
||||
printf(" where valid options are:\n");
|
||||
printf(" -b don't display beacon frames\n");
|
||||
printf(" -r don't show received frames (shown by default)\n");
|
||||
printf(" -t show transmitted frames\n");
|
||||
printf(" -c don't show ctl frames\n");
|
||||
printf(" -m don't show mgmt frames\n");
|
||||
printf(" -d don't show data frames\n");
|
||||
printf(" -s <len> show, at most, this many data field bytes\n");
|
||||
printf(" -x show the whole frame as raw bytes\n");
|
||||
printf(" -w don't decrypt data frame contents\n");
|
||||
printf(" -u don't unfragment\n");
|
||||
printf(" -f show fragments as well as defragged frame\n");
|
||||
printf(" -k <<keyindex(0-3)>-xx:xx:xx:xx:xx>\n");
|
||||
printf(" set wep key[keyindex], don't foget to set all 4 keys\n");
|
||||
printf(" -v display the program version and exit.\n\n");
|
||||
printf(" Note: this program doesn't do a whole lot of cmdline argument validation\n");
|
||||
printf(" so be careful when setting them.\n\n");
|
||||
}
|
||||
/* end of file frdumper.c */
|
126
src/wlandump/wlandump.h
Normal file
126
src/wlandump/wlandump.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
#ifndef _FRDUMPER_H
|
||||
#define _FRDUMPER_H (1)
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#define APPNAME_MAX (32)
|
||||
#define INPUT_FILE_FRAME_MAXLEN ((WLAN_A3FR_MAXLEN * 3) + 2)
|
||||
#define STYPE_NAME_MAX (19)
|
||||
#define TOTAL_MGMT_FIXED_FIELDS (10)
|
||||
#define TOTAL_MGMT_INFO_ELEMENTS (8)
|
||||
#define TYPE_NAME_MAX (5)
|
||||
|
||||
/* Management Frame Fixed Field Types */
|
||||
#define MGMT_FF_AUTH_ALG (0)
|
||||
#define MGMT_FF_AUTH_SEQ (1)
|
||||
#define MGMT_FF_BCN_INT (2)
|
||||
#define MGMT_FF_CAP_INFO (3)
|
||||
#define MGMT_FF_CURR_AP (4)
|
||||
#define MGMT_FF_LISTEN_INT (5)
|
||||
#define MGMT_FF_REASON (6)
|
||||
#define MGMT_FF_AID (7)
|
||||
#define MGMT_FF_STATUS (8)
|
||||
#define MGMT_FF_TS (9)
|
||||
|
||||
/* Management Frame Information Element Types */
|
||||
#define MGMT_IE_SSID (0)
|
||||
#define MGMT_IE_SUPP_RATES (1)
|
||||
#define MGMT_IE_FH_PARMS (2)
|
||||
#define MGMT_IE_DS_PARMS (3)
|
||||
#define MGMT_IE_CF_PARMS (4)
|
||||
#define MGMT_IE_TIM (5)
|
||||
#define MGMT_IE_IBSS_PARMS (6)
|
||||
#define MGMT_IE_CHALLENGE (7)
|
||||
|
||||
/* Management Frame Types */
|
||||
#define MGMT_TYPE_ASSOCREQ (0)
|
||||
#define MGMT_TYPE_ASSOCRESP (1)
|
||||
#define MGMT_TYPE_ATIM (2)
|
||||
#define MGMT_TYPE_AUTHEN (3)
|
||||
#define MGMT_TYPE_BEACON (4)
|
||||
#define MGMT_TYPE_DEAUTHEN (5)
|
||||
#define MGMT_TYPE_DISASSOC (6)
|
||||
#define MGMT_TYPE_PROBEREQ (7)
|
||||
#define MGMT_TYPE_PROBERESP (8)
|
||||
#define MGMT_TYPE_REASSOCREQ (9)
|
||||
#define MGMT_TYPE_REASSOCRESP (10)
|
||||
|
||||
/* Data Frame Types */
|
||||
#define DATA_TYPE_DATAONLY (11)
|
||||
#define DATA_TYPE_DATA_CFACK (12)
|
||||
#define DATA_TYPE_DATA_CFPOLL (13)
|
||||
#define DATA_TYPE_DATA_CFACK_CFPOLL (14)
|
||||
#define DATA_TYPE_NULL (15)
|
||||
#define DATA_TYPE_CFACK (16)
|
||||
#define DATA_TYPE_CFPOLL (17)
|
||||
#define DATA_TYPE_CFACK_CFPOLL (18)
|
||||
|
||||
/* Control Frame Types */
|
||||
#define CTL_TYPE_PSPOLL (19)
|
||||
#define CTL_TYPE_RTS (20)
|
||||
#define CTL_TYPE_CTS (21)
|
||||
#define CTL_TYPE_ACK (22)
|
||||
#define CTL_TYPE_CFEND (23)
|
||||
#define CTL_TYPE_CFENDCFACK (24)
|
||||
|
||||
typedef struct wlan_p80211_frame
|
||||
{
|
||||
char type[TYPE_NAME_MAX + 1];
|
||||
char stype[STYPE_NAME_MAX + 1];
|
||||
void (*pfunc)( UINT8 *, int, UINT16 );
|
||||
} wlan_p80211_frame_t;
|
||||
|
||||
typedef struct wlan_p80211_frame_fields
|
||||
{
|
||||
UINT8 exists;
|
||||
void *info;
|
||||
} wlan_p80211_frame_fields_t;
|
||||
|
||||
extern char appname[APPNAME_MAX + 1];
|
||||
|
||||
extern int opt_nobeacon;
|
||||
extern int opt_showrx;
|
||||
extern int opt_showtx;
|
||||
extern int opt_noshowctl;
|
||||
extern int opt_noshowmgmt;
|
||||
extern int opt_noshowdata;
|
||||
extern int opt_showdatalen;
|
||||
extern int opt_showraw;
|
||||
extern int opt_nodecrypt;
|
||||
extern int opt_nodefrag;
|
||||
extern int opt_showfrags;
|
||||
extern int opt_wepkeyset;
|
||||
extern UINT8 wep_key[WLAN_WEP_NKEYS][WLAN_WEP_KEYLEN];
|
||||
|
||||
int print_80211_frame( wlan_sniffer_t *snif, UINT8 *frame_buffer, UINT16 len );
|
||||
void print_80211_frame_ctl( p80211_hdr_t *phdr, int index );
|
||||
void print_80211_mgmt_header( p80211_hdr_t *phdr, int index, UINT16 len );
|
||||
void print_ctl_frame( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_ack( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_cfend( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_cfendcfack( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_cts( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_pspoll( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_ctl_rts( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_data_frame( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_fixed_fields( wlan_p80211_frame_fields_t *ff, UINT16 len );
|
||||
void print_info_elements( wlan_p80211_frame_fields_t *ie, UINT16 len );
|
||||
void print_mgmt_assocreq( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_assocresp( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_authen( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_beacon( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_deauthen( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_disassoc( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_ibssatim( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_probereq( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_proberesp( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_reassocreq( UINT8 *pbuf, int index, UINT16 len );
|
||||
void print_mgmt_reassocresp( UINT8 *pbuf, int index, UINT16 len );
|
||||
|
||||
void wlandump_crc32_mktable(void);
|
||||
void wlandump_wep_decrypt( UINT8 *f, UINT16 len);
|
||||
|
||||
#endif /* _FRDUMPER_H */
|
||||
|
Loading…
Reference in a new issue