Current location - Education and Training Encyclopedia - Graduation thesis - Writing network sniffing tools with VC
Writing network sniffing tools with VC
At present, there are many Sniff tools, such as Netxray and Sniffer pro, which are the most famous tools in the Windows environment. It is very convenient to use them to analyze packages in Windows environment. Sniffit, Snoop, Tcpdump, Dsniff and so on are very common in UNIX environment. This paper introduces a simple network sniffer, network data packets and analysis and development tools libpcap and winpcap realized in C language.

The realization of network sniffer program based on 2.

Programming in C environment, the source code is as follows:

/* June 2, 2002

* Bby Team 19 Graduation Qualification Project */

# Including

# Including

//The path must be added, and the header packet32.h must be included.

# contains "... \ ... \ contains \packet32.h"

# contains "... \ ... \..\Include\ntddndis.h"

# Define the maximum number of adapters 10

//prototype

//Outsourcing

void print packets(LP packet LP packet);

//Device list

char Adapter list[Max _ Num _ Adapter][ 1024];

//Start the main program

int main()

{

//Define a pointer to the adapter fabric device pointer.

LP adapter LP adapter = 0;

//Define a pointer to the package structure.

LPPACKET lpPacket

int I;

DWORD dwErrorCode

DWORD dwVersion

DWORD dwWindowsMajorVersion

//Unicode string (WinNT)

WCHAR adapter name[8 192]; //List of network adapter devices

WCHAR *temp,* temp 1;

//ASCII string (Win9x)

char adapter namea[8 192]; //List of network adapter devices

char *tempa,* temp 1a;

int AdapterNum=0,Open

ULONG adapter length;

Char buffer [256000]; //A buffer to hold data from the drive.

struct bpf _ stat stat

//Get the name of the local network card

AdapterLength = 4096

Printf("Packet.dll test application. Library version: %s\n ",packet get version()););

Printf ("Installed adapter: \ n");

I = 0;

The following code is used to obtain the names of different versions of network adapters:

The network card names in Win9x and WinNT are realized in ASCII and UNICODE respectively, so the version number of the local operating system should be obtained first.

dw version = GetVersion();

dwWindowsMajorVersion =(DWORD)(LOBYTE(LOWORD(dw version)));

The first Packet.dll function used here is Packet GetAdapternames (PT STRPSTR, PULONG BufferSize), which is usually the first function to communicate with the driver and be called. It puts the name of the network adapter installed in the user's local system in the buffer PSTR. BufferSize is the length of the buffer:

If (! (dwVersion & gt= 0x80000000。 & ampdwWindowsMajorVersion & gt= 4))

