C programming: sniffer with winpcap

#ifdef _MSC_VER
/*
 * we do not want the warnings about the old deprecated and unsecure CRT functions
 * since these examples can be compiled under *nix as well
 */
#define _CRT_SECURE_NO_WARNINGS
#endif

#include 
#include 
#include 
#ifdef _WIN32
#include 

 /*
  * 14 bytes ethernet header
  * 0000-05DC	IEEE802.3 Length Field (0.:1500.)
  * 0101-01FF	Experimental
  * 0200	Xerox PUP (conflicts with 802.3 Length Field range) (see 0A00)
  * 0201	Xerox PUP Address Translation (conflicts ...) (see 0A01)
  * 0400	Nixdorf (conflicts with 802.3 Length Field)
  * 0600	Xerox NS IDP
  * 0601	XNS Address Translation (3Mb only)
  * 0800	DOD Internet Protocol (IP)
  * 0801	X.75 Internet
  * 0802	NBS Internet
  * 0803	ECMA Internet
  * 0804	CHAOSnet
  * 0805	X.25 Level 3
  * 0806	Address Resolution Protocol (ARP) (for IP and for CHAOS)
  * 0807	XNS Compatibility
  * 081C	Symbolics Private
  * 0888-088A	Xyplex
  * 0900	Ungermann-Bass network debugger
  * 0A00	Xerox IEEE802.3 PUP
  * 0A01	Xerox IEEE802.3 PUP Address Translation
  * 0BAD	Banyan Systems
  * 0BAF	Banyon VINES Echo
  * 1000	Berkeley Trailer negotiation
  * 1001-100F	Berkeley Trailer encapsulation for IP
  * 1234	DCA - Multicast
  * 1600	VALID system protocol
  * 1989	Artificial Horizons ("Aviator" dogfight simulator [on Sun])
  * 1995	Datapoint Corporation (RCL lan protocol)
  * 3C00	3Com NBP virtual circuit datagram (like XNS SPP) not registered
  * 3C01	3Com NBP System control datagram not registered
  * 3C02	3Com NBP Connect request (virtual cct) not registered
  * 3C03	3Com NBP Connect repsonse not registered
  * 3C04	3Com NBP Connect complete not registered
  * 3C05	3Com NBP Close request (virtual cct) not registered
  * 3C06	3Com NBP Close response not registered
  * 3C07	3Com NBP Datagram (like XNS IDP) not registered
  * 3C08	3Com NBP Datagram broadcast not registered
  * 3C09	3Com NBP Claim NetBIOS name not registered
  * 3C0A	3Com NBP Delete Netbios name not registered
  * 3C0B	3Com NBP Remote adaptor status request not registered
  * 3C0C	3Com NBP Remote adaptor response not registered
  * 3C0D	3Com NBP Reset not registered
  * 4242	PCS Basic Block Protocol
  * 424C       Information Modes Little Big LAN diagnostic
  * 4321	THD - Diddle
  * 4C42       Information Modes Little Big LAN
  * 5208	BBN Simnet Private
  * 6000	DEC unassigned, experimental
  * 6001	DEC Maintenance Operation Protocol (MOP) Dump/Load Assistance
  * 6002	DEC Maintenance Operation Protocol (MOP) Remote Console
  * 6003	DECNET Phase IV, DNA Routing
  * 6004	DEC Local Area Transport (LAT)
  * 6005	DEC diagnostic protocol (at interface initialization?)
  * 6006	DEC customer protocol
  * 6007	DEC Local Area VAX Cluster (LAVC), System Communication Architecture (SCA)
  * 6008	DEC AMBER
  * 6009	DEC MUMPS
  * 6010-6014	3Com Corporation
  * 7000	Ungermann-Bass download
  * 7001	Ungermann-Bass NIUs
  * 7002	Ungermann-Bass diagnostic/loopback
  * 7003	Ungermann-Bass ??? (NMC to/from UB Bridge)
  * 7005	Ungermann-Bass Bridge Spanning Tree
  * 7007	OS/9 Microware
  * 7009	OS/9 Net?
  * 7020-7029	LRT (England) (now Sintrom)
  * 7030	Racal-Interlan
  * 7031	Prime NTS (Network Terminal Service)
  * 7034	Cabletron
  * 8003	Cronus VLN
  * 8004	Cronus Direct
  * 8005	HP Probe protocol
  * 8006	Nestar
  * 8008	AT&T/Stanford Univ.	Local use
  * 8010	Excelan
  * 8013	Silicon Graphics diagnostic
  * 8014	Silicon Graphics network games
  * 8015	Silicon Graphics reserved
  * 8016	Silicon Graphics XNS NameServer, bounce server
  * 8019	Apollo DOMAIN
  * 802E	Tymshare
  * 802F	Tigan, Inc.
  * 8035	Reverse Address Resolution Protocol (RARP)
  * 8036	Aeonic Systems
  * 8037	IPX (Novell Netware?)
  * 8038	DEC LanBridge Management
  * 8039	DEC DSM/DDP
  * 803A	DEC Argonaut Console
  * 803B	DEC VAXELN
  * 803C	DEC DNS Naming Service
  * 803D	DEC Ethernet CSMA/CD Encryption Protocol
  * 803E	DEC Distributed Time Service
  * 803F	DEC LAN Traffic Monitor Protocol
  * 8040	DEC PATHWORKS DECnet NETBIOS Emulation
  * 8041	DEC Local Area System Transport
  * 8042	DEC unassigned
  * 8044	Planning Research Corp.
  * 8046	AT&T
  * 8047	AT&T
  * 8048	DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not)
  * 8049	ExperData
  * 805B	VMTP (Versatile Message Transaction Protocol, RFC-1045) (Stanford) [was Stanford V Kernel, experimental]
  * 805C	Stanford V Kernel, version 6.0
  * 805D	Evans & Sutherland
  * 8060	Little Machines
  * 8062	Counterpoint Computers
  * 8065	University of Mass. at Amherst
  * 8066	University of Mass. at Amherst
  * 8067	Veeco Integrated Automation
  * 8068	General Dynamics
  * 8069	AT&T
  * 806A	Autophon
  * 806C	ComDesign
  * 806D	Compugraphic Corporation
  * 806E-8077	Landmark Graphics Corporation
  * 807A	Matra
  * 807B	Dansk Data Elektronik
  * 807C	Merit Internodal (or Univ of Michigan?)
  * 807D-807F	Vitalink Communications
  * 8080	Vitalink TransLAN III Management
  * 8081-8083	Counterpoint Computers
  * 8088-808A	Xyplex
  * 809B	EtherTalk (AppleTalk over Ethernet)
  * 809C-809E	Datability
  * 809F	Spider Systems Ltd.
  * 80A3	Nixdorf Computers
  * 80A4-80B3	Siemens Gammasonics Inc.
  * 80C0-80C3	DCA (Digital Comm. Assoc.) Data Exchange Cluster
  * 80C6	Pacer Software
  * 80C7	Applitek Corporation
  * 80C8-80CC	Intergraph Corporation
  * 80CD-80CE	Harris Corporation
  * 80CF-80D2	Taylor Instrument
  * 80D3-80D4	Rosemount Corporation
  * 80D5	IBM SNA Services over Ethernet
  * 80DD	Varian Associates
  * 80DE-80DF	TRFS (Integrated Solutions Transparent Remote File System)
  * 80E0-80E3	Allen-Bradley
  * 80E4-80F0	Datability
  * 80F2	Retix
  * 80F3	AppleTalk Address Resolution Protocol (AARP)
  * 80F4-80F5	Kinetics
  * 80F7	Apollo Computer
  * 80FF-8101	Wellfleet Communications
  * 8102	Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.]
  * 8103	Wellfleet Communications
  * 8107-8109	Symbolics Private
  * 812B	Talaris
  * 8130	Waterloo Microsystems Inc.
  * 8131	VG Laboratory Systems
  * 8137	Novell (old) NetWare IPX (ECONFIG E option)
  * 8138	Novell, Inc.
  * 8139-813D	KTI
  * 813F	M/MUMPS data sharing
  * 8145	Vrije Universiteit (NL)		Amoeba 4 RPC (obsolete)
  * 8146	Vrije Universiteit (NL)		FLIP (Fast Local Internet Protocol)
  * 8147	Vrije Universiteit (NL)		[reserved]
  * 814C	SNMP over Ethernet (see RFC1089)
  * 814F	Technically Elite Concepts	Network Professor
  * 8191	PowerLAN			NetBIOS/NetBEUI (PC)
  * 817D	XTP
  * 81D6	Artisoft Lantastic
  * 81D7	Artisoft Lantastic
  * 8203-8205	QNX Software Systems Ltd.
  * 8390	Accton Technologies (unregistered)
  * 852B	Talaris multicast
  * 8582	Kalpana
  * 86DD       IP version 6
  * 8739	Control Technology Inc.		RDP Without IP
  * 873A	Control Technology Inc.		Mcast Industrial Ctrl Proto.
  * 873B	Control Technology Inc.		Proprietary
  * 873C	Control Technology Inc.		Proprietary
  * 8820	Hitachi Cable (Optoelectronic Systems Laboratory)
  * 8856       Axis Communications AB		proprietary bootstrap/config
  * 8888	HP LanProbe test?
  * 9000	Loopback (Configuration Test Protocol)
  * 9001	3Com (Formerly Bridge Communications), XNS Systems Management
  * 9002	3Com (Formerly Bridge Communications), TCP/IP Systems Management
  * 9003	3Com (Formerly Bridge Communications), loopback detection
  * AAAA	DECNET?		Used by VAX 6220 DEBNI
  * FAF5	Sonix Arpeggio
  * FF00	BBN VITAL-LanBridge cache wakeups
  */
