一个简单嗅探器的实现

这是最近的一段代码。

也没有什么好说的,简单的socket编程,设置网卡为混杂模式,接受所有封包,并打印所有封包的基本信息,及内容。

#include<stdio.h>
#include<winsock2.h>
#include<string.h>
#include<windows.h>
#include<mstcpip.h>
#pragma comment(lib,"ws2_32.lib")
#define RECVPORT 7000     //绑定的接包端口号

struct iphdr
{
	unsigned char head;
	unsigned char tos;
	unsigned short length;     //IP包头定义
	unsigned short flags;
	unsigned short offset;
	unsigned char ttl;
	unsigned char protc;
	unsigned short checksum;
	unsigned int sourceip;
	unsigned int destip; 
};

struct udphdr
{
	unsigned int sourceport;
	unsigned int destport;
	unsigned int length;				//UDP包头定义
	unsigned int checksum;
};

struct tcphdr
{
	USHORT sourceport;
	USHORT destport;
	unsigned int seq;
	unsigned int ack;					//TCP包头定义
	unsigned char offset;
	unsigned char flags;
	USHORT win;
	USHORT checksum;
	USHORT urg;
};

	FILE *f;
	char orig[100],*p,end;
	char type[20]={0},version[20]={0},plat[20]={0},ttl[20]={0},win[20]={0},df[20]={0},tos[20]={0};
	int i=0,j=0;
	int ttli,dfi,tosi,winb,wine;
	bool winf=false;
	

int solve(char *buff)          //解包函数定义
{	
	struct iphdr *ip;
	struct tcphdr *tcp;
	struct udphdr *udp;
	struct sockaddr_in test1,test2;
	BYTE *datat=NULL,*datau=NULL;
	BYTE test;

	ip=(struct iphdr*)buff;												//取IP头
	tcp=(struct tcphdr*)(buff+((ip->head)&0xf)*sizeof(unsigned int)); //取TCP头
    udp=(struct udphdr*)(buff+((ip->head)&0xf)*sizeof(unsigned int)); //取UDP头
	test1.sin_addr.s_addr=ip->sourceip;
    test2.sin_addr.s_addr=ip->destip;
	datat=((BYTE *)tcp)+(tcp->offset>>4)*4;
	datau=(BYTE *)udp;	
		printf("从:%s,",inet_ntoa(test1.sin_addr));
		printf("到:%s\n",inet_ntoa(test2.sin_addr));
		switch(ip->protc)
		{
			case 1:printf("Proto ICMP,");break; 
			case 2:printf("Proto IGMP,");break;
			case 6:printf("Proto TCP,");break;
			case 8:printf("Proto EGP,");break;
			case 9:printf("Proto IGP,");break;
			case 17:printf("Proto UDP,");break;
			case 41:printf("Proto IPv6,");break;
			case 89:printf("Proto OSPF,");break;
			default:printf("Proto error,");break;
		}
		if(ip->protc==6)
		{
			int port=0;
			port=ntohs(tcp->sourceport);
			printf("从TCP端口:%d,到TCP端口:%d,SEQ:%d,ACK:%d\n",ntohs(tcp->sourceport),ntohs(tcp->destport),ntohl(tcp->seq),ntohl(tcp->ack));
			switch(port)
			{
			    case 21:printf("这是一个ftp协议数据包\n");break;
				case 80:printf("这是一个HTTP协议数据包\n");break;
				case 110:printf("这是一个pop3协议数据包\n");break;
				case 25:printf("这是一个SMTP协议数据包\n ");break;
			}
			printf("FLAGS:");
			if(tcp->flags&0x20)
				printf("URG ");
			if(tcp->flags&0x10)
				printf("ACK ");
			if(tcp->flags&0x8)                   //对TCP命令,输出标志位
				printf("PSH ");
			if(tcp->flags&0x4)
				printf("RST ");
			if(tcp->flags&0x2)
				printf("SYN ");
			if(tcp->flags&0x1)
				printf("FIN ");
			printf("data:%s\n",datat);
		
		}
		else if(ip->protc==17)
		{
			printf("从UDP端口:%d,到UDP端口:%d,\nDATA:%s",ntohs(udp->sourceport),ntohs(udp->destport),datau);
		}
		printf("TTL:%d\n",ip->ttl);
		printf("\n");
			
		return 0;
}