{//is Windows NT.

//The device list could not be found.

if(PacketGetAdapterNames(AdapterName,& ampAdapterLength)==FALSE){

Printf ("Unable to retrieve adapter list! \ n ");

return- 1;

The realization of a simple network sniffer comes from: bookmark paper network.

}

//Find the device list

temp = AdapterName

temp 1 = adapter name;

while ((*temp! ='\0')||(*(temp- 1)! ='\0'))

{

if (*temp=='\0 ')

{

memcpy(AdapterList,temp 1,(temp-temp 1)* 2);

temp 1 = temp+ 1;

i++;

}

temp++;

}

//Display the list of adapters

adapter num = I;

for(I = 0; i wprintf(L"\n%d- %s\n ",i+ 1,adapter list);

printf(" \ n ");

}

Else // Otherwise it is windows 9x, and the method of obtaining the adapter name is the same as that under WinNT.

{

if(PacketGetAdapterNames(adaptername,& ampAdapterLength)==FALSE){

Printf ("Unable to retrieve adapter list! \ n ");

The implementation of a simple network sniffer in this paper comes from

return- 1;

}

tempa = AdapterNamea

temp 1a = adapter namea;

And ((*tempa! ='\0')||(*(tempa- 1)! ='\0'))

{

if (*tempa=='\0 ')

{

memcpy(AdapterList,temp 1a,tempa-temp 1a);

temp 1a = tempa+ 1;

i++;

}

tempa++;

}

adapter num = I;

for(I = 0; i printf("\n%d- %s\n ",i+ 1,adapter list);

printf(" \ n ");

}

The following code is to let the user choose the network adapter number to listen to:

//Select the device

do

{

Printf ("Select the number of the adapter to open:");

Scanf("%d ",& open);

If (open the> adapter number)

Printf ("\ nthis number must be less than %d", adaptenum);

} while (open & gt adapter num);

Then, turn on the selected device, which can be set to "mixed" mode or "direct" mode. The code is as follows:

//Turn on the device

LP adapter = packet Open adapter(adapter list[Open- 1]);

//When the device cannot be opened, an error message is displayed:

If (! LP adapter | |(LP adapter-& gt; HFile == Invalid handle value))

{

dw error code = GetLastError();

Printf ("Unable to open adapter, error code: %lx\n", dwerrorcode);

return- 1;

}

Use the following code to set the network card to promiscuous mode:

Packet SethwFilter (LPAdapter Object, ULONG filter) function is used here, which sets hardware filter for incoming data packet and returns TRUE if the operation is successful. AdapterObject is a pointer to the network card device where the filter is located; Constant filters of filters are defined in the header file ntddndis.h, including:

Ndis-Packet-Type-Promiscuos: Set promiscuous mode, and every incoming packet will be accepted by the network card;

NDIS- Packet Type-Directional: Only packets sent directly to the host network card are accepted;

NDIS- packet-type-broadcast: only broadcast packets are accepted;

NDIS- Packet-Type-Multicast: Only multicast packets of the host's group are accepted;

NDIS- Packet-Type-All-Multicast: Accept each multicast packet.

//Set the network adapter to promiscuous mode.

//If the promiscuous mode setting fails, an error will be prompted:

If(PacketSetHwFilter(lpAdapter, NDIS _ packet _ type _ jumble) ==FALSE){

The realization of a simple network sniffer comes from: bookmark paper network.

Printf ("Warning: promiscuous mode cannot be set! \ n ");

}

Then put a 5 12K buffer in the driver:

The function packet set buff (LP adapter adapter object, int dim) is used here to set the buffer of the driver of the network card pointed by the adapter object, and return TRUE if successful. Dim is the size of the new buffer. After setting, the data in the old buffer will be discarded and the stored data packets will be lost.

Note: Whether the size of the driver buffer is set properly will affect the performance of the packet interception process. The setting should ensure fast operation and no packet loss. What is set here is 5 12000 bytes.

//Set a buffer of 5 12K in the driver.

//If the buffer cannot be set, an error will be prompted:

if(PacketSetBuff(lpAdapter,5 12000)==FALSE){

Printf ("Unable to set kernel buffer! \ n ");

return- 1;

}

Packet set read timeout (LP adapter adapter object, int timeout) is used to set the timeout value of the read operation bound to the network card specified by the adapter object. Timeout is in milliseconds, and 0 means there is no timeout. When there is no packet, read will not return.

//Set 1 sec read timeout.

//Set the read operation timeout 1 sec.

if(PacketSetReadTimeout(LP adapter, 1000)==FALSE){

Printf ("Warning: Cannot set read tiemout! \ n ");

}

Next, locate the device, the code is as follows:

The function PacketAllocatePacket(Void) used here will allocate a packet structure in memory and return a pointer to it, but the Buffer field of this structure has not been set, so the function PacketInitPacket should be called again to initialize it.

//Allocate and initialize a packet structure, which will be used for

//Receive the data packet.

//When positioning fails, an error will be prompted:

if((LP packet = PacketAllocatePacket())= = NULL){

Printf ("\ nerror: unable to allocate LPPACKET structure. );

return(- 1);

}

Then, you can initialize the device and start accepting network packets:

Initialize the packet structure with the function of packet init packet (lppacket lppacket, PVOID Buffer, UINT Length). LpPacket is the pointer to be initialized; Buffer is a pointer to a user-allocated buffer containing packet data; Length is the length of the buffer.

It should be noted that the buffer associated with the packet structure stores the packets intercepted by the packet capture driver, and the number of packets is limited by the buffer size. The maximum buffer size is the amount of data that an application can read from the driver at a time. Therefore, setting a large buffer can reduce the number of system calls and improve the interception efficiency. The setting here is 256K K k.

PacketInitPacket(lpPacket,(char*)buffer,256000);

Next, it is the main loop of packet interception:

//main capture cycle

The function packet receive packet (lpadapter object, LPPACKET lpPacket, BOOLEAN Sync) is used here, which will accept (intercept) a set of packets. These parameters include an adapter structure pointer to a network card for specifying packet interception, a packet structure for containing packets, and a flag indicating whether to operate in synchronous mode or asynchronous mode. When the operations are synchronized, the function locks the program; When the operation is asynchronous, the function does not lock the program, and the process of PacketWaitPacket must be called to check whether it is completed correctly. Generally, synchronous mode is adopted.

//Until there is a keyboard to type:

And (! kbhit())

{

//Capture packet Capture packet.

//When capturing a package fails, an error will be prompted:

if(PacketReceivePacket(LP adapter,lpPacket,TRUE)==FALSE){

Printf ("Error: Packet Received Packet Failed");

The realization of a simple network sniffer comes from: bookmark paper network.

return(- 1);

}

//Print the data in the package and call the custom function PrintPackets ().

print packets(LP packet);

}

Finally, print out the statistical data, the code is as follows:

The function packetgetstats (lpadapterdapter object, struct bpf_star*s) used here can get the values of the internal variables of two drivers: the number of packets received by the specified network card since calling the PacketOpenAdapter; And the number of packets received by the network card but discarded by the kernel. These two values are copied by the driver into the bpf_stat structure provided by the application.

//Print capture statistics

//Get statistical information

//When the state cannot be read from the kernel, an error will be prompted:

if(PacketGetStats(lpAdapter,& ampstat)==FALSE){

Printf ("Warning: Unable to get statistics from the kernel! \ n ");

}

//Print "XX packet interception; XX packet dropped ":

other

Printf ("\ n \ nReceived %d packets. \n%d data packets are lost ",stat.bs_recv, stat.bs _ drop);

Here, the function packet free packet (LP packet lppacket) is used to release the structure pointed by lppacket:

//Free up space

packet free packet(LP packet);

Use the function packet close adapter (LP adapter lpadapter) to release the adapter structure lpadapter and close the network card pointer:

//Close the adapter and exit.

//Turn off the device and exit.

packet close adapter(LP adapter);

return(0);

}//End of main program

The code of the custom function PrintPackets () for printing datagrams is not described in detail here.

3 Conclusion

Through the preparation of network sniffer, the purpose is to let everyone know the importance of network management, always pay attention to the security of network information, and do a good job of encryption and decryption of information.