URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 23 » 原始套接字问题编写ping命令的问题
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
原始套接字问题编写ping命令的问题
Author: silence_wu    Posted: 2005-10-20 22:27    Length: 5,454 byte(s)
[Original] [Print] [Top]
使用原始套接字编写了一个ping命令:
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>


#define IP_HEAD_LEN 20
#define ICMP_LEN 8

void handle_alarm(int signo);
void send_ip(void);
void recv_ip(void);
unsigned short ip_checksum(unsigned short * pcheck,int check_len);

int ip_fd;//原始套接字的描述符
int p_id;//进程号
int packet_len=IP_HEAD_LEN+ICMP_LEN;
struct sockaddr_in send_addr;
char send_buf[1024];
int sequence=0;//报文的序列号

void handle_alarm(int signo)
{
alarm(1);
send_ip();
}
void send_ip(void)
{
int len;
struct icmphdr *icmp_p;
icmp_p=(struct icmphdr *)send_buf;
icmp_p->type=ICMP_ECHO;
icmp_p->code=0;
(icmp_p->un).echo.id=p_id;
(icmp_p->un).echo.sequence=sequence;
gettimeofday((struct timeval *)(icmp_p+1),NULL);
len=sizeof(struct timeval)+ICMP_LEN;

icmp_p->checksum=0;
icmp_p->checksum=ip_checksum((u_short *)icmp_p,len);
len=sendto(ip_fd,send_buf,len,0,(struct sockaddr *)&send_addr,
sizeof(send_addr));
if(len<0)
fprintf(stderr,"sendto error. ");
sequence++;
printf("sendto %s",inet_ntoa(send_addr.sin_addr));
}


void recv_ip(void)
{
char recv_buf[1024];
int len;
int n;
struct ip *ip_p;
struct timeval *time_now,*time_send;
struct timeval now;
int iphead_len;
int icmp_len;
struct icmphdr *icmp_p;
float delay;

while(1){
printf(" -------------");
n=recvfrom(ip_fd,recv_buf,sizeof(recv_buf),0,NULL,NULL);
printf(" n=%d",n);
if(n<0)
{
if(errno==EINTR)
continue;
else{printf("recvfrom error");
continue;}
}
ip_p=(struct ip*)recv_buf;
iphead_len=ip_p->ip_hl<<2;
icmp_p=(struct icmphdr *)(recv_buf+iphead_len);
icmp_len=n-iphead_len;
if(icmp_len<8)
fprintf(stderr,"error icmp len=%d. ",icmp_len);
if(icmp_p->type==ICMP_ECHOREPLY){
if((icmp_p->un).echo.id!=p_id)
return;
if(icmp_len<16)
printf("icmplen=%d. ",icmp_len);
gettimeofday(&now,NULL);
time_now=&now;
time_send=(struct timeval *)(icmp_p+1);
if(time_now->tv_usec-=time_send->tv_usec<0){
time_now->tv_sec--;
time_now->tv_usec+=1000000;}
time_now->tv_sec-=time_send->tv_sec;
delay=time_now->tv_sec*1000.0+time_now->tv_usec/1000.0;
printf(" %dbytes recv from %s:sequence=%d,ttl=%d,rtt=%fms. ",
icmp_len,inet_ntoa(send_addr.sin_addr),(icmp_p->un).echo.
sequence,ip_p->ip_ttl,delay);}
}
}
unsigned short ip_checksum(unsigned short *pcheck,int check_len)
{
int nleft=check_len;
int sum=0;
unsigned short *p=pcheck;
unsigned short result=0;
while(nleft>1){sum=sum+(*p++);
nleft-=2;}
if(nleft==1){
*(unsigned char *)(&result)=*(unsigned char *)p;
sum+=result;}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
result=sum;
return result;
}

int main(int argc,char ** argv[])
{
struct sigaction act;
if(argc!=2){
fprintf(stderr,"usage:ping<IP_ADDR>. ");
exit(1);}
setuid(getuid());
act.sa_handler=handle_alarm;
act.sa_flags=0;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM,&act,NULL);
p_id=getpid();
inet_aton(argv[1],&send_addr.sin_addr);
ip_fd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(ip_fd<0){
fprintf(stderr,"raw socket error. ");
exit(1);}

raise(SIGALRM);
recv_ip();
}

在执行时,可以ping通自己的机器,但如果ping其它的机器则没有响应,请问这个是怎么回事?
另外,ping自己机器时的响应时间和linux自带的ping命令比较起来要长很多,请问这又是怎么回事?
我使用的是linux(rh9.0)平台。
[Original] [Print] [Top]
« Previous thread
大家有没有什么好的办法来防止伪造socket报文?
C/C++编程版
23
Next thread »
关于信号集的困惑
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:52:32, cost 0.038676023483276 ms.