資源簡介
課程設計內容
本實驗為ICMP實驗。實驗內容:Ping命令實現的擴充,在給定的Ping程序的基礎上做如下功能擴充:
? -h 顯示幫助信息
? -b 允許ping一個廣播地址,只用于IPv4
? -t 設置ttl值,只用于IPv4
? -q 安靜模式。不顯示每個收到的包的分析結果,只在結束時,顯示匯總結果
程序分為兩大部分:一部分讀取收到的所有消息,并輸出ICMP Echo replay消息,另一部分每個一秒鐘發送一個Echo消息。另一部分由SIGALARM信號每秒驅動一次。

代碼片段和文件信息
#include?“ping.h“????????????
struct?proto proto_v4?=?{?proc_v4?send_v4?NULL?NULL?0?IPPROTO_ICMP?};
#ifdef IPV6
struct?proto proto_v6?=?{?proc_v6?send_v6?NULL?NULL?0?IPPROTO_ICMPV6?};
#endif
int?datalen?=?56; /*?data?that?goes?with?ICMP?echo?request?*/
int?pingnum=4;
int?anjing=0;
int?getpostcount=0;
double?rttcount=0;
int?broadcasting=0;
int?setttl=0;
int?ttlnum=64;
void?printhelp(){
printf(“-h 顯示幫助信息?\n“);
printf(“-t?? 設置ttl值,只用于IPv4\n“);
printf(“-q 安靜模式。不顯示每個收到的包的分析結果,只在結束時,顯示匯總結果?\n“);
}
int?main(int?argc?char?**argv)
{
int c;
struct?addrinfo *ai;
opterr?=?0; /*?don‘t?want?getopt()?writing?to?stderr?*/
while?(?(c?=?getopt(argc?argv?“vhqbn:t:s:“))?!=?-1)?{
switch?(c)?{
case?‘v‘:
verbose++;
break;
case‘h‘:
printf(“\n“);
printhelp();
exit(0);
break;
case‘q‘:
anjing=1;
break;
case‘b‘:
broadcasting=1;
break;
case‘n‘:
pingnum=atoi(argv[optind-1]);
break;
case‘s‘:
datalen=atoi(argv[optind-1]);
if(datalen>1024||datalen<0)
printf(“數據包長度應大于0小于1024\n“);
break;
case‘t‘:
setttl=1;
ttlnum?=?atoi(argv[optind-1]);?
break;
case?‘?‘:
err_quit(“未知的命令?請輸入-h來查看幫助\n“);
}
}
if?(optind?!=?argc-1)
err_quit(“usage:?ping?[?-v?]?“);
host?=?argv[optind];
pid?=?getpid();
signal(SIGALRM?sig_alrm);
ai?=?host_serv(host?NULL?0?0);
printf(“ping?%s?(%s):?%d?data?bytes\n“?ai->ai_canonname
???Sock_ntop_host(ai->ai_addr?ai->ai_addrlen)?datalen);
/*?4initialize?according?to?protocol?*/
if?(ai->ai_family?==?AF_INET)?{
pr?=?&proto_v4;
#ifdef IPV6
}?else?if?(ai->ai_family?==?AF_INET6)?{
pr?=?&proto_v6;
if?(IN6_IS_ADDR_V4MAPPED(&(((struct?sockaddr_in6?*)
?ai->ai_addr)->sin6_addr)))
err_quit(“cannot?ping?IPv4-mapped?IPv6?address“);
#endif
}?else
err_quit(“unknown?address?family?%d“?ai->ai_family);
pr->sasend?=?ai->ai_addr;
pr->sarecv?=?calloc(1?ai->ai_addrlen);
pr->salen?=?ai->ai_addrlen;
readloop();
exit(0);
}
void
proc_v4(char?*ptr?ssize_t?len?struct?timeval?*tvrecv)/*輸出結果*/
{
int hlen1?icmplen;
double rtt;
struct?ip *ip;
struct?icmp *icmp;
struct?timeval *tvsend;
ip?=?(struct?ip?*)?ptr; /*?start?of?IP?header?*/
hlen1?=?ip->ip_hl?<2; /*?length?of?IP?header?*/
icmp?=?(struct?icmp?*)?(ptr?+?hlen1); /*?start?of?ICMP?header?*/
if?(?(icmplen?=?len?-?hlen1)?8)
err_quit(“icmplen?(%d)?8“?icmplen);
if?(icmp->icmp_type?==?ICMP_ECHOREPLY)?{
if?(icmp->icmp_id?!=?pid)
return; /*?not?a?response?to?our?ECHO_REQUEST?*/
if?(icmplen?16)
err_quit(“icmplen?(%d)?16“?icmplen);
tvsend?=?(struct?timeval?*)?icmp->icmp_data;
tv_sub(tvrecv?tvsend);
rtt?=?tvrecv->tv_sec?*?1000.0?+?tvrecv->tv_usec?/?1000.0;
if(anjing!=1){
printf(“%d?bytes?from?%s:?seq=%u?ttl=%d?rtt=%.3f?ms\n“
icmplen?Sock_ntop_host(pr->sarecv?pr->salen)
icmp->icmp_seq?ip->ip_ttl?rtt);
rttcount+=rtt;
getpostcount++;
}else{
rttcount+=rtt;
getpostcount++;
}
}?else?if?(ver
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????目錄???????????0??2011-09-25?16:25??my\
?????文件???????11840??2011-06-26?21:18??my\ping.c
?????文件????????2150??2009-11-04?16:43??my\ping.h
評論
共有 條評論