📄 460.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="461.htm">下一篇</a>]
<hr><p align="left"><small> scz 于 2001-5-14 9:20:36 加贴在 绿盟科技论坛(bbs.nsfocus.com)--UNIX系统安全 <br>
: <br>
你用sniffer抓发出去几个包?校验和、协议解析正常吗。不帮你调试了, <br>
gettimeofday在干嘛? <br>
/* 填写ICMP报文的标示符 */ <br>
(icmp_p->un).echo.id=p_id[j]; <br>
/* 填写ICMP报文的序号 */ <br>
(icmp_p->un).echo.sequence=sequence[j]; <br>
RFC 792 (Internet Control Message Protocol) suggests how the ICMP Identifier <br>
<br>
field and the ICMP Sequence Number field should be used: <br>
"The identifier and sequence number may be used by the echo sender to aid in <br>
<br>
matching the replies with the echo requests. For example, the identifier <br>
might be used like a port in TCP or UDP to identify a session, and the <br>
sequence number might be incremented on each echo request sent. The echoer <br>
returns these same values in the echo reply". <br>
It literally suggests that the ICMP Identifier field will be used to <br>
differentiate between ICMP Query messages sent to different hosts. It also <br>
suggests that the ICMP Sequence Number field will be used to differentiate <br>
between the ICMP query messages sent to the same host. <br>
The 'ping' utility with UNIX and UNIX-like operating systems has adopted <br>
this suggestion. <br>
下面是cpu师兄的ping.c <br>
/* <br>
简单的ping.c <br>
华南木棉 cpu@socket <br>
*/ <br>
#include <stdio.h> <br>
#include <sys/types.h> <br>
#include <sys/socket.h> <br>
#include <sys/time.h> <br>
#include <signal.h> <br>
#include <unistd.h> <br>
#include <netdb.h> <br>
#include <netinet/in.h> <br>
#include <netinet/in_systm.h> <br>
#include <netinet/ip.h> <br>
#include <netinet/ip_icmp.h> <br>
#include <string.h> <br>
#include <arpa/inet.h> <br>
#include <errno.h> <br>
extern errno; <br>
struct sockaddr_in dst; <br>
struct hostent *hp; <br>
struct in_addr in; <br>
char host[32]; <br>
int s; <br>
u_short id; <br>
u_short sequence; <br>
u_char buf[128]; <br>
struct ip *ip; <br>
struct icmphdr *icmp; <br>
long lStartTime; <br>
long lEndTime; <br>
int sent; <br>
int received; <br>
double max, min, avg, total; <br>
struct timeval timeout = {2, 0}; <br>
struct timeval waitime = {1, 0}; <br>
long time_now () { <br>
struct timeval now; <br>
long lPassed; <br>
gettimeofday(&now, 0); <br>
lPassed = now.tv_sec * 1000000 + now.tv_usec; <br>
return lPassed; <br>
} <br>
} <br>
u_short ChkSum (u_short *addr, int len) { <br>
register int nleft = len; <br>
register int sum = 0; <br>
u_short answer = 0; <br>
while (nleft > 1) { <br>
sum += *addr++; <br>
nleft -= 2; <br>
} <br>
if (nleft == 1) { <br>
*(u_char *)(&answer) = *(u_char *)addr; <br>
sum += answer; <br>
} <br>
sum = (sum >> 16) + (sum + 0xffff); <br>
sum += (sum >> 16); <br>
answer = ~sum; <br>
return(answer); <br>
} <br>
int SendEcho () { <br>
int n, tolen; <br>
bzero(buf, sizeof buf); <br>
icmp->icmp_type = ICMP_ECHO; <br>
icmp->icmp_code = 0; <br>
icmp->icmp_cksum = 0; <br>
icmp->icmp_id = id; /* Unix Process ID */ <br>
icmp->icmp_seq= sequence++; <br>
icmp->icmp_cksum = ChkSum((u_short *)icmp, 16); <br>
bzero(&dst, sizeof(struct sockaddr_in)); <br>
dst.sin_family = AF_INET; <br>
dst.sin_addr.s_addr = in.s_addr; <br>
tolen = sizeof(struct sockaddr_in); <br>
if ((n = sendto(s, icmp, 64, 0, (struct sockaddr *)&dst, tolen)) < 0 <br>
) { <br>
perror("send to"); <br>
exit(0); <br>
} <br>
lStartTime = time_now(); <br>
sent ++; <br>
} <br>
void inthdlr () { <br>
if (!sent) goto OUT; <br>
printf("\n---- %s ping statistics by Digger ----\n", host); <br>
printf("%d packets transmitted, %d packets received, %.1f%% loss\n", <br>
<br>
sent, received, (sent-received)/(sent*1.0)*100); <br>
if (!received) goto OUT; <br>
printf("round-trip min/avg/max = %.1f/%.1f/%.1f ms\n", <br>
min, total/received, max); <br>
OUT: <br>
close(s); <br>
exit(0); <br>
} <br>
int main (int argc, char **argv) { <br>
double roundtrip; <br>
int n, fromlen; <br>
fd_set fdR; <br>
ip = (struct ip *)(buf); <br>
icmp = (struct icmphdr *)(buf + sizeof(struct ip)); <br>
id = getpid(); <br>
sequence = 0; <br>
if (argc != 2) { <br>
printf("usage: %s host|IP\n", argv[0]); <br>
exit(1); <br>
} <br>
if ((hp = gethostbyname(argv[1])) == NULL) { <br>
if ((dst.sin_addr.s_addr = inet_addr(argv[1])) == -1) { <br>
fprintf(stderr, "%s: unknown host\n", argv[1]); <br>
exit(1); <br>
} <br>
} else { <br>
bcopy(hp->h_addr_list[0], &dst.sin_addr, hp->h_length); <br>
} <br>
in.s_addr = dst.sin_addr.s_addr; <br>
if (inet_addr(argv[1]) == -1) { <br>
printf("Digger ping %s (%s): 56 data bytes\n", <br>
hp->h_name, inet_ntoa(dst.sin_addr)); <br>
} else { <br>
printf("Digger ping %s: 56 data bytes\n", argv[1]); <br>
} <br>
strcpy(host, argv[1]); <br>
if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP )) < 0) { <br>
perror("socket"); <br>
exit(0); <br>
} <br>
signal(SIGINT, inthdlr); <br>
for(;;) { <br>
SendEcho(); <br>
bzero(&dst, sizeof(struct sockaddr_in)); <br>
dst.sin_family = AF_INET; <br>
dst.sin_addr.s_addr = in.s_addr; <br>
fromlen = sizeof(struct sockaddr_in); <br>
FD_ZERO(&fdR); <br>
FD_SET(s, &fdR); <br>
AGAIN: <br>
switch(select(s+1, &fdR, NULL, NULL, &timeout)) { <br>
case -1: <br>
perror("select"); <br>
close(s); <br>
exit(0); <br>
case 0: <br>
printf("timeout\n"); <br>
continue; <br>
default: <br>
if(FD_ISSET(s, &fdR)) { <br>
if ((n = recvfrom(s, buf, sizeof(buf), 0, <br>
(struct sockaddr *)&dst, &fromlen)) < 0) { <br>
perror("recvfrom"); <br>
close(s); <br>
exit(0); <br>
} <br>
if (icmp->icmp_type == 0 && <br>
icmp->icmp_code == 0 && <br>
icmp->icmp_id == id && <br>
icmp->icmp_seq == sequence-1) { <br>
lEndTime = time_now(); <br>
roundtrip = <br>
(lEndTime-lStartTime)/1000.0 <br>
; <br>
max = (max > roundtrip) ? max : roun <br>
dtrip; <br>
/* max = MAX(max, roundtrip); */ <br>
if (min == 0) <br>
min = roundtrip; <br>
else <br>
min = (min < roundtrip) ? mi <br>
n : roundtrip; <br>
/* min = MIN(min, roundtrip) <br>
; */ <br>
received ++; <br>
total += roundtrip; <br>
printf("%d bytes from %s: ", <br>
n-20, inet_ntoa(dst.sin_addr) <br>
); <br>
printf("icmp_seq=%d ", icmp->icmp_se <br>
q); <br>
printf("ttl=%d ", ip->ip_ttl); <br>
printf("time=%.1f ms\n", roundtrip); <br>
<br>
} else <br>
goto AGAIN; <br>
} <br>
} <br>
if (roundtrip <= 1000000) { <br>
waitime.tv_sec = 0; <br>
waitime.tv_usec = 1000000 - roundtrip; <br>
} else { <br>
waitime.tv_sec = 1; <br>
waitime.tv_usec = 1000000 - roundtrip; <br>
} <br>
select(0, NULL, NULL, NULL, &waitime); <br>
} <br>
} <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="321.htm">上一层</a>][<a href="461.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 + -