局域网下的被动嗅探,一些简单的拆包

// #include 
// #include 
#include 
#include 
#include 
#include  
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "ws2_32.lib")
#define IPLEN	32              // Ip len
#define MAXLINE 65535		    // Max pack

typedef struct ipheadr {	    /* ip header */
	unsigned char vers_l;		// version and len
	unsigned char s_type;	    // server type
	unsigned short t_len;	    // total-len
	unsigned short sign;	    // flags
	unsigned short mark;        // sign and slice offset
	unsigned char ttl;			// time to live
	unsigned char proto;		// protocol 
	unsigned short c_code;		// checksum
	unsigned int sourceip;      // source ip
	unsigned int destip;		// dest ip
} IpPack;

typedef struct tcpheadr {	    /* tcp header */
	unsigned short s_port;      // source port   
	unsigned short d_port;	    // dest port
	unsigned int seq_n;			// seq number
	unsigned int ack_n;			// ack numbert
	unsigned short m_s_offset;	// offset, save, mark    
	unsigned short windows;	    // window size
	unsigned short check_sum;   // checksum
	unsigned short urg_point;   // urg point
} TcpPack;

typedef struct udpheadr {		/* udp header */
	unsigned short s_port;		// source port
	unsigned short d_port;		// dest port
	unsigned short t_len;		// total len
	unsigned short check_sum;	// checksum
} UdpPack;

void decode_ip(char *pdata);
void decode_tcp(char *pdata, char *source, char *dest);
void decode_udp(char *pdata, char *source, char *dest);
void my_vprint(char *source, unsigned short s_port,
			   char *dest, unsigned short d_port);

int main()
{
	WSADATA wsaData;
	WORD Version = MAKEWORD(2, 2);
	if (WSAStartup(Version, &wsaData) != 0) {
		fprintf(stderr, "Can't open socket(v2.2)-Lib.\n");
		exit(0);
	}

	char hostname[32];
	struct hostent *pHost;
	struct sockaddr_in addr_in;
	/* get-hostname */
	gethostname(hostname, 32);
	if ((pHost = gethostbyname(hostname)) == NULL) {
		fprintf(stderr, "Can't get local hostname.\n");
		return -1;
	}

	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons(0);
	memcpy(&addr_in.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length);
	/* socket is set to the original stream */
	int fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
	if (fd < 0) {
		fprintf(stderr, "Can't create socket.\n");
		exit(0);
	}

	if (bind(fd, (struct sockaddr*)&addr_in, sizeof(struct sockaddr)) != 0) {
		fprintf(stderr, "Bind %s is error.\n", pHost->h_addr_list[0]);
		closesocket(fd);
		exit(0);
	}

	/* set network card is confounding */
	DWORD dwValue = 1;
	if (ioctlsocket(fd, SIO_RCVALL, &dwValue) != 0) { 
		fprintf(stderr, "Could not be set to promiscuous mode.\n");
		closesocket(fd);
		exit(0);
	}
	printf("\nActive Connections\n\n");
	printf("%7s%15s%25s\r\n", "Proto", "Local Address", "Foreign Address");
	char srcp[MAXLINE];
	int nRet;
	while (1) {
		if ((nRet = recv(fd, srcp, MAXLINE, 0)) > 0)
			decode_ip(srcp);
	}

	closesocket(fd);
	WSACleanup();
	return 0;
}

void decode_ip(char *pdata)
{
	IpPack *ip = (IpPack*)pdata;
	in_addr source_ip, dest_ip;
	char sourcename[32], destname[32];
	
	source_ip.S_un.S_addr = ip->sourceip;
	dest_ip.S_un.S_addr = ip->destip;
	strcpy_s(sourcename, IPLEN, inet_ntoa(source_ip));
	strcpy_s(destname, IPLEN, inet_ntoa(dest_ip));
	
	switch (ip->proto)
	{
	case IPPROTO_TCP:
		decode_tcp(pdata + 20, sourcename, destname);
		break;
	case IPPROTO_UDP:
		decode_udp(pdata + 20, sourcename, destname);
			break;
	}
}

void decode_tcp(char *pdata, char *source, char *dest)
{	
	TcpPack *tcp = (TcpPack *)pdata;
	printf("  TCP    ");
	my_vprint(source, ntohs(tcp->s_port), dest, ntohs(tcp->d_port));
	switch (tcp->d_port) {
    case 21:
    case 22:
    case 23:
	case 80:
		// save to i/o ... 
		break;
	}
}

void decode_udp(char *pdata, char *source, char *dest)
{
	UdpPack *udp = (UdpPack *)pdata;
	printf("  UDP    ");
	my_vprint(source, ntohs(udp->s_port), dest, ntohs(udp->d_port));
    switch(udp->d_port) {
    case 53: 
        // save to i/o
    }
}

void my_vprint(char *source, unsigned short s_port,
	char *dest, unsigned short d_port)
{
	char tmp[7];
	char buff1[22], buff2[22]; // 255.255.255.255:65535-  
	/* Formatter */
	itoa(s_port, tmp, 10); // number turn into string
	strcpy(buff1, "");
	strcat(buff1, source);
	strcat(buff1, ":");
	strcat(buff1, tmp);
	itoa(d_port, tmp, 10);
	strcpy(buff2, "");
	strcat(buff2, dest);
	strcat(buff2, ":");
	strcat(buff2, tmp);
	strcpy(tmp, "");
	printf("%-21s  %-21s\n", buff1, buff2);
}

其实代码很简单,只不过多用了一个ioctlsocket函数,此函数设置网卡模式,剩下就是简单的拆包工作。大家可以对这个简单的嗅探器进行扩展,这里面只分析了TCP和UDP的包,而且TCP更详细的拆包(应用层)并没有给出,例如http,ssh等。

代码运行环境:vs2017,代码运行效果如下:

局域网下的被动嗅探,一些简单的拆包_第1张图片

你可能感兴趣的:(局域网下的被动嗅探,一些简单的拆包)