- 论坛徽章:
- 0
|
从网上down了一个程序,并修改后如下
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<net/if.h>
#include<sys/ioctl.h>
/*下面是IP和TCP包头结构*/
struct IP{
unsigned int ip_length:4;
/*定义IP头的长度*/
unsigned int ip_version:4;
/*IP版本,Ipv4 */
unsigned char ip_tos;
/*服务类型*/
unsigned short
ip_total_length; /*IP数据包的总长度*/
unsigned short ip_id;
/*鉴定城*/
unsigned short ip_flags;
/*IP 标志 */
unsigned char ip_ttl;
/*IP 包的存活期*/
unsigned char ip_protocol;
/*IP 上层的协议*/
unsigned short ip_cksum;
/*IP头校验和*/
unsigned int ip_source ;
/*源IP地址*/
unsigned int ip_dest;
/*目的IP地址*/
};
struct tcp{
unsigned short tcp_source_port;
/*定义TCP源端口*/
unsigned short tcp_dest_port;
/*TCP目的端口*/
unsigned short tcp_seqno;
/*TC P序列号*/
unsigned int tcp_ackno;
/*发送者期望的下一个序列号*/
unsigned int tcp_res1:4;
/*下面几个是TCP标志*/
unsigned int tcp_hlen:4;
unsigned int tcp_fin:1;
unsigned int tcp_syn:1;
unsigned int tcp_rst:1;
unsigned int tcp_psh:1;
unsigned int tcp_ack:1;
unsigned int tcp_urg:1;
unsigned int tcp_res2:2;
unsigned short tcp_winsize; /*能接收的最大字节数*/
unsigned short tcp_cksum;
/* TCP校验和*/
unsigned short tcp_urgent;
/* 紧急事件标志*/
};
static void promisc(char *device,int sock);
/*主函数*/
int main()
{
int sock,bytes_recieved,fromlen;
char buffer[65535];
struct sockaddr_in from;
/*定义socket结构*/
struct IP ip;
/*定义IP和TCP*/
struct tcp *tcp;
sock=socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
promisc(\"lan1\",sock);
/* 上面是建立socket连接,第一个参数是地址族类型,用INTERNET类型*/
/* 第二个参数是socket类型,这里用了SOCK_RAW,它可以绕过传输层*/
/* 直接访问IP层的包,为了调用SOCK_RAW,需要有root权限*/
/* 第三个参数是协议,选IPPROTO_TCP指定了接收TCP层的内容*/
while(1)
/*建立一个死循环,不停的接收网络信息*/
{
fromlen=sizeof from;
bytes_recieved=recvfrom(sock,buffer,sizeof buffer,0,(struct sockaddr *)&from,&fromlen);
/*上面这个函数是从建立的socket连接中接收数据*/
/*因为recvfrom()需要一个sockaddr数据类型,所以我们用了一个强制类型转换*/
#ifdef test
printf(\"\\nBytes received ::: %5d\\n\",bytes_recieved);
perror(\"err \");
#endif
/*显示出接收的数据字节数*/
if(!strcmp(inet_ntoa(from.sin_addr),\"127.0.0.1\") )
continue;
printf(\"source address ::: %s\\n\",inet_ntoa(from.sin_addr));
/*显示出源地址*/
#ifdef test
//ip=(struct IP)buffer;
memcpy(&ip,buffer,sizeof(struct IP));
/*把接收的数据转化为我们预先定义的结构,便于查看*/
printf(\"IP header length ::: %d\\n\",ip.ip_length);
/*显示IP头的长度*/
#endif
memcpy(&ip,buffer,sizeof(struct IP));
printf(\"Protocol ::: %d\\n\",ip.ip_protocol);
#ifdef test
/*显示协议类型,6是TCP,17是UDP*/
tcp=(struct tcp *)(buffer + (4*ip.ip_total_length));
/*上面这名需要详细解释一下,因为接收的包头数据中,IP头的大小是固定的4字节*/
/*所以我用IP长度乘以4,指向TCP头部分*/
printf(\"Source port ::: %d\\n\",ntohs(tcp->tcp_source_port)); /*显示出端口*/
printf(\"Dest prot ::: %d\\n\",ntohs(tcp->tcp_dest_port));/*显示出目标端口*/
#endif
}
}
static void promisc(char *device,int sock)
{
struct ifreq ifq;
strncpy(ifq.ifr_name,device,sizeof(device)+1);
if(ioctl(sock,SIOCGIFFLAGS,&ifq)==-1)
{
perror(\"err SIOCGIFFLAGS\");
exit(0);
}
printf(\"success ioctl,%d\\n\",ifq.ifr_flags);
ifq.ifr_flags|=IFF_PROMISC;
printf(\"success ioctl,%d\\n\",ifq.ifr_flags);
if(ioctl(sock,SIOCSIFFLAGS,&ifq)==-1)
{
perror(\"err SIOCSIFFLAGS\");
exit(0);
}
}
在hp主机上编译并执行程序时不能获得任何包,但是如果把IPPROTO_TCP修改成IPPROTO_ICMP
后,则可以获得从其他机器执行ping命令的包。请解释这里哪错了。 |
|