typedef struct ether_header
{
	u_char dmac[6];	//destination mac
	u_char smac[6]; //source mac
	u_short type;	//type IP=0x0800,ARP=0x0806
}ether_header;

/* 4 bytes IP address */
typedef struct ip_address
{
	u_char byte1;
	u_char byte2;
	u_char byte3;
	u_char byte4;
}ip_address;

/* rfc791 -> IPv4 header */
typedef struct ip_header
{
	u_char  ver_ihl;        // Version (4 bits) + Internet header length (4 bits)
	u_char  tos;            // Type of service 
	u_short tlen;           // Total length 
	u_short identification; // Identification
	u_short flags_fo;       // Flags (3 bits) + Fragment offset (13 bits)
	u_char  ttl;            // Time to live
	u_char  proto;          // Protocol
	u_short crc;            // Header checksum
	ip_address  saddr;      // Source address
	ip_address  daddr;      // Destination address
	//u_int   op_pad;         // Option + Padding
}ip_header;

BOOL LoadNpcapDlls()
{
	_TCHAR npcap_dir[512];
	UINT len;
	len = GetSystemDirectory(npcap_dir, 480);
	if (!len) {
		fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
		return FALSE;
	}
	_tcscat_s(npcap_dir, 512, _T("\\Npcap"));
	if (SetDllDirectory(npcap_dir) == 0) {
		fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
		return FALSE;
	}
	return TRUE;
}
#endif

