# Include "stdafx. H"
# Include "stdio. H"
# Include "string. H"
# Include "mstcpip. H"
# Include "winsock2.h"
# Pragma comment (Lib, "ws2_32.lib ")
# Define status_failed 0 xFFFF // defines the error code
# Define max_pack_len 65535 // maximum number of recipients
IP Packets
# Define max_addr_len 16 // decimal point
Maximum address Length
# Define max_hostname_lan 255 // maximum Host Name Length
Typedef struct _ iphdr // defines the IP Header
{
Unsigned char h_lenver; // 4
Bit Header Length + 4-bit IP version number
Unsigned char TOS;
// 8-bit service type (ToS)
Unsigned short total_len; // 16
Total bit length (bytes)
Unsigned short ident; // 16
Bit ID
Unsigned short frag_and_flags; // 3-Bit Flag
Unsigned char TTL;
// 8-bit TTL
Unsigned char proto; // 8
Bit protocol (TCP or other)
Unsigned short checksum; // 16
Bit IP header checksum
Unsigned int sourceip; // 32
Source IP Address
Unsigned int destip; // 32
Destination IP address
} Ip_header;
Typedef struct _ tcphdr // defines the beginning of TCP
Department
{
Ushort th_sport;
// 16-bit Source Port
Ushort th_dport;
// 16-bit destination port
Unsigned int th_seq;
Unsigned int th_ack;
Unsigned char th_lenres; // 4
Bit header length/6 Reserved Words
Unsigned char th_flag; // 6
Bit Flag bit
Ushort th_win;
// 16-bit window size
Ushort th_sum;
// 16-bit checksum
Ushort th_urp;
// 16-bit emergency data offset
} Tcp_header;
Socket sockraw;
Char * tcpflag [6] = {// set
TCP flag
"Fin ",
// Fin: indicates that the sender has no data requirements for transmission and wants to release the connection.
"Syn ",
// SYN: the flag is used to establish a connection and synchronize the serial number between the two parties. If SYN = 1 and ACK = 0, the packet is a connection request. If SYN = 1 and ACK = 1
Accept the connection.
"Rst ",
// Rst: Used to reset a connection. The RST flag is called a reset packet. Generally, if a segment received by TCP does not belong to any segment on the host
Send a reset packet to the remote end.
"Psh ",
// PSH: if it is set, the receiving end should transmit the data to the application layer as soon as possible.
"Ack ",
// Ack: indicates the flag. If the value is 1, it indicates that the validation number in the package is valid. Otherwise, the confirmation number in the package is invalid.
"URG"
// URG: indicates the emergency data. If it is 1, the package contains emergency data. In this case, the emergency Data Pointer is valid.
};
Bool paramtcp = true; //-t follow TCP
Packets
Char * strfromipfilter = NULL; // source IP address
Filter
Char * strdestipfilter = NULL; // The Destination Address has passed
Filter
// Referrence
Int decodeippack (char *, INT );
Int decodetcppack (char *);
Void checksockerror (INT, char *);
Void usage (void );
Bool getcmdline (INT, char **);
//
Void main (INT argc, char ** argv)
{
Int ierrorcode;
Char recvbuf [max_pack_len] = {0 };
Usage ();
If (getcmdline (argc, argv) = true)
Exit (0 );
// Initialize the socket
Wsadata;
Ierrorcode = wsastartup (makeword (2, 1), & wsadata );
Checksockerror (ierrorcode, "wsastartup ");
Sockraw = socket (af_inet, sock_raw, ipproto_ip );
Checksockerror (sockraw, "socket ");
// Obtain the IP address of the Local Machine
Char far name [max_hostname_lan];
Ierrorcode = gethostname (name, max_hostname_lan );
Checksockerror (ierrorcode, "gethostname ");
Struct hostent far * phostent;
Phostent = (struct hostent *) malloc (sizeof (struct hostent ));
Phostent = gethostbyname (name );
Sockaddr_in SA;
SA. sin_family = af_inet;
SA. sin_port = htons (6000 );
Memcpy (& SA. sin_addr.s_un.s_addr, phostent-> h_addr_list [0], phostent-> h_length );
Ierrorcode = BIND (sockraw, (psockaddr) & SA, sizeof (SA ));
Checksockerror (ierrorcode, "bind ");
// Set sock_raw to sio_rcvall to receive all IP Packets
DWORD dwbufferlen [10];
DWORD dwbufferinlen = 1;
DWORD dwbytesreturned = 0;
Ierrorcode = wsaioctl (sockraw,
Sio_rcvall,
& Dwbufferinlen,
Sizeof (dwbufferinlen ),
& Dwbufferlen,
Sizeof (dwbufferlen ),
& Dwbytesreturned,
Null,
Null );
Checksockerror (ierrorcode, "IOCTL ");
// Listen for IP Packets
While (true)
{
Memset (recvbuf, 0, sizeof (recvbuf ));
Ierrorcode = Recv (sockraw, recvbuf, sizeof (recvbuf), 0 );
Checksockerror (ierrorcode, "Recv ");
Ierrorcode = decodeippack (recvbuf, ierrorcode );
Checksockerror (ierrorcode, "decode ");
}
}
// Ip address unpacking program
Int decodeippack (char * Buf, int ibufsize)
{
Ip_header * pipheader;
Int iprotocol, ittl;
Char szprotocol [4];
Char szsourceip [max_addr_len], szdestip [max_addr_len];
Sockaddr_in sasource, sadest;
Pipheader = (ip_header *) BUF;
// Check proto
Iprotocol = pipheader-> proto;
Strncpy (szprotocol, "TCP", 4 );
If (iprotocol = ipproto_tcp)
{
// Check Source IP
Sasource. sin_addr.s_addr = pipheader-> sourceip;
Strncpy (szsourceip, inet_ntoa (sasource. sin_addr), max_addr_len );
If (strfromipfilter)
If (strcmp (strfromipfilter, szsourceip ))
Return true;
// Check DEST IP
Sadest. sin_addr.s_addr = pipheader-> destip;
Strncpy (szdestip, inet_ntoa (sadest. sin_addr), max_addr_len );
If (strdestipfilter)
If (strcmp (strdestipfilter, szdestip ))
Return true;
// TTL
Ittl = pipheader-> TTL;
// Output
Printf ("% s", szprotocol );
Printf ("% s-> % s", szsourceip, szdestip );
Printf ("bytes = % d TTL = % d", ibufsize, ittl );
// Calculate IP header length
Int iiphlen = sizeof (unsigned long) * (pipheader-> h_lenver & 0xf );
// Decode sub Protocol: TCP
Decodetcppack (BUF + iiphlen );
}
Return true;
}
// Sock error handling program
Void checksockerror (INT ierrorcode, char * perrormsg)
{
If (ierrorcode = socket_error)
{
Printf ("% s error: % d/N", perrormsg, getlasterror ());
Closesocket (sockraw );
Exit (0 );
}
}
// TCP unpacking program
Int decodetcppack (char * tcpbuf)
{
Tcp_header * ptcpheader;
Ptcpheader = (tcp_header *) tcpbuf;
Printf ("port: % d-> % d", ntohs (ptcpheader-> th_sport), ntohs (ptcpheader-> th_dport ));
Unsigned char flagmask = 1;
Int hdrlen = (ptcpheader-> th_lenres)> 2;
Printf ("/n % s", (byte *) ptcpheader) + hdrlen );
For (INT I = 0; I <6; I ++)
{
If (ptcpheader-> th_flag) & flagmask)
Printf ("% s", tcpflag [I]);
Else
Printf ("");
Flagmask = flagmask <1;
}
Printf ("/N ");
Return true;
}
// Command line parameter Processing
Bool getcmdline (INT argc, char ** argv)
{
For (INT I = 1; I <argc; I ++)
{
If (argv [I] [0]! = '/')
Return true;
Else
{
Switch (argv [I] [1])
{
Case 'F ':
Case 'F ':
{
Strfromipfilter = (char *) malloc (16 * sizeof (char ));
Memset (strfromipfilter, * sizeof (char ));
Strcpy (strfromipfilter, argv [I] + 3 );
Break;
}
Case 'D ':
Case 'D ':
{
Strdestipfilter = (char *) malloc (16 * sizeof (char ));
Memset (strdestipfilter, 0, 16 * sizeof (char ));
Strcpy (strdestipfilter, argv [I] + 3 );
Break;
}
Case '? ':
Return true;
Break;
Default:
Break;
}
}
}
Printf ("/nwill sniffer ");
Printf ("TCP ");
If (strfromipfilter)
Printf ("fromip: % s", strfromipfilter );
If (strdestipfilter)
Printf ("destip: % s", strdestipfilter );
Printf ("/n/tctrl + C to quit/nstart:/N ");
Return (false );
}
Void usage (void)
{
Printf ("/tsinffer for Win2k console/N ");
Printf ("Usage:/N ");
Printf ("/T/F: fromip output packets fromip = fromip (default all)/n ");
Printf ("/t/d: destip output packets destip = destip (default all )");
Printf ("/nexample:/N ");
Printf ("/tsniffer.exe/D: 192.168.15.233/N ");
Printf ("/tsniffer.exe/F: 192.168.15.231/N ");
}