rawsocket和recvfrom php socket recvfrom

A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is able to send       any IP protocol that is specified in the passed header.  Receiving of all       IP protocols via IPPROTO_RAW is not possible using raw sockets.

在用raw socket写一个Ping程序;
最开始的时候多方参考,不巧参考的程序特性各异并且功能较为复杂,所以我一开始写的程序就复杂化了;创建raw sock的时候直接使用了IPPROTO_RAW;
知道通过设置IP_HDRINCL可以控制IP header,但是不知道上面那句话;
本来以为IPPROTO_RAW是一个通用协议呢..

不管怎么样,在开始只发送包的时候,程序当中自己设置了ip header,所以没啥问题;
但是当希望recvfrom的时候问题出来了:在发送ping的sockfd接口收不到任何包;具体问题是recvfrom不会返回;
郁闷了一会儿;
灵光一闪,把raw改成IPPROTO_ICMP,recvfrom返回是返回了,但是wireshark现实icmp的类型是69,不认识~~
认真分析包发现 69是0x45,同时包的长度增加了20;那就很容易理解了,多了一个IP包头;
也即IPPROTO_ICMP不需要自己设置IP头部么~~

因为代码中太多的IP头设置,因此仍然保留了RAW;为了接收包,新定义一个recvfd,类型是IPPROTO_ICMP;
需要注意的是
recvfd应该在发包之前定义,这样,发送的ping包的回复可以及时地送到这个端口;

哎呀,果然是写写程序才真的明白阿~~
贴一下代码,会比较有成就感 哈哈

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

char buff[28]={0};
int sockfd;
struct sockaddr_in target;

unsigned short in_cksum(unsigned short *addr, int len)
{
int sum=0;
unsigned short res=0;
while( len > 1) {
sum += *addr++;
len -=2;
// printf("sum is %x.n",sum);
}
if( len == 1) {
*((unsigned char *)(&res))=*((unsigned char *)addr);
sum += res;
}
sum = (sum >>16) + (sum & 0xffff);
sum += (sum >>16) ;
res = ~sum;
return res;
}



int main(int argc, char * argv[]){

int send, recv,i;
send = 0;
recv = 0;
i = 0;

if(inet_aton(argv[1],&target.sin_addr)==0){
printf("bad ip address %sn",argv[1]);
exit(1);
}

int recvfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
struct ip *ip = (struct ip *)buff;
struct icmp * icmp = (struct icmp*)(ip+1);

if((sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0)
{ perror("socket error!");exit(1); }

ip->ip_v = 4;
ip->ip_hl = 5;
ip->ip_tos = 0;
ip->ip_len = htons(28);
ip->ip_id = htons(8);
ip->ip_off = htons(0);
ip->ip_ttl = 65;
ip->ip_p = IPPROTO_ICMP;
ip->ip_sum = 0;
ip->ip_src.s_addr = target.sin_addr.s_addr;
ip->ip_dst.s_addr = target.sin_addr.s_addr;

icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_id = 2;
icmp->icmp_seq = 3;

while(send < 4)
{
send++;
// icmp->icmp_seq = icmp->icmp_seq+1;
icmp->icmp_cksum = 0;
icmp->icmp_cksum = in_cksum((unsigned short *)icmp,8);
sendto(sockfd, buff, 28,0,(struct sockaddr *)&target,sizeof(target));
sleep(1);
}

struct sockaddr_in from;
int lenfrom = sizeof(from);
rawsocket和recvfrom php socket recvfrom
char recvbuff[1024];
int n;
//printf("recvfd is %dn",recvfd);
while(recv<4){
if((n = recvfrom(recvfd,recvbuff,sizeof(recvbuff),0,(struct sockaddr *)&from,&lenfrom))<0) {perror("receive error!n");exit(1);};
struct ip *ip=(struct ip *)recvbuff;
struct icmp *icmp = (struct icmp*)(ip+1);
// printf("n is %d,ip header length is %dn ",n,ip->ip_hl);
if((n-ip->ip_hl*4)<8) {printf("Not ICMP Reply!n");break;}
if((icmp->icmp_type==ICMP_ECHOREPLY)&&(icmp->icmp_id==2)){
printf("%d reply coming back from %s: icmp sequence=%u ttl=%dn",recv+1,inet_ntoa(from.sin_addr),icmp->icmp_seq,ip->ip_ttl);

recv++;}


}

return 0;
}


  

爱华网本文地址 » http://www.413yy.cn/a/25101011/48546.html

更多阅读

php虚拟主机空间哪里购买好 虚拟主机和空间的区别

php虚拟主机空间哪里购买好——简介目前,很多个人博客、网站及中小企业网站站长都选择php虚拟主机来托管自己的网站。之所以选择php主机,除了它开源和免费的特性外,还能很好的支持php+mysql网站开发,极大的发挥其功能,为网站快速而稳定的

php开发环境Wamp Server WAMP5安装教程 wampserver环境配置

php开发环境Wamp Server WAMP5安装教程——简介wamp5工具简介:是:php,mysql,apache集成的开发环境,wamp5该版本集成了php5.2的所有版本,以及phpMyAdmin 2.系列版本,集成了管理mysql数据库的图形工具SQLiteManager和phpmyadmin两种管理工具

php文件怎么打开? 种子php文件怎么打开

简介很多没有做过网页的都不知道php文件是什么样的文件,今天小编过来跟大家说一下php文件是什么样的文件吧,其实PHP是一个网页脚本,但不同于html xml 标签语言,直接可以通过浏览器打开,需要有PHP的运行环境才可以访问和打开文件,如果只

如何和女生微信聊天(康纳课程视频) 微信和女生聊天秘籍

如何和女生微信聊天(康纳课程视频)与女生短信互动的时候:女生回应“呵呵”女生回应得很慢第一条短信该发什么能让女生愿意回复什么样的短信能刺激女生的好奇心在短信中如何邀约女生......像上面此类的短信互动问题会有各种各样,有没有

声明:《rawsocket和recvfrom php socket recvfrom》为网友你不懂爷的霸气分享!如侵犯到您的合法权益请联系我们删除