/* prototype of the packet handler */
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data);

int main()
{
	pcap_if_t* alldevs;
	pcap_if_t* d;
	int inum;
	int i = 0;
	pcap_t* adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];

#ifdef _WIN32
	/* Load Npcap and its functions. */
	if (!LoadNpcapDlls())
	{
		fprintf(stderr, "Couldn't load Npcap\n");
		exit(1);
	}
#endif

	/* Retrieve the device list */
	if (pcap_findalldevs(&alldevs, errbuf) == -1)
	{
		fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}

	/* Print the list */
	for (d = alldevs; d; d = d->next)
	{
		printf("%d. %s", ++i, d->name);
		if (d->description)
			printf(" (%s)\n", d->description);
		else
			printf(" (No description available)\n");
	}

	if (i == 0)
	{
		printf("\nNo interfaces found! Make sure Npcap is installed.\n");
		return -1;
	}

	printf("Enter the interface number (1-%d):", i);
	scanf("%d", &inum);

	if (inum < 1 || inum > i)
	{
		printf("\nInterface number out of range.\n");
		/* Free the device list */
		pcap_freealldevs(alldevs);
		return -1;
	}

	/* Jump to the selected adapter */
	for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);

	/* Open the device */
	/* Open the adapter */
	if ((adhandle = pcap_open_live(d->name,	// name of the device
		65536,			// portion of the packet to capture. 
		// 65536 grants that the whole packet will be captured on all the MACs.
		1,				// promiscuous mode (nonzero means promiscuous)
		1000,			// read timeout
		errbuf			// error buffer
	)) == NULL)
	{
		fprintf(stderr, "\nUnable to open the adapter. %s is not supported by Npcap\n", d->name);
		/* Free the device list */
		pcap_freealldevs(alldevs);
		return -1;
	}

	printf("\nlistening on %s...\n", d->description);

	/* At this point, we don't need any more the device list. Free it */
	pcap_freealldevs(alldevs);

	/* start the capture */
	pcap_loop(adhandle, 0, packet_handler, NULL);

	pcap_close(adhandle);
	return 0;
}


