update packet spammer

This commit is contained in:
Bastian Bloessl
2013-10-10 11:20:20 +02:00
parent 47f0f8b379
commit b5535e732d
+103 -285
View File
@@ -18,139 +18,60 @@
// Thanks for contributions: // Thanks for contributions:
// 2007-03-15 fixes to getopt_long code by Matteo Croce rootkit85@yahoo.it // 2007-03-15 fixes to getopt_long code by Matteo Croce rootkit85@yahoo.it
#include <time.h>
#include <stdlib.h>
#include "packetspammer.h" #include "packetspammer.h"
#include "radiotap.h" #include "radiotap.h"
/* wifi bitrate to use in 500kHz units */ static const uint8_t radiotap_hdr[] = {
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 0x00, 0x00, // <-- radiotap version
0x16, 0x00, // <- radiotap header length 0x19, 0x00, // <- radiotap header length
0x0f, 0x00, 0x00, 0x00, // <-- bitmap 0x6f, 0x08, 0x00, 0x00, // <-- bitmap
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
0x00, // <-- flags (Offset +0x10) 0x00, // <-- flags
0x6c, // <-- rate (0ffset +0x11) 0x0c, // <-- rate
0x64, 0x14, 0x40, 0x01, // <-- channel 0x71, 0x09, 0xc0, 0x00, // <-- channel
// 0x00, // <-- antsignal 0xde, // <-- antsignal
// 0x00, // <-- antnoise 0x00, // <-- antnoise
// 0x00, // <-- antenna 0x01, // <-- 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 static const char wifi_hdr[] = {
// information from the radiotap header 0x88, 0x00, 0x30, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
typedef struct { 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
int m_nChannel; 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
int m_nChannelFlags; 0xc0, 0x20, 0x20, 0x00
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);
}
static const char llc_hdr[] = {
0xaa, 0xaa, 0x03,
0x00, 0x00, 0x00,
0x88, 0xb5
};
static const char wsm_hdr[] = {
0x02, 0x55, 0x04, 0x01, 0x40, 0x10,
0x01, 0x0c, 0x0f, 0x01, 0xb2, 0x50,
0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void void
usage(void) usage(void)
{ {
printf( printf(
"(c)2006-2007 Andy Green <andy@warmcat.com> Licensed under GPL2\n" "(c)2006-2007 Andy Green <andy@warmcat.com> Licensed under GPL2\n\n"
"packet spammer\n=================================="
"\n" "\n"
"Usage: packetspammer [options] <interface>\n\nOptions\n" "Usage: packetspammer [options] <interface>\n\nOptions\n\n"
"-d/--delay <delay> Delay between packets\n\n" " -n/--number <nr packets> number of packets to send\n\n"
"-f/--fcs Mark as having FCS (CRC) already\n" " -r/--rate <rate> packets per second\n\n"
" (pkt ends with 4 x sacrificial - chars)\n" " -s/--size <size> packets size in byte (including MAC header)\n\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"); "\n");
exit(1); exit(1);
} }
@@ -159,51 +80,52 @@ usage(void)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
u8 u8aSendBuffer[500]; uint8_t buf[4092];
char szErrbuf[PCAP_ERRBUF_SIZE]; char szErrbuf[PCAP_ERRBUF_SIZE];
int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0; int r, nDelay = 100000;
int nOrdinal = 0, r, nDelay = 100000;
int nRateIndex = 0, retval, bytes;
pcap_t *ppcap = NULL; pcap_t *ppcap = NULL;
struct bpf_program bpfprogram; char fBrokenSocket = 0;
char * szProgram = "", fBrokenSocket = 0;
u16 u16HeaderLen;
char szHostname[PATH_MAX];
if (gethostname(szHostname, sizeof (szHostname) - 1)) { int rate = 1;
perror("unable to get hostname"); int number = 50;
} int size = 128;
szHostname[sizeof (szHostname) - 1] = '\0';
printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
while (1) { while (1) {
int nOptionIndex; int nOptionIndex;
static const struct option optiona[] = { static const struct option optiona[] = {
{ "delay", required_argument, NULL, 'd' }, { "run", required_argument, NULL, 'R' },
{ "fcs", no_argument, &flagMarkWithFCS, 1 }, { "rate", required_argument, NULL, 'r' },
{ "help", no_argument, &flagHelp, 1 }, { "number", required_argument, NULL, 'n' },
{ "size", required_argument, NULL, 's' },
{ "help", no_argument, NULL, 1 },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
int c = getopt_long(argc, argv, "d:hf",
int c = getopt_long(argc, argv, "R:r:n:s:h",
optiona, &nOptionIndex); optiona, &nOptionIndex);
if (c == -1) if (c == -1) {
break; break;
}
switch (c) { switch (c) {
case 0: // long option case 0: // long option
break; break;
case 'h': // help case 'h': // help
usage(); usage();
case 'd': // delay
nDelay = atoi(optarg);
break; break;
case 'f': // mark as FCS attached case 'r':
flagMarkWithFCS = 1; rate = atoi(optarg);
break;
case 'n':
number = atoi(optarg);
break;
case 's':
size = atoi(optarg);
break; break;
default: default:
@@ -216,173 +138,69 @@ main(int argc, char *argv[])
if (optind >= argc) if (optind >= argc)
usage(); usage();
// open the interface in pcap // open the interface in pcap
szErrbuf[0] = '\0';
ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf); ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
if (ppcap == NULL) { if (ppcap == NULL) {
printf("Unable to open interface %s in pcap: %s\n", printf("Unable to open interface %s in pcap: %s\n",
argv[optind], szErrbuf); argv[optind], szErrbuf);
return (1); 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); pcap_setnonblock(ppcap, 1, szErrbuf);
printf(" (delay between packets %dus)\n", nDelay); nDelay = 1000000 / rate;
memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer)); printf("rate %d\n", rate);
printf("number %d\n", number);
printf("delay %d\n", nDelay);
printf("size %d\n", size);
while (!fBrokenSocket) { memset(buf, 0, sizeof(buf));
u8 * pu8 = u8aSendBuffer; srand(time(NULL));
struct pcap_pkthdr * ppcapPacketHeader = NULL; int i;
struct ieee80211_radiotap_iterator rti; for(i = 0; i < sizeof(buf); i++) {
PENUMBRA_RADIOTAP_DATA prd; buf[i] = (rand() % 255) + 1;
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) while (!fBrokenSocket && number) {
goto do_tx; uint8_t *pu8 = buf;
u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8)); // radiotap header
memcpy(buf, radiotap_hdr,
sizeof(radiotap_hdr));
pu8 += sizeof(radiotap_hdr);
printf("rtap: "); // wifi header
Dump(pu8Payload, u16HeaderLen); memcpy(pu8, wifi_hdr, sizeof(wifi_hdr));
pu8 += sizeof(wifi_hdr);
if (ppcapPacketHeader->len < // llc header
(u16HeaderLen + n80211HeaderLength)) memcpy(pu8, llc_hdr, sizeof(llc_hdr));
continue; pu8 += sizeof(llc_hdr);
bytes = ppcapPacketHeader->len - pu8 += sprintf((char *)pu8, "%06d ", number);
(u16HeaderLen + n80211HeaderLength); pu8 += sprintf((char *)pu8, "%06d", size);
if (bytes < 0) *pu8 = 0;
continue; pu8++;
if (ieee80211_radiotap_iterator_init(&rti, int packet_size = size + sizeof(radiotap_hdr) - 4;
(struct ieee80211_radiotap_header *)pu8Payload, if((pu8 - buf) > packet_size) {
bytes) < 0) printf("size is too small: %d\n", size);
continue; return 1;
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; r = pcap_inject(ppcap, buf, packet_size);
if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS) if(r != packet_size) {
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"); perror("Trouble injecting packet");
return (1); return 1;
} }
if (nDelay)
if(nDelay) {
usleep(nDelay); usleep(nDelay);
} }
number--;
}
return 0;
return (0);
} }