init
This commit is contained in:
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
IFACE=wlan0
|
||||
|
||||
### check for command line arguments
|
||||
if [[ $# -eq 1 ]]
|
||||
then
|
||||
IFACE=$1
|
||||
|
||||
elif [[ $# != "0" ]]
|
||||
then
|
||||
echo "too much command line arguments!"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "setting interface >>${IFACE}<< to managed mode"
|
||||
|
||||
sudo ifconfig ${IFACE} down
|
||||
sudo iwconfig ${IFACE} mode managed
|
||||
sudo ifconfig ${IFACE} up
|
||||
sudo service network-manager start
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
IFACE=wlan0
|
||||
CHANNEL=3
|
||||
|
||||
### check for command line arguments
|
||||
if [[ $# -eq 2 ]]
|
||||
then
|
||||
CHANNEL=$1
|
||||
IFACE=$2
|
||||
|
||||
elif [[ $# -eq 1 ]]
|
||||
then
|
||||
CHANNEL=$1
|
||||
|
||||
elif [[ $# != "0" ]]
|
||||
then
|
||||
echo "too much command line arguments!"
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
echo "setting interface >>${IFACE}<< to monitor channel >>${CHANNEL}<<"
|
||||
|
||||
sudo service network-manager stop
|
||||
sudo ifconfig ${IFACE} down
|
||||
sudo iwconfig ${IFACE} mode monitor
|
||||
sudo iwconfig ${IFACE} channel ${CHANNEL}
|
||||
sudo ifconfig ${IFACE} up
|
||||
@@ -0,0 +1,16 @@
|
||||
packetspammer: packetspammer.c
|
||||
gcc -Wall radiotap.c packetspammer.c -o packetspammer -lpcap
|
||||
|
||||
clean:
|
||||
rm -f packetspammer *~
|
||||
|
||||
send: packetspammer
|
||||
scp packetspammer root@192.168.0.60:/usr/local/bin
|
||||
# scp packetspammer root@192.168.0.99:/usr/local/bin
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)/usr/bin
|
||||
cp packetspammer $(DESTDIR)/usr/bin
|
||||
|
||||
style:
|
||||
cstyle packetspammer.c radiotap.c
|
||||
@@ -0,0 +1,34 @@
|
||||
Packetspammer
|
||||
Andy Green <andy@warmcat.com>
|
||||
|
||||
Packetspammer sends unencrypted broadcast packets down a mac80211 wireless
|
||||
interface that should be set for Monitor mode. It spams the packets down the
|
||||
interface as fast as it can, although you can specify a delay between packets.
|
||||
|
||||
At the same time it is listening for packets with a MAC of 13:22:33:44:xx:xx
|
||||
and will display metadata about any incoming packets (like the bitrate) and
|
||||
the packet contents. So if you run packetspammer on two nearby machines, they
|
||||
will show each other's packets like this:
|
||||
|
||||
RX: Rate: 54.0Mbps, Freq: 2.417GHz, Ant: 0, Flags: 10
|
||||
0000: 50 61 63 6B 65 74 73 70 61 6D 6D 65 72 20 2D 2D Packetspammer --
|
||||
0010: 62 72 6F 61 64 63 61 73 74 20 70 61 63 6B 65 74 broadcast packet
|
||||
0020: 23 34 37 39 31 36 20 2D 2D 20 3A 2D 44 20 2D 2D #47916 -- :-D --
|
||||
0030: 75 6C 74 72 61 63 61 74 2E 68 6F 6D 65 2E 77 61 ultracat.home.wa
|
||||
0040: 72 6D 63 61 74 2E 63 6F 6D rmcat.com
|
||||
|
||||
|
||||
Typical usage:
|
||||
|
||||
echo -n mon0 > /sys/class/ieee80211/phy0/add_iface
|
||||
iwconfig mon0 mode monitor
|
||||
ifconfig mon0 up
|
||||
packetspammer mon0
|
||||
|
||||
You may need to bring up your normal interface first and set its channel, eg
|
||||
|
||||
ifconfig wlan0 up
|
||||
iwconfig wlan0 channel 2
|
||||
|
||||
If you normal interface is associated to an AP on a particular channel, that's
|
||||
fine, the packet injection won't disturb the association.
|
||||
@@ -0,0 +1,260 @@
|
||||
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
|
||||
/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003, 2004 David Young. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of David Young may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
|
||||
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications to fit into the linux IEEE 802.11 stack,
|
||||
* Mike Kershaw (dragorn@kismetwireless.net)
|
||||
*/
|
||||
|
||||
#ifndef IEEE80211RADIOTAP_H
|
||||
#define IEEE80211RADIOTAP_H
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/* Radiotap header version (from official NetBSD feed) */
|
||||
#define IEEE80211RADIOTAP_VERSION "1.5"
|
||||
/* Base version of the radiotap packet header data */
|
||||
#define PKTHDR_RADIOTAP_VERSION 0
|
||||
|
||||
/* A generic radio capture format is desirable. There is one for
|
||||
* Linux, but it is neither rigidly defined (there were not even
|
||||
* units given for some fields) nor easily extensible.
|
||||
*
|
||||
* I suggest the following extensible radio capture format. It is
|
||||
* based on a bitmap indicating which fields are present.
|
||||
*
|
||||
* I am trying to describe precisely what the application programmer
|
||||
* should expect in the following, and for that reason I tell the
|
||||
* units and origin of each measurement (where it applies), or else I
|
||||
* use sufficiently weaselly language ("is a monotonically nondecreasing
|
||||
* function of...") that I cannot set false expectations for lawyerly
|
||||
* readers.
|
||||
*/
|
||||
|
||||
/* XXX tcpdump/libpcap do not tolerate variable-length headers,
|
||||
* yet, so we pad every radiotap header to 64 bytes. Ugh.
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_HDRLEN 64
|
||||
|
||||
/* The radio capture header precedes the 802.11 header.
|
||||
* All data in the header is little endian on all platforms.
|
||||
*/
|
||||
struct ieee80211_radiotap_header {
|
||||
u8 it_version; /* Version 0. Only increases
|
||||
* for drastic changes,
|
||||
* introduction of compatible
|
||||
* new fields does not count.
|
||||
*/
|
||||
u8 it_pad;
|
||||
__le16 it_len; /* length of the whole
|
||||
* header in bytes, including
|
||||
* it_version, it_pad,
|
||||
* it_len, and data fields.
|
||||
*/
|
||||
__le32 it_present; /* A bitmap telling which
|
||||
* fields are present. Set bit 31
|
||||
* (0x80000000) to extend the
|
||||
* bitmap by another 32 bits.
|
||||
* Additional extensions are made
|
||||
* by setting bit 31.
|
||||
*/
|
||||
};
|
||||
|
||||
#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
|
||||
|
||||
/* Name Data type Units
|
||||
* ---- --------- -----
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TSFT __le64 microseconds
|
||||
*
|
||||
* Value in microseconds of the MAC's 64-bit 802.11 Time
|
||||
* Synchronization Function timer when the first bit of the
|
||||
* MPDU arrived at the MAC. For received frames, only.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
|
||||
*
|
||||
* Tx/Rx frequency in MHz, followed by flags (see below).
|
||||
*
|
||||
* IEEE80211_RADIOTAP_FHSS __le16 see below
|
||||
*
|
||||
* For frequency-hopping radios, the hop set (first byte)
|
||||
* and pattern (second byte).
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RATE u8 500kb/s
|
||||
*
|
||||
* Tx/Rx data rate
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* RF signal power at the antenna, decibel difference from
|
||||
* one milliwatt.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* RF noise power at the antenna, decibel difference from one
|
||||
* milliwatt.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
|
||||
*
|
||||
* RF signal power at the antenna, decibel difference from an
|
||||
* arbitrary, fixed reference.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
|
||||
*
|
||||
* RF noise power at the antenna, decibel difference from an
|
||||
* arbitrary, fixed reference point.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
|
||||
*
|
||||
* Quality of Barker code lock. Unitless. Monotonically
|
||||
* nondecreasing with "better" lock strength. Called "Signal
|
||||
* Quality" in datasheets. (Is there a standard way to measure
|
||||
* this?)
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
|
||||
*
|
||||
* Transmit power expressed as unitless distance from max
|
||||
* power set at factory calibration. 0 is max power.
|
||||
* Monotonically nondecreasing with lower power levels.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
|
||||
*
|
||||
* Transmit power expressed as decibel distance from max power
|
||||
* set at factory calibration. 0 is max power. Monotonically
|
||||
* nondecreasing with lower power levels.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
|
||||
* one milliwatt (dBm)
|
||||
*
|
||||
* Transmit power expressed as dBm (decibels from a 1 milliwatt
|
||||
* reference). This is the absolute power level measured at
|
||||
* the antenna port.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_FLAGS u8 bitmap
|
||||
*
|
||||
* Properties of transmitted and received frames. See flags
|
||||
* defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_ANTENNA u8 antenna index
|
||||
*
|
||||
* Unitless indication of the Rx/Tx antenna for this packet.
|
||||
* The first antenna is antenna 0.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
|
||||
*
|
||||
* Properties of received frames. See flags defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
|
||||
*
|
||||
* Properties of transmitted frames. See flags defined below.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_RTS_RETRIES u8 data
|
||||
*
|
||||
* Number of rts retries a transmitted frame used.
|
||||
*
|
||||
* IEEE80211_RADIOTAP_DATA_RETRIES u8 data
|
||||
*
|
||||
* Number of unicast retries a transmitted frame used.
|
||||
*
|
||||
*/
|
||||
enum ieee80211_radiotap_type {
|
||||
IEEE80211_RADIOTAP_TSFT = 0,
|
||||
IEEE80211_RADIOTAP_FLAGS = 1,
|
||||
IEEE80211_RADIOTAP_RATE = 2,
|
||||
IEEE80211_RADIOTAP_CHANNEL = 3,
|
||||
IEEE80211_RADIOTAP_FHSS = 4,
|
||||
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
|
||||
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
|
||||
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
|
||||
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
|
||||
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
|
||||
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
|
||||
IEEE80211_RADIOTAP_ANTENNA = 11,
|
||||
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
|
||||
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
|
||||
IEEE80211_RADIOTAP_RX_FLAGS = 14,
|
||||
IEEE80211_RADIOTAP_TX_FLAGS = 15,
|
||||
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
|
||||
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
|
||||
IEEE80211_RADIOTAP_EXT = 31
|
||||
};
|
||||
|
||||
/* Channel flags. */
|
||||
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
|
||||
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
|
||||
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
|
||||
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
|
||||
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
|
||||
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
|
||||
#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
|
||||
#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
|
||||
|
||||
/* For IEEE80211_RADIOTAP_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
|
||||
* during CFP
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
|
||||
* with short
|
||||
* preamble
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
|
||||
* with WEP encryption
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
|
||||
* with fragmentation
|
||||
*/
|
||||
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
|
||||
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
|
||||
* 802.11 header and payload
|
||||
* (to 32-bit boundary)
|
||||
*/
|
||||
/* For IEEE80211_RADIOTAP_RX_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
|
||||
|
||||
/* For IEEE80211_RADIOTAP_TX_FLAGS */
|
||||
#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
|
||||
* retries */
|
||||
#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
|
||||
#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
|
||||
|
||||
/* Ugly macro to convert literal channel numbers into their mhz equivalents
|
||||
* There are certianly some conditions that will break this (like feeding it '30')
|
||||
* but they shouldn't arise since nothing talks on channel 30. */
|
||||
#define ieee80211chan2mhz(x) \
|
||||
(((x) <= 14) ? \
|
||||
(((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
|
||||
((x) + 1000) * 5)
|
||||
|
||||
#endif /* IEEE80211_RADIOTAP_H */
|
||||
@@ -0,0 +1,388 @@
|
||||
// (c)2007 Andy Green <andy@warmcat.com>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
// Thanks for contributions:
|
||||
// 2007-03-15 fixes to getopt_long code by Matteo Croce rootkit85@yahoo.it
|
||||
|
||||
#include "packetspammer.h"
|
||||
#include "radiotap.h"
|
||||
|
||||
/* wifi bitrate to use in 500kHz units */
|
||||
|
||||
static const u8 u8aRatesToUse[] = {
|
||||
|
||||
54*2,
|
||||
48*2,
|
||||
36*2,
|
||||
24*2,
|
||||
18*2,
|
||||
12*2,
|
||||
9*2,
|
||||
11*2,
|
||||
11, // 5.5
|
||||
2*2,
|
||||
1*2
|
||||
};
|
||||
|
||||
/* this is the template radiotap header we send packets out with */
|
||||
|
||||
static const u8 u8aRadiotapHeader[] = {
|
||||
|
||||
0x00, 0x00, // <-- radiotap version
|
||||
0x16, 0x00, // <- radiotap header length
|
||||
0x0f, 0x00, 0x00, 0x00, // <-- bitmap
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
|
||||
0x00, // <-- flags (Offset +0x10)
|
||||
0x6c, // <-- rate (0ffset +0x11)
|
||||
0x64, 0x14, 0x40, 0x01, // <-- channel
|
||||
// 0x00, // <-- antsignal
|
||||
// 0x00, // <-- antnoise
|
||||
// 0x00, // <-- antenna
|
||||
|
||||
};
|
||||
#define OFFSET_FLAGS 0x10
|
||||
#define OFFSET_RATE 0x11
|
||||
|
||||
/* Penumbra IEEE80211 header */
|
||||
|
||||
static const u8 u8aIeeeHeader[] = {
|
||||
0x08, 0x01, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
|
||||
0x10, 0x86,
|
||||
};
|
||||
|
||||
// this is where we store a summary of the
|
||||
// information from the radiotap header
|
||||
|
||||
typedef struct {
|
||||
int m_nChannel;
|
||||
int m_nChannelFlags;
|
||||
int m_nRate;
|
||||
int m_nAntenna;
|
||||
int m_nRadiotapFlags;
|
||||
} __attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
|
||||
|
||||
|
||||
|
||||
int flagHelp = 0, flagMarkWithFCS = 0;
|
||||
|
||||
void
|
||||
Dump(u8 * pu8, int nLength)
|
||||
{
|
||||
char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
|
||||
unsigned char baaLast[2][16];
|
||||
uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
|
||||
|
||||
buf = szBuf;
|
||||
szChar[0] = '\0';
|
||||
|
||||
for (n = 0; n < nLength; n++) {
|
||||
baaLast[(nLine&1)^1][n&0xf] = pu8[n];
|
||||
if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
|
||||
szChar[n&0xf] = '.';
|
||||
else
|
||||
szChar[n&0xf] = pu8[n];
|
||||
szChar[(n&0xf)+1] = '\0';
|
||||
nPos += sprintf(&sz[nPos], "%02X ",
|
||||
baaLast[(nLine&1)^1][n&0xf]);
|
||||
if ((n&15) != 15)
|
||||
continue;
|
||||
if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) {
|
||||
nSameCount++;
|
||||
} else {
|
||||
if (nSameCount)
|
||||
buf += sprintf(buf, "(repeated %d times)\n",
|
||||
nSameCount);
|
||||
buf += sprintf(buf, "%04x: %s %s\n",
|
||||
nStart, sz, szChar);
|
||||
nSameCount = 0;
|
||||
printf("%s", szBuf);
|
||||
buf = szBuf;
|
||||
}
|
||||
nPos = 0; nStart = n+1; nLine++;
|
||||
fFirst = 0; sz[0] = '\0'; szChar[0] = '\0';
|
||||
}
|
||||
if (nSameCount)
|
||||
buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
|
||||
|
||||
buf += sprintf(buf, "%04x: %s", nStart, sz);
|
||||
if (n & 0xf) {
|
||||
*buf++ = ' ';
|
||||
while (n & 0xf) {
|
||||
buf += sprintf(buf, " ");
|
||||
n++;
|
||||
}
|
||||
}
|
||||
buf += sprintf(buf, "%s\n", szChar);
|
||||
printf("%s", szBuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf(
|
||||
"(c)2006-2007 Andy Green <andy@warmcat.com> Licensed under GPL2\n"
|
||||
"\n"
|
||||
"Usage: packetspammer [options] <interface>\n\nOptions\n"
|
||||
"-d/--delay <delay> Delay between packets\n\n"
|
||||
"-f/--fcs Mark as having FCS (CRC) already\n"
|
||||
" (pkt ends with 4 x sacrificial - chars)\n"
|
||||
"Example:\n"
|
||||
" echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
|
||||
" iwconfig mon0 mode monitor\n"
|
||||
" ifconfig mon0 up\n"
|
||||
" packetspammer mon0 Spam down mon0 with\n"
|
||||
" radiotap header first\n"
|
||||
"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
u8 u8aSendBuffer[500];
|
||||
char szErrbuf[PCAP_ERRBUF_SIZE];
|
||||
int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
|
||||
int nOrdinal = 0, r, nDelay = 100000;
|
||||
int nRateIndex = 0, retval, bytes;
|
||||
pcap_t *ppcap = NULL;
|
||||
struct bpf_program bpfprogram;
|
||||
char * szProgram = "", fBrokenSocket = 0;
|
||||
u16 u16HeaderLen;
|
||||
char szHostname[PATH_MAX];
|
||||
|
||||
if (gethostname(szHostname, sizeof (szHostname) - 1)) {
|
||||
perror("unable to get hostname");
|
||||
}
|
||||
szHostname[sizeof (szHostname) - 1] = '\0';
|
||||
|
||||
|
||||
printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
|
||||
|
||||
while (1) {
|
||||
int nOptionIndex;
|
||||
static const struct option optiona[] = {
|
||||
{ "delay", required_argument, NULL, 'd' },
|
||||
{ "fcs", no_argument, &flagMarkWithFCS, 1 },
|
||||
{ "help", no_argument, &flagHelp, 1 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
int c = getopt_long(argc, argv, "d:hf",
|
||||
optiona, &nOptionIndex);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
case 0: // long option
|
||||
break;
|
||||
|
||||
case 'h': // help
|
||||
usage();
|
||||
|
||||
case 'd': // delay
|
||||
nDelay = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'f': // mark as FCS attached
|
||||
flagMarkWithFCS = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unknown switch %c\n", c);
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
usage();
|
||||
|
||||
|
||||
// open the interface in pcap
|
||||
|
||||
szErrbuf[0] = '\0';
|
||||
ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
|
||||
if (ppcap == NULL) {
|
||||
printf("Unable to open interface %s in pcap: %s\n",
|
||||
argv[optind], szErrbuf);
|
||||
return (1);
|
||||
}
|
||||
|
||||
nLinkEncap = pcap_datalink(ppcap);
|
||||
nCaptureHeaderLength = 0;
|
||||
|
||||
switch (nLinkEncap) {
|
||||
|
||||
case DLT_PRISM_HEADER:
|
||||
printf("DLT_PRISM_HEADER Encap\n");
|
||||
nCaptureHeaderLength = 0x40;
|
||||
n80211HeaderLength = 0x20; // ieee80211 comes after this
|
||||
szProgram = "radio[0x4a:4]==0x13223344";
|
||||
break;
|
||||
|
||||
case DLT_IEEE802_11_RADIO:
|
||||
printf("DLT_IEEE802_11_RADIO Encap\n");
|
||||
nCaptureHeaderLength = 0x40;
|
||||
n80211HeaderLength = 0x18; // ieee80211 comes after this
|
||||
szProgram = "ether[0x0a:4]==0x13223344";
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("!!! unknown encapsulation on %s !\n", argv[1]);
|
||||
return (1);
|
||||
|
||||
}
|
||||
|
||||
if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
|
||||
puts(szProgram);
|
||||
puts(pcap_geterr(ppcap));
|
||||
return (1);
|
||||
} else {
|
||||
if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
|
||||
puts(szProgram);
|
||||
puts(pcap_geterr(ppcap));
|
||||
} else {
|
||||
printf("RX Filter applied\n");
|
||||
}
|
||||
pcap_freecode(&bpfprogram);
|
||||
}
|
||||
|
||||
pcap_setnonblock(ppcap, 1, szErrbuf);
|
||||
|
||||
printf(" (delay between packets %dus)\n", nDelay);
|
||||
|
||||
memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
|
||||
|
||||
while (!fBrokenSocket) {
|
||||
u8 * pu8 = u8aSendBuffer;
|
||||
struct pcap_pkthdr * ppcapPacketHeader = NULL;
|
||||
struct ieee80211_radiotap_iterator rti;
|
||||
PENUMBRA_RADIOTAP_DATA prd;
|
||||
u8 * pu8Payload = u8aSendBuffer;
|
||||
int n, nRate;
|
||||
|
||||
// receive
|
||||
|
||||
retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
|
||||
(const u_char**)&pu8Payload);
|
||||
|
||||
if (retval < 0) {
|
||||
fBrokenSocket = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (retval != 1)
|
||||
goto do_tx;
|
||||
|
||||
u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
|
||||
|
||||
printf("rtap: ");
|
||||
Dump(pu8Payload, u16HeaderLen);
|
||||
|
||||
if (ppcapPacketHeader->len <
|
||||
(u16HeaderLen + n80211HeaderLength))
|
||||
continue;
|
||||
|
||||
bytes = ppcapPacketHeader->len -
|
||||
(u16HeaderLen + n80211HeaderLength);
|
||||
if (bytes < 0)
|
||||
continue;
|
||||
|
||||
if (ieee80211_radiotap_iterator_init(&rti,
|
||||
(struct ieee80211_radiotap_header *)pu8Payload,
|
||||
bytes) < 0)
|
||||
continue;
|
||||
|
||||
while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
|
||||
|
||||
switch (rti.this_arg_index) {
|
||||
case IEEE80211_RADIOTAP_RATE:
|
||||
prd.m_nRate = (*rti.this_arg);
|
||||
break;
|
||||
|
||||
case IEEE80211_RADIOTAP_CHANNEL:
|
||||
prd.m_nChannel =
|
||||
le16_to_cpu(*((u16 *)rti.this_arg));
|
||||
prd.m_nChannelFlags =
|
||||
le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
|
||||
break;
|
||||
|
||||
case IEEE80211_RADIOTAP_ANTENNA:
|
||||
prd.m_nAntenna = (*rti.this_arg) + 1;
|
||||
break;
|
||||
|
||||
case IEEE80211_RADIOTAP_FLAGS:
|
||||
prd.m_nRadiotapFlags = *rti.this_arg;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pu8Payload += u16HeaderLen + n80211HeaderLength;
|
||||
|
||||
if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
|
||||
bytes -= 4;
|
||||
|
||||
printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
|
||||
"Ant: %d, Flags: 0x%X\n",
|
||||
prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
|
||||
prd.m_nChannel / 1000,
|
||||
prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
|
||||
prd.m_nAntenna,
|
||||
prd.m_nRadiotapFlags);
|
||||
|
||||
Dump(pu8Payload, bytes);
|
||||
|
||||
do_tx:
|
||||
|
||||
// transmit
|
||||
|
||||
memcpy(u8aSendBuffer, u8aRadiotapHeader,
|
||||
sizeof (u8aRadiotapHeader));
|
||||
if (flagMarkWithFCS)
|
||||
pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
|
||||
nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
|
||||
if (nRateIndex >= sizeof (u8aRatesToUse))
|
||||
nRateIndex = 0;
|
||||
pu8 += sizeof (u8aRadiotapHeader);
|
||||
|
||||
memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
|
||||
pu8 += sizeof (u8aIeeeHeader);
|
||||
|
||||
pu8 += sprintf((char *)pu8,
|
||||
"Packetspammer %02d"
|
||||
"broadcast packet"
|
||||
"#%05d -- :-D --%s ----",
|
||||
nRate/2, nOrdinal++, szHostname);
|
||||
r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
|
||||
if (r != (pu8-u8aSendBuffer)) {
|
||||
perror("Trouble injecting packet");
|
||||
return (1);
|
||||
}
|
||||
if (nDelay)
|
||||
usleep(nDelay);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <utime.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <pcap.h>
|
||||
#include <endian.h>
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
typedef u32 __le32;
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define le16_to_cpu(x) (x)
|
||||
#define le32_to_cpu(x) (x)
|
||||
#else
|
||||
#define le16_to_cpu(x) ((((x)&0xff)<<8)|(((x)&0xff00)>>8))
|
||||
#define le32_to_cpu(x) \
|
||||
((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)&0xff0000)>>8)|(((x)&0xff000000)>>24))
|
||||
#endif
|
||||
#define unlikely(x) (x)
|
||||
|
||||
#define MAX_PENUMBRA_INTERFACES 8
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Radiotap parser
|
||||
*
|
||||
* Copyright 2007 Andy Green <andy@warmcat.com>
|
||||
*/
|
||||
|
||||
#include "packetspammer.h"
|
||||
#include "radiotap.h"
|
||||
|
||||
/**
|
||||
* ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
|
||||
* @iterator: radiotap_iterator to initialize
|
||||
* @radiotap_header: radiotap header to parse
|
||||
* @max_length: total length we can parse into (eg, whole packet length)
|
||||
*
|
||||
* Returns: 0 or a negative error code if there is a problem.
|
||||
*
|
||||
* This function initializes an opaque iterator struct which can then
|
||||
* be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
|
||||
* argument which is present in the header. It knows about extended
|
||||
* present headers and handles them.
|
||||
*
|
||||
* How to use:
|
||||
* call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
|
||||
* struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
|
||||
* checking for a good 0 return code. Then loop calling
|
||||
* __ieee80211_radiotap_iterator_next()... it returns either 0,
|
||||
* -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
|
||||
* The iterator's @this_arg member points to the start of the argument
|
||||
* associated with the current argument index that is present, which can be
|
||||
* found in the iterator's @this_arg_index member. This arg index corresponds
|
||||
* to the IEEE80211_RADIOTAP_... defines.
|
||||
*
|
||||
* Radiotap header length:
|
||||
* You can find the CPU-endian total radiotap header length in
|
||||
* iterator->max_length after executing ieee80211_radiotap_iterator_init()
|
||||
* successfully.
|
||||
*
|
||||
* Example code:
|
||||
* See Documentation/networking/radiotap-headers.txt
|
||||
*/
|
||||
|
||||
int ieee80211_radiotap_iterator_init(
|
||||
struct ieee80211_radiotap_iterator *iterator,
|
||||
struct ieee80211_radiotap_header *radiotap_header,
|
||||
int max_length)
|
||||
{
|
||||
/* Linux only supports version 0 radiotap format */
|
||||
if (radiotap_header->it_version)
|
||||
return -EINVAL;
|
||||
|
||||
/* sanity check for allowed length and radiotap length field */
|
||||
if (max_length < le16_to_cpu(radiotap_header->it_len))
|
||||
return -EINVAL;
|
||||
|
||||
iterator->rtheader = radiotap_header;
|
||||
iterator->max_length = le16_to_cpu(radiotap_header->it_len);
|
||||
iterator->arg_index = 0;
|
||||
iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present);
|
||||
iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
|
||||
iterator->this_arg = 0;
|
||||
|
||||
/* find payload start allowing for extended bitmap(s) */
|
||||
|
||||
if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
|
||||
while (le32_to_cpu(*((u32 *)iterator->arg)) &
|
||||
(1<<IEEE80211_RADIOTAP_EXT)) {
|
||||
iterator->arg += sizeof(u32);
|
||||
|
||||
/*
|
||||
* check for insanity where the present bitmaps
|
||||
* keep claiming to extend up to or even beyond the
|
||||
* stated radiotap header length
|
||||
*/
|
||||
|
||||
if (((ulong)iterator->arg -
|
||||
(ulong)iterator->rtheader) > iterator->max_length)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iterator->arg += sizeof(u32);
|
||||
|
||||
/*
|
||||
* no need to check again for blowing past stated radiotap
|
||||
* header length, because ieee80211_radiotap_iterator_next
|
||||
* checks it before it is dereferenced
|
||||
*/
|
||||
}
|
||||
|
||||
/* we are all initialized happily */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
|
||||
* @iterator: radiotap_iterator to move to next arg (if any)
|
||||
*
|
||||
* Returns: 0 if there is an argument to handle,
|
||||
* -ENOENT if there are no more args or -EINVAL
|
||||
* if there is something else wrong.
|
||||
*
|
||||
* This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
|
||||
* in @this_arg_index and sets @this_arg to point to the
|
||||
* payload for the field. It takes care of alignment handling and extended
|
||||
* present fields. @this_arg can be changed by the caller (eg,
|
||||
* incremented to move inside a compound argument like
|
||||
* IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
|
||||
* little-endian format whatever the endianess of your CPU.
|
||||
*/
|
||||
|
||||
int ieee80211_radiotap_iterator_next(
|
||||
struct ieee80211_radiotap_iterator *iterator)
|
||||
{
|
||||
|
||||
/*
|
||||
* small length lookup table for all radiotap types we heard of
|
||||
* starting from b0 in the bitmap, so we can walk the payload
|
||||
* area of the radiotap header
|
||||
*
|
||||
* There is a requirement to pad args, so that args
|
||||
* of a given length must begin at a boundary of that length
|
||||
* -- but note that compound args are allowed (eg, 2 x u16
|
||||
* for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
|
||||
* a reliable indicator of alignment requirement.
|
||||
*
|
||||
* upper nybble: content alignment for arg
|
||||
* lower nybble: content length for arg
|
||||
*/
|
||||
|
||||
static const u8 rt_sizes[] = {
|
||||
[IEEE80211_RADIOTAP_TSFT] = 0x88,
|
||||
[IEEE80211_RADIOTAP_FLAGS] = 0x11,
|
||||
[IEEE80211_RADIOTAP_RATE] = 0x11,
|
||||
[IEEE80211_RADIOTAP_CHANNEL] = 0x24,
|
||||
[IEEE80211_RADIOTAP_FHSS] = 0x22,
|
||||
[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
|
||||
[IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
|
||||
[IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
|
||||
[IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
|
||||
[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
|
||||
[IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
|
||||
[IEEE80211_RADIOTAP_ANTENNA] = 0x11,
|
||||
[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
|
||||
[IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11
|
||||
/*
|
||||
* add more here as they are defined in
|
||||
* include/net/ieee80211_radiotap.h
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* for every radiotap entry we can at
|
||||
* least skip (by knowing the length)...
|
||||
*/
|
||||
|
||||
while (iterator->arg_index < sizeof(rt_sizes)) {
|
||||
int hit = 0;
|
||||
int pad;
|
||||
|
||||
if (!(iterator->bitmap_shifter & 1))
|
||||
goto next_entry; /* arg not present */
|
||||
|
||||
/*
|
||||
* arg is present, account for alignment padding
|
||||
* 8-bit args can be at any alignment
|
||||
* 16-bit args must start on 16-bit boundary
|
||||
* 32-bit args must start on 32-bit boundary
|
||||
* 64-bit args must start on 64-bit boundary
|
||||
*
|
||||
* note that total arg size can differ from alignment of
|
||||
* elements inside arg, so we use upper nybble of length
|
||||
* table to base alignment on
|
||||
*
|
||||
* also note: these alignments are ** relative to the
|
||||
* start of the radiotap header **. There is no guarantee
|
||||
* that the radiotap header itself is aligned on any
|
||||
* kind of boundary.
|
||||
*/
|
||||
|
||||
pad = (((ulong)iterator->arg) -
|
||||
((ulong)iterator->rtheader)) &
|
||||
((rt_sizes[iterator->arg_index] >> 4) - 1);
|
||||
|
||||
if (pad)
|
||||
iterator->arg_index +=
|
||||
(rt_sizes[iterator->arg_index] >> 4) - pad;
|
||||
|
||||
/*
|
||||
* this is what we will return to user, but we need to
|
||||
* move on first so next call has something fresh to test
|
||||
*/
|
||||
iterator->this_arg_index = iterator->arg_index;
|
||||
iterator->this_arg = iterator->arg;
|
||||
hit = 1;
|
||||
|
||||
/* internally move on the size of this arg */
|
||||
iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
|
||||
|
||||
/*
|
||||
* check for insanity where we are given a bitmap that
|
||||
* claims to have more arg content than the length of the
|
||||
* radiotap section. We will normally end up equalling this
|
||||
* max_length on the last arg, never exceeding it.
|
||||
*/
|
||||
|
||||
if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
|
||||
iterator->max_length)
|
||||
return -EINVAL;
|
||||
|
||||
next_entry:
|
||||
iterator->arg_index++;
|
||||
if (unlikely((iterator->arg_index & 31) == 0)) {
|
||||
/* completed current u32 bitmap */
|
||||
if (iterator->bitmap_shifter & 1) {
|
||||
/* b31 was set, there is more */
|
||||
/* move to next u32 bitmap */
|
||||
iterator->bitmap_shifter =
|
||||
le32_to_cpu(*iterator->next_bitmap);
|
||||
iterator->next_bitmap++;
|
||||
} else {
|
||||
/* no more bitmaps: end */
|
||||
iterator->arg_index = sizeof(rt_sizes);
|
||||
}
|
||||
} else { /* just try the next bit */
|
||||
iterator->bitmap_shifter >>= 1;
|
||||
}
|
||||
|
||||
/* if we found a valid arg earlier, return it now */
|
||||
if (hit)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we don't know how to handle any more args, we're done */
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "ieee80211_radiotap.h"
|
||||
|
||||
/* Radiotap header iteration
|
||||
* implemented in net/wireless/radiotap.c
|
||||
* docs in Documentation/networking/radiotap-headers.txt
|
||||
*/
|
||||
/**
|
||||
* struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
|
||||
* @rtheader: pointer to the radiotap header we are walking through
|
||||
* @max_length: length of radiotap header in cpu byte ordering
|
||||
* @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
|
||||
* @this_arg: pointer to current radiotap arg
|
||||
* @arg_index: internal next argument index
|
||||
* @arg: internal next argument pointer
|
||||
* @next_bitmap: internal pointer to next present u32
|
||||
* @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
|
||||
*/
|
||||
|
||||
struct ieee80211_radiotap_iterator {
|
||||
struct ieee80211_radiotap_header *rtheader;
|
||||
int max_length;
|
||||
int this_arg_index;
|
||||
u8 *this_arg;
|
||||
|
||||
int arg_index;
|
||||
u8 *arg;
|
||||
__le32 *next_bitmap;
|
||||
u32 bitmap_shifter;
|
||||
};
|
||||
|
||||
extern int ieee80211_radiotap_iterator_init(
|
||||
struct ieee80211_radiotap_iterator *iterator,
|
||||
struct ieee80211_radiotap_header *radiotap_header,
|
||||
int max_length);
|
||||
|
||||
extern int ieee80211_radiotap_iterator_next(
|
||||
struct ieee80211_radiotap_iterator *iterator);
|
||||
|
||||
Reference in New Issue
Block a user