/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char* param, const struct pcap_pkthdr* pcap_header, const u_char* pkt_data)
{
	struct tm* ltime;
	char timestr[16];
	time_t local_tv_sec;
	ether_header* eh;
	ip_header* ih;
	ip_address saddr;
	ip_address daddr;
	u_short sport = 0, dport = 0;
	u_char header_length;
	u_char ip_offset;

	/* convert the timestamp to readable format */
	local_tv_sec = pcap_header->ts.tv_sec;
	ltime = localtime(&local_tv_sec);
	strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

	//get ethernet header of ethernet datagram from byte 0 to byte 13
	eh = (ether_header*)(pkt_data);
	//type high bit
	u_char htype = eh->type & 0xF;
	//type low bit
	u_char ltype = (eh->type >> 8) & 0xF;
	//Big endian type
	u_short ether_type = 0;
	ether_type = ether_type | htype;
	ether_type = ((ether_type << 8) & 0xFF00) | ltype;

	//get ethernet datagram
	printf("ETHER HEADER: %s,%.6d [ len:%4d ] [ ether_type:0x%04X ] [ SMAC: %02X:%02X:%02X:%02X:%02X:%02X -> DMAC: %02X:%02X:%02X:%02X:%02X:%02X ] ",
		timestr,
		pcap_header->ts.tv_usec,
		pcap_header->len,
		ether_type,
		eh->smac[0],
		eh->smac[1],
		eh->smac[2],
		eh->smac[3],
		eh->smac[4],
		eh->smac[5],
		eh->dmac[0],
		eh->dmac[1],
		eh->dmac[2],
		eh->dmac[3],
		eh->dmac[4],
		eh->dmac[5]);

	//here is ip datagram
	if (ether_type == 0x800)
	{
		//get ip header
		ih = (ip_header*)(pkt_data + 14);
		// rfc790 [ASSIGNED INTERNET PROTOCOL NUMBERS]
		//  Decimal    Octal      Protocol Numbers                 
		//  -------    -----      ----------------                 
		//       0       0         Reserved                        
		//       1       1         ICMP                            
		//       2       2         Unassigned                      
		//       3       3         Gateway-to-Gateway              
		//       4       4         CMCC Gateway Monitoring Message 
		//       5       5         ST                              
		//       6       6         TCP                             
		//       7       7         UCL                             
		//       8      10         Unassigned                      
		//       9      11         Secure                          
		//      10      12         BBN RCC Monitoring              
		//      11      13         NVP                             
		//      12      14         PUP                             
		//      13      15         Pluribus                        
		//      14      16         Telenet                         
		//      15      17         XNET                            
		//      16      20         Chaos                           
		//      17      21         User Datagram                   
		//      18      22         Multiplexing                    
		//      19      23         DCN                             
		//      20      24         TAC Monitoring                  
		//   21-62   25-76         Unassigned                      
		//      63      77         any local network               
		//      64     100         SATNET and Backroom EXPAK       
		//      65     101         MIT Subnet Support              
		//   66-68 102-104         Unassigned                      
		//      69     105         SATNET Monitoring               
		//      70     106         Unassigned                      
		//      71     107         Internet Packet Core Utility    
		//   72-75 110-113         Unassigned                      
		//      76     114         Backroom SATNET Monitoring      
		//      77     115         Unassigned                      
		//      78     116         WIDEBAND Monitoring             
		//      79     117         WIDEBAND EXPAK                  
		//  80-254 120-376         Unassigned                      
		//     255     377         Reserved       
		if (6 == ih->proto)
		{
			//get source ip of ip datagram from byte 13 to byte 16
			saddr = ih->saddr;
			//get source ip of ip datagram from byte 17 to byte 20
			daddr = ih->daddr;


			//get IP datagram
			header_length = ((ih->ver_ihl) & 0x0f) * 4;//header 长度单位是4字节,最大60

			ip_offset = 0 + 14 + header_length;
			u_char total_length = ((ih->tlen & 0x00FF) << 8) | ((ih->tlen >> 8) & 0x00FF);//大小端转换
			u_char data_size = total_length - header_length;
			u_char* p_data = (u_char*)(pkt_data + ip_offset);

			printf("IP HEADER: version = %d, header length = %d, totol length = %d, idnt = %d, flag = %d, ttl = %d, pro = %d, crc = %d, src = %3d.%3d.%3d.%3d, dst = %3d.%3d.%3d.%3d, data = ",
				(ih->ver_ihl >> 4) & 0x0f,
				header_length,
				total_length,
				((ih->identification & 0x00FF) << 8) | ((ih->identification >> 8) & 0x00FF),//大小端转换
				ih->flags_fo,
				ih->ttl,
				ih->proto,
				ih->crc,
				saddr.byte1,
				saddr.byte2,
				saddr.byte3,
				saddr.byte4,
				daddr.byte1,
				daddr.byte2,
				daddr.byte3,
				daddr.byte4);

			for (int i = 0; i < data_size; i++)
			{
				printf("%02X ", *p_data);
				p_data++;
			}
			printf(" TCP/IP ");
		}
	}
	//here is ARP datagram
	else if (ether_type == 0x806) {
		printf(" ARP ");
	}

	printf("\n");
}

你可能感兴趣的:(c语言,计算机网络)