📄 459.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>apue</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> ● UNIX网络编程 (BM: clown) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="321.htm">上一层</a>][<a href="460.htm">下一篇</a>]
<hr><p align="left"><small> cyclone 于 2001-5-13 17:40:50 加贴在 绿盟科技论坛(bbs.nsfocus.com)--UNIX系统 <br>
安全: <br>
我想还是把代码贴出来吧:请各位帮我看看 <br>
我用sniffer抓到的数据包也只有一个,并没有想象的那样给出三个分离的 <br>
ICMP(echo)数据包! <br>
========================= pthread ping ========================== <br>
#include ..... <br>
#define IP_HEAD_LEN 20 <br>
#define ICMP_LEN 8 <br>
#define TIMEOUT 2 //second <br>
void send_icmp(int j); <br>
int recv_icmp(int j); <br>
unsigned short ip_checksum( unsigned short *pcheck, int check_len); <br>
typedef struct destnation{ <br>
char destip[16]; <br>
int i; <br>
}destnation_ping; <br>
destnation_ping ping_dst[3]; <br>
char send_buf[3][1024]; <br>
char recv_buf[3][1024]; <br>
int p_id[3]; <br>
int sequence[3]; <br>
int icmp_fd[3]; <br>
int packet_len=IP_HEAD_LEN+ICMP_LEN; <br>
int pingf=0; // timeout flags <br>
int icmp_back=0;// Works for return int * <br>
struct sockaddr_in send_addr[3]; <br>
fd_set fdR[3]; <br>
/* <br>
* timeout_p:用于处理超时原因引起的备份服务器操作 <br>
*/ <br>
void timeout_p() <br>
{ <br>
pingf=0; <br>
printf("\nThe last result: --%d--\n\n", pingf); <br>
} <br>
/* <br>
* send_icmp:用于发送含ICMP报文的IP数据包 <br>
*/ <br>
void send_icmp(int j) <br>
{ <br>
int len; <br>
struct icmphdr *icmp_p; <br>
icmp_p=(struct icmphdr *)send_buf[j]; <br>
/* 填写ICMP报文的类型 */ <br>
icmp_p->type=ICMP_ECHO; <br>
/* 填写ICMP报文的代码 */ <br>
icmp_p->code=0; <br>
/* 填写ICMP报文的标示符 */ <br>
(icmp_p->un).echo.id=p_id[j]; <br>
/* 填写ICMP报文的序号 */ <br>
(icmp_p->un).echo.sequence=sequence[j]; <br>
gettimeofday( (struct timeval *)(icmp_p+1), NULL); <br>
/*报文的长度等于IP包头的长度加上ICMP报文头的长度和数据的长度 */ <br>
len=sizeof(struct timeval)+packet_len; <br>
/* 使用IP计算IP包头校验和的计算方法来计算ICMP的校验和 */ <br>
icmp_p->checksum=0; <br>
icmp_p->checksum=ip_checksum( (u_short *)icmp_p, len); <br>
/* 发送IP书记包 */ <br>
printf("sendto %s. sequence[%d]=%d\n", inet_ntoa(send_addr[j].sin_addr), <br>
<br>
j, sequence[j]); <br>
len=sendto(icmp_fd[j], send_buf[j], len, 0, <br>
(struct sockaddr *)&send_addr[j], sizeof(send_addr[j])); <br>
if(len<0) <br>
fprintf(stderr, "sendto error.\n"); <br>
sequence[j]++; <br>
} <br>
/* <br>
* recv_icmp() 用于接受包含ICMP包文的IP数据包 <br>
*/ <br>
int recv_icmp(int j) <br>
{ <br>
int len; <br>
int n=0; <br>
struct ip *ip_p; <br>
struct timeval *time_now, *time_send; <br>
struct timeval now, timeout; <br>
int iphead_len; <br>
int icmp_len; <br>
struct icmphdr* icmp_p; <br>
float delay; <br>
timeout.tv_sec=TIMEOUT; <br>
timeout.tv_usec=0; <br>
FD_SET(icmp_fd[j], &fdR[j]); <br>
switch( select(icmp_fd[j]+1, &fdR[j], NULL, NULL, &timeout)){ <br>
case -1: <br>
perror("select"); <br>
close(icmp_fd[j]); <br>
return(1); <br>
case 0: <br>
printf("timeout\n"); <br>
close(icmp_fd[j]); <br>
pingf++; // Tell main file the ping is timeout; <br>
return(1); <br>
default: <br>
if( FD_ISSET(icmp_fd[j], &fdR[j])){ <br>
n=recvfrom(icmp_fd[j],recv_buf[j], sizeof(recv_buf[j]),0,NULL,NU <br>
LL); <br>
if(n<0){ <br>
if(errno==EINTR){ <br>
perror("receive"); <br>
}else{ <br>
printf("recvfrom error"); <br>
perror("receive"); <br>
} <br>
} <br>
ip_p=(struct ip*)recv_buf[j]; <br>
/* 获取IP包头的长度*/ <br>
iphead_len=ip_p->ip_hl<<2; <br>
/* 获取IP数据包中包含的ICMP报文 */ <br>
icmp_p=(struct icmphdr *)(recv_buf[j]+iphead_len); <br>
/* 计算ICMP报文的长度,它等于接收到的长度减去IP包头的长度 */ <br>
icmp_len=n-iphead_len; <br>
if(icmp_len<8) <br>
fprintf(stderr, "error icmp len=%d.\n", icmp_len); <br>
/* 如果ICMP的类型相同则输出显示 */ <br>
if(icmp_p->type==ICMP_ECHOREPLY){ <br>
if(( icmp_p->un).echo.id!=p_id[j]) <br>
return 0; <br>
if( icmp_len<16) <br>
printf("icmplen=%d.\n", icmp_len); <br>
gettimeofday(&now, NULL); <br>
time_now=&now; <br>
time_send=(struct timeval*)(icmp_p+1); <br>
if(time_now->tv_usec-=time_send->tv_usec<0){ <br>
time_now->tv_sec--; <br>
time_now->tv_usec+=1000000; <br>
} <br>
time_now->tv_sec-=time_send->tv_sec; <br>
/* 计算时延长度 */ <br>
delay=time_now->tv_sec*1000.0+time_now->tv_usec/1000.0; <br>
printf("%d bytes recv from %s: sequence=%d, ttl=%d, rtt=%fms.\n" <br>
<br>
,icmp_len, inet_ntoa(send_addr[j].sin_addr), (icmp_p->un).echo.sequence, ip_ <br>
p->ip_ttl, <br>
delay); <br>
close(icmp_fd[j]); <br>
return(1); <br>
} <br>
} <br>
} //End of switch <br>
close(icmp_fd[j]); <br>
} <br>
/* <br>
* ip_checksum:IP数据包头校验和的计算方法 <br>
*/ <br>
unsigned short ip_checksum(unsigned short *pcheck, int check_len) <br>
{ <br>
int nleft=check_len; <br>
int sum=0; <br>
unsigned short *p=pcheck; <br>
unsigned short result=0; <br>
while(nleft>1){ <br>
sum=sum+(*p++); <br>
nleft-=2; <br>
} <br>
if(nleft==1){ <br>
*(unsigned char *)(&result)=*(unsigned char *)p; <br>
sum+=result; <br>
} <br>
sum=(sum>>16)+(sum&0xFFFF); <br>
sum+=(sum>>16); <br>
result=~sum; <br>
return result; <br>
} <br>
int *ping(struct destnation *ipaddr) <br>
{ <br>
p_id[ipaddr->i]==getpid(); <br>
// setuid(getuid()); <br>
inet_aton(ipaddr->destip, &send_addr[ipaddr->i].sin_addr); <br>
icmp_fd[ipaddr->i]=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); <br>
if(icmp_fd[ipaddr->i]<0){ <br>
fprintf(stderr, "raw socket error.\n"); <br>
icmp_back=1; <br>
return(&icmp_back); <br>
} <br>
} <br>
send_icmp(ipaddr->i); <br>
icmp_back=recv_icmp(ipaddr->i); <br>
} <br>
int main() <br>
{ <br>
char line[128]; <br>
pthread_t p_tid[3]; <br>
int p_return[3; <br>
sequence[0]=random(); <br>
sequence[1]=random(); <br>
sequence[2]=random(); <br>
printf("\n After random <br>
sequence={%d,%d,%d}\n\n",sequence[0],sequence[1],sequence[2]); <br>
strncpy( ping_dst[0].destip, "192.168.1.10", 16); <br>
strncpy( ping_dst[1].destip, "192.168.1.11", 16); <br>
strncpy( ping_dst[2].destip, "192.168.1.12", 16); <br>
ping_dst[0].i=0; <br>
ping_dst[1].i=1; <br>
ping_dst[2].i=2; <br>
while(1){ <br>
bzero(recv_buf, 3*sizeof(recv_buf[0])); <br>
pthread_create(&p_tid[0],NULL,(void *)ping,(void *)&ping_dst[0]); <br>
pthread_create(&p_tid[1],NULL,(void *)ping,(void *)&ping_dst[1]); <br>
pthread_create(&p_tid[2],NULL,(void *)ping,(void *)&ping_dst[2]); <br>
pthread_join(p_tid[0], (void *)&p_return[0]); <br>
pthread_join(p_tid[1], (void *)&p_return[1]); <br>
pthread_join(p_tid[2], (void *)&p_return[2]); <br>
printf("\n=============== SLEEPING 10 sec =============\n\n"); <br>
sleep(10); <br>
} <br>
printf("Main id =%d\n", getpid()); <br>
} <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="321.htm">上一层</a>][<a href="460.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 + -