#include <stdio.h>
#include <conio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#ifndef SIO_RCVALL
#define SIO_RCVALL         0x98000001
#endif

#define MAX_PACKET_SIZE    0x10000

static  BYTE Buffer[MAX_PACKET_SIZE]; // 64 Kb

typedef struct _IPHeader
{
	UCHAR     verlen;     // Version and length 
	UCHAR     tos;        // Type of service 
	USHORT    length;     // Total datagram length 
	USHORT    id;         // Identification 
	USHORT    offset;     // Flags, fragment offset 
	UCHAR     ttl;        // Time to live 
	UCHAR     protocol;   // Protocol 
	USHORT    xsum;       // Header checksum 
	ULONG     src;        // Source address 
	ULONG     dest;       // Destination address 
} IPHeader;

static void sniff( SOCKET s );

/////////////////////////////////////////////////////////////////////
void main()
{
	WSADATA     wsadata;   // WinSock initialization.
	SOCKET      s;         // Listening socket.
	char        name[128]; // Host hane (computer name).
	HOSTENT*    phe;       // Host information.
	SOCKADDR_IN sa;        // Host address.

	if( WSAStartup(MAKEWORD(2,2), &wsadata) )
	{
		printf("Windows sockets 2.2 not found.");
		return;
	}

	s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
	if( s!=INVALID_SOCKET )
	{
		gethostname(name, sizeof(name));
		phe = gethostbyname( name );
		if( phe )
		{
			ZeroMemory( &sa, sizeof(sa) );
			sa.sin_family = AF_INET;
			sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
			if( bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR))!=SOCKET_ERROR ) 
			{
				long flag = 1;
				if( ioctlsocket(s, SIO_RCVALL, &flag)==0 )
				{
					printf("Sniffing...\n");
					sniff( s );
				}else printf("ioctlsocket() failed.");
			}else printf("bind() failed.");
		}else printf("gethostbyname() failed.");
		closesocket( s );
	}else printf("socket() failed.");
 	WSACleanup();
	printf("end.");
}

/////////////////////////////////////////////////////////////////////
static void sniff( SOCKET s )
{
	int count;

	int i;


	while( !_kbhit() )
	{
		count = recv( s, Buffer, sizeof(Buffer), 0 );
		if( count==SOCKET_ERROR )
		{
			printf("recv() failed.");
			break;
		}
		
		printf("\n\nPacket: \nCount: %d\n", count);

		{
			IPHeader* hdr = (IPHeader *)Buffer;
			printf("Protocol: %d\n", hdr->protocol);
			printf("Length: %d\n", htons(hdr->length));
			printf("From: %.8X\n", hdr->src);
			printf("To: %.8X\n", hdr->dest);
		}

		for( i = 0; i < count; i++ )
		{
			printf(" %X", Buffer[i]);
		}

		/*
		if( count >= sizeof(IPHeader) )
		{
			IPHeader* hdr = (IPHeader *)Buffer;
			printf("VerLen: %x ", hdr->verlen);
			if( (hdr->verlen & 0xF0) == 0x40 )
			{
				// count...
				printf("%.8X -> %.8X   prot: %d   size: %d\n",
				       hdr->src, hdr->dest,
				       hdr->protocol, htons(hdr->length));
 
			}
			else printf("Bad IP packet.\n");
		}
		*/
	}
}