Haha, it's a very old technology, but I wrote one in the past two days, and everyone laughed.
Sniff is implemented in three steps:
1. Set the NIC to the hybrid mode
2. Capture IP data packets
3. Analyze IP data packets
The following is the implementation
//////////////////////////////////////// //////////////////////////////////////// ///
Mysniff. h
//////////////////////////////////////// //////////////////////////////////////// ///
# Include <winsock2.h>
# Include <iostream>
# Include <string. h>
# Include <ws2tcpip. h>
# Include <mstcpip. h>
Using namespace STD;
Class mysniff
{
Public:
Mysniff (void );
~ Mysniff (void );
Public:
Int initsniff (); // listener initialization Function
Int listenfunction (); // listener Function
Void releasesocket (); // releases the socket function
Void ipanalyse (char * BUF); // ip packet analysis function
PRIVATE:
Socket m_socket; // The socket used for listening
Wsadata m_wsadata; // variable used to initialize Network Programming
Hostent * m_hostent; // used to store the IP address list of the Local Machine
Struct sockaddr_in m_sockaddr; // ip address used for listening
};
/*************************************** ***********************
* Data Type: protostruct
* Main function: defines the structure of the protocol and protocol name to facilitate obtaining the protocol according to the protocol.
* Protocol name
**************************************** **********************/
Typedef struct _ protostruct
{
Int proto; // protocol ID
String prototext; // protocol name
} Protostruct;
/*************************************** ***********************
* Data Type: ipheader
* Main function: defines the data structure corresponding to the IP datagram header, when the number of IP addresses received
* After forced data type conversion, you can retrieve the corresponding data
**************************************** **********************/
Typedef struct _ ipheader
{
Unsigned char verandheader_len; // version and header length
Unsigned char servertype; // data type
Unsigned short totallen; // packet size
Unsigned short ident; // datagram ID
Unsigned short flags; // flag and part offset
Unsigned char TTL; // survival time
Unsigned char proto; // Protocol
Unsigned short checksum; // The first checksum.
Unsigned int sourceip; // Source Address
Unsigned int destip; // Destination Address
} Ipheader;
/*************************************** ***********************
* Data Type: tcpheader
* Main function: defines the data structure corresponding to the tip datagram header.
* After forced data type conversion, you can retrieve the corresponding data
**************************************** **********************/
Typedef struct _ tcpheader
{
Unsigned short sourport; // Source Port
Unsigned short desport; // destination port
Unsigned int seqno; // serial number
Unsigned int askno; // confirmation number
Unsigned char offset; // data offset. How far is the data start from the start of the packet segment?
Unsigned char controtbit; // bit control
Unsigned short wndsize; // window size, used to control the volume of data sent by the recipient
Unsigned short chksum; // check
Unsigned short urgptr; // emergency pointer
} Tcpheader;
/*************************************** ***********************
* Data Type: udpheader
* Main function: defines the data structure corresponding to the UDP datagram header.
* After forced data type conversion, you can retrieve the corresponding data
**************************************** **********************/
Typedef struct _ udpheader
{
Unsigned short sourprot; // Source Port
Unsigned short destport; // destination port
Unsigned short Len; // UDP datagram Length
Unsigned chksum; // check
} Udpheader;
/*************************************** ***********************
* Data Type: tcmpheader
* Main function: defines the data structure corresponding to the tcmp datagram header.
* After forced type conversion is performed on the tcmp data, the corresponding data can be retrieved.
**************************************** **********************/
Typedef struct _ icmpheader
{
Unsigned char type; // Message Type
Unsigned char code; // code
Unsigned short chksum; // check
} Icmpheader;
// Define the UDP Header Length
# Define udp_head_len 8
// Define the length of the ICMP Header
# Define icmp_head_len 4
/********************************* End of file *** ************************************/
//////////////////////////////////////// //////////////////////////////////////// //////////
Mysniff. cpp
//////////////////////////////////////// //////////////////////////////////////// //////////
# Include "mysinff. H"
Protostruct myprotos [12] =
{
{Ipproto_ip, "ip "},
{Ipproto_icmp, "ICMP "},
{Ipproto_igmp, "IGMP "},
{Ipproto_ggp, "GGP "},
{Ipproto_tcp, "TCP "},
{Ipproto_pup, "Pup "},
{Ipproto_udp, "UDP "},
{Ipproto_idp, "IDP "},
{Ipproto_nd, "NP "},
{Ipproto_raw, "Raw "},
{Ipproto_max, "Max "},
{Null ,""}
};
String getproto (int proto );
Mysniff: mysniff (void)
{
}
Mysniff ::~ Mysniff (void)
{
}
/*************************************** **************************************** *
* Function Introduction: This function is used to complete the listener initialization function, including registering DLL and initializing socket
* Input parameter: None
* Output parameter: None
* Return value: indicates the initialization success or the type of the initialization failure error.
**************************************** **************************************** */
Int mysniff: initsniff ()
{
If (wsastartup (makeword (2, 2), & m_wsadata) = socket_error)
{
Releasesocket ();
Return-1;
}
If (m_socket = socket (af_inet, sock_raw, ipproto_ip) = socket_error)
{
Releasesocket ();
Return-2;
}
Int rcvtime = 5000;
If (setsockopt (m_socket, sol_socket, so_rcvtimeo, (const char *) & rcvtime, sizeof (rcvtime) = socket_error)
{
Return-3;
}
Char flag [256];
Setsockopt (m_socket, ipproto_ip, ip_hdrincl, (char *) & flag, sizeof (FLAG ));
Char localname [50];
Gethostname (localname, sizeof (localname ));
Struct hostent * myhost;
Myhost = gethostbyname (localname );
M_sockaddr.sin_family = af_inet;
M_sockaddr.sin_addr = * (in_addr *) myhost-> h_addr_list [0];
M_sockaddr.sin_port = htons (8080 );
If (BIND (m_socket, (struct sockaddr *) & m_sockaddr, sizeof (m_sockaddr) = socket_error)
{
Return-4;
}
Unsigned long dwvalue = 1;
Ioctlsocket (m_socket, sio_rcvall, & dwvalue );
Return 0;
}
/*************************************** **************
* Function: Disable the socket used for listening and release socket resources.
* Input parameter: None
* Output parameter: None
* Return value: None
**************************************** *************/
Void mysniff: releasesocket ()
{
Shutdown (m_socket, sd_both );
Closesocket (m_socket );
Wsacleanup ();
}
/*************************************** **************
* Function: Listener function. The Listener function is used to intercept and complete IP datagram.
Data Type analysis and data analysis.
* Input parameter: None
* Output parameter: None
* Return value: whether it is successful. If it fails, the cause of failure is returned.
**************************************** *************/
Int mysniff: listenfunction ()
{
Char Buf [65535];
Ipheader * ipheader; // structure variable that stores the IP packet header
In_addr ipaddr; // address type variable
Unsigned short headerlen, totallen; // the header length and Total Packet Length of the Data Packet
Unsigned short sourport, destport;
String strsourip, strdestip; // source IP address, destination IP address
String strsourport, strdestport; // source port address, destination port address
Char * data; // pointer to the protocol data packet
String strproto; // protocol name
Int ret = 0;
While (true)
{
// Memset (BUF, 0, 1024 );
Totallen = 0;
Ret = Recv (m_socket, Buf, sizeof (BUF), 0 );
If (ret = socket_error)
{
Continue;
}
Char * workbuf = Buf;
Ipheader = (ipheader *) workbuf; // forcibly convert the IP address data Header
Ipaddr. s_un.s_addr = ipheader-> sourceip; // obtain the source IP address.
Strsourip = inet_ntoa (ipaddr); // convert the obtained source IP address to a string
Ipaddr. s_un.s_addr = ipheader-> destip; // obtain the destination IP address.
Strdestip = inet_ntoa (ipaddr); // convert the obtained destination IP address to a string
Unsigned char proto = ipheader-> proto;
Strproto = getproto (PROTO );
Headerlen = ipheader-> verandheader_len & 0xf;
Headerlen = headerlen * 4;
Totallen = ntohs (ipheader-> totallen );
Totallen = totallen-headerlen;
Switch (PROTO)
{
Case ipproto_icmp:
{
Icmpheader * icmpheader; // structure variable for storing ICMP packet headers
Icmpheader = (icmpheader *) (workbuf + headerlen );
Strsourport = "-";
Strdestport = "-";
Char * nowdata = (char *) icmpheader) + icmp_head_len; // point data to the data part of the ICMP data packet
Totallen-= icmp_head_len; // obtain the total length of the Data Part Of The ICMP data packet.
Data = new char [totallen + 1];
// Memcpy (data, nowdata, totallen );
Break;
}
Case ipproto_tcp:
{
Tcpheader * tcpheader; // structure variable for storing TCP packet headers
Tcpheader = (tcpheader *) (workbuf + headerlen );
Sourport = ntohs (tcpheader-> sourport );
Destport = ntohs (tcpheader-> desport );
Headerlen = (tcpheader-> offset)> 4) & 0xf;
Headerlen = headerlen * 4;
Char * nowdata = (char *) tcpheader) + headerlen;
Totallen-= headerlen; // obtain the total length of the Data Part of the TCP packet
Data = new char [totallen + 1];
// Memcpy (data, nowdata, totallen );
Break;
}
Case ipproto_udp:
{
Udpheader * udpheader; // structure variable that stores the UDP packet header
Udpheader = (udpheader *) (workbuf + headerlen );
Sourport = ntohs (udpheader-> sourprot );
Destport = ntohs (udpheader-> destport );
Char * nowdata = (char *) udpheader) + udp_head_len;
Totallen-= udp_head_len; // obtain the total length of the Data Part Of The UDP packet.
Data = new char [totallen + 1];
// Memcpy (data, nowdata, totallen );
Break;
}
} // End switch;
Cout <strproto. c_str () <"/t" <strsourip. c_str () <"/t" <strdestip. c_str ()
<"/T" <sourport <"/t" <destport <"/t" <RET <"/t" <totallen <Endl;
// Cout <data <Endl;
}
Return 0;
}
/*************************************** **************
* Function: Obtain the protocol name based on the specified protocol type.
* Input parameters:
Int proto protocol type
* Output parameter: None
* Return value: the name of the Protocol.
**************************************** *************/
String getproto (int proto)
{
Bool bfound = false;
For (INT I = 0; I <11; I ++)
{
If (myprotos [I]. proto = PROTO)
{
Bfound = true;
Break;
}
}
If (bfound)
Return myprotos [I]. prototext;
Return myprotos [11]. prototext;
}
/********************************* End of file *** ************************************/
//////////////////////////////////////// //////////////////////////////////////// ///////////////
Sniff. cpp
//////////////////////////////////////// //////////////////////////////////////// ////////////////
# Include "mysinff. H"
# Include <windows. h>
# Include <process. h>
Int main ()
{
Mysniff;
If (mysniff. initsniff ()! = 0)
{
Cout <"init sniff error! "<Endl;
}
Else
{
Mysniff. listenfunction ();
}
Char ch;
Cin> CH;
Return 0;
}