int main()
{
	WSADATA ws;
	long lresult;
	SOCKET sock;
	struct sockaddr_in myaddress;					//定义主函数变量
	struct hostent *host;
	char name[100],buffer[65535],k;
    int err1,err2,err3,i;
        
	printf("输入ENTER键开始\n");
	k=getchar();
	lresult=WSAStartup(MAKEWORD(2,2),&ws);
	if(lresult<0)
		printf("error!");
	myaddress.sin_family=AF_INET;
	myaddress.sin_port=htons(RECVPORT);             //初始化
	gethostname(name,sizeof(name));
	host=gethostbyname(name);
	memcpy(&myaddress.sin_addr,host->h_addr_list[0],host->h_length);
    
	sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
	err2=bind(sock,(PSOCKADDR)&myaddress,sizeof(myaddress));   //绑定端口
	if(err2<0)
	{
		printf("BIND ERROR!");
		exit(1);	
	}
	DWORD inbuffer=1;
	DWORD outbuffer[10];
	DWORD returned=0;
	err1=WSAIoctl(sock,SIO_RCVALL,&inbuffer,sizeof(inbuffer),&outbuffer,sizeof(outbuffer),&returned,NULL,NULL);
	if(err1<0)
	{
		printf("IO OPTION SET ERROR!");						//设置端口为接收所有包模式
		exit(1);	
	}	
	for(i=1;i<=30;i++)
	{
		memset(buffer,0,sizeof(buffer));//清空接收缓冲区
		err3=recv(sock,buffer,sizeof(buffer),0);    //接包
		if(err3<0)
		{
			printf("RECEIVE ERROR!");
			exit(1);	
		}
		solve(buffer);          //定义解包函数解包
	}	
	return 0;
}


菜鸟言论,仅供娱乐。

关于嗅探器的源代码#include #include #include #include #include #pragma comment(lib,"ws2_32.lib") #define MAX_HOSTNAME_LAN 255 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) #define MAX_ADDR_LEN 16 struct ipheader { unsigned char ip_hl:4; unsigned char ip_v:4; unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; typedef struct tcpheader { unsigned short int sport; unsigned short int dport; unsigned int th_seq; unsigned int th_ack; unsigned char th_x:4; unsigned char th_off:4; unsigned char Flags; unsigned short int th_win; unsigned short int th_sum; unsigned short int th_urp; }TCP_HDR; typedef struct udphdr { unsigned short sport; unsigned short dport; unsigned short len; unsigned short cksum; }UDP_HDR; void main(){ SOCKET sock; WSADATA wsd; DWORD dwBytesRet; unsigned int optval = 1; unsigned char *dataudp,*datatcp; int i,pCount=0,lentcp, lenudp; SOCKADDR_IN sa,saSource, saDest; struct hostent FAR * pHostent; char FAR name[MAX_HOSTNAME_LAN]; char szSourceIP[MAX_ADDR_LEN], szDestIP[MAX_ADDR_LEN],RecvBuf[65535] = {0}; struct udphdr *pUdpheader; struct ipheader *pIpheader; struct tcpheader *pTcpheader; WSAStartup(MAKEWORD(2,1),&wsd); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP))==SOCKET_ERROR) exit(1); gethostname(name, MAX_HOSTNAME_LAN); pHostent = gethostbyname(name); sa.sin_family = AF_INET; sa.sin_port = htons(6000); memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length); bind(sock, (SOCKADDR *)&sa, sizeof(sa)); if ((WSAGetLastError())==10013) exit(1); WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL); pIpheader = (struct ipheader *)RecvBuf; pTcpheader = (struct tcpheader *)(RecvBuf+ sizeof(struct ipheader )); pUdpheader = (struct udphdr *) (RecvBuf+ sizeof(struct ipheader )); while (1){ memset(RecvBuf, 0, sizeof(RecvBuf)); recv(sock, RecvBuf, sizeof(RecvBuf), 0); saSource.sin_addr.s_addr = pIpheader->ip_src; strncpy(szSourceIP, inet_ntoa(saSource.sin_addr), MAX_ADDR_LEN); saDest.sin_addr.s_addr = pIpheader->ip_dst; strncpy(szDestIP, inet_ntoa(saDest.sin_addr), MAX_ADDR_LEN); lentcp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader))); lenudp =(ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr))); if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){ printf("*******************************************\n"); pCount++; datatcp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader); printf("-TCP-\n"); printf("\n%s\n",szDestIP); printf("\n%i\n",ntohs(pTcpheader->dport)); printf("datatcp address->%x\n",datatcp); printf("size of ipheader->%i\n",sizeof(struct ipheader)); printf("size of tcpheader->%i\n",sizeof(struct tcpheader)); printf("size of the hole packet->%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lentcp-1); for (i=0;i<lentcp;i++){ printf("\\x%.2x",*(datatcp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lentcp;i++){ if( *(datatcp+i)=20) printf("%c",*(datatcp+i)); else printf("."); } printf("\n\n*******************************************\n"); } if((pIpheader->ip_p)==IPPROTO_UDP&&lentcp!=0){ pCount++; dataudp=(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); printf("-UDP-\n"); printf("\n%s\n",szDestIP); printf("\n%d\n",ntohs(pTcpheader->dport)); printf("UDP%x\n",dataudp); printf("IP%i\n",sizeof(struct ipheader)); printf("UDP%i\n",sizeof(struct udphdr)); printf("%i\n",ntohs(pIpheader->ip_len)); printf("\nchar Packet%i [%i]=\"",pCount,lenudp-1); for (i=0;i<lenudp;i++){ printf("\\x%.2x",*(dataudp+i)); if (i==0) printf("\"\n\""); } printf("\";\n\n\n"); for (i=0;i<lenudp;i++){ if( *(dataudp+i)=20) printf("%c",*(dataudp+i)); else printf("."); } printf("\n\n*******************************************\n"); } } }
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值