# Include <stdio. h>
# Include <string. h>
# Include <winsock2.h>
# Include "mstcpip. H"
# Pragma comment (Lib, "ws2_32.lib ")
# Define status_failed 0 xFFFF // defines the error code
# Define max_pack_len 65535 // maximum IP Message received
# Define max_addr_len 16 // the maximum length of the decimal point address
# Define max_proto_text_len 16 // the maximum length of the sub-protocol name (for example, "TCP ")
# Define max_proto_num 12 // number of sub-Protocols
# Define max_hostname_lan 255 // maximum Host Name Length
# Define pai_param_help true
# Define def_sniffer_dbg_en
Typedef struct _ iphdr
{
Unsigned char h_lenver; // 4-bit Header Length + 4-bit IP version number
Unsigned char TOS; // an 8-bit service type TOS
Unsigned short total_len; // The total length of 16 bits (in 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, UDP, or other)
Unsigned short checksum; // 16-bit IP header checksum
Unsigned int sourceip; // 32-bit source IP address
Unsigned int destip; // 32-bit destination IP address
} Ip_header;
Typedef struct _ tcphdr // defines the TCP Header
{
Ushort th_sport; // 16-bit Source Port
Ushort th_dport; // 16-bit destination port
Unsigned int th_seq; // 32-bit serial number
Unsigned int th_ack; // 32-bit confirmation number
Unsigned char th_lenres; // 4-bit header length/6-bit reserved words
Unsigned char th_flag; // 6-digit flag
Ushort th_win; // 16-bit window size
Ushort th_sum; // 16-bit checksum
Ushort th_urp; // 16-bit emergency data offset
} Tcp_header;
Typedef struct _ udphdr // defines the UDP Header
{
Unsigned short uh_sport; // 16-bit Source Port
Unsigned short uh_dport; // 16-bit destination port
Unsigned short uh_len; // 16-Bit Length
Unsigned short uh_sum; // 16-bit checksum
} Udp_header;
Typedef struct _ icmphdr // defines the ICMP Header
{
Byte I _type; // 8-bit type
Byte I _code; // 8-bit code
Ushort I _cksum; // 16-bit checksum
Ushort I _id; // identification number (process number is generally used as the identification number)
Ushort I _seq; // message serial number
Ulong timestamp; // Timestamp
} Icmp_header;
Typedef struct _ protomap // defines the sub-Protocol ing table
{
Int protonum;
Char prototext [max_proto_text_len];
} Protomap;
Protomap [max_proto_num] = {// assign a value to the sub-Protocol ing table
{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 ,""}};
Socket sockraw;
Char tcpflag [6] = {'F','s ', 'R', 'P', 'A', 'U'}; // defines the TCP flag
Bool paramtcp = false; //-t follows the TCP packet
Bool paramudp = false; //-u follows UDP Packets
Bool paramicmp = false; //-I: Follow ICMP Packets
Bool paramdecode = true; //-D decodes the Protocol
Char * strfromipfilter = NULL; // filter source IP addresses
Char * strdestipfilter = NULL; // destination address filtering
Int decodeippack (char *, INT );
Int decodetcppack (char *);
Int decodeudppack (char *);
Int decodeicmppack (char *);
Void checksockerror (INT, char *);
Char * checkprotocol (INT );
Void usage (void );
Bool getcmdline (INT, char **);
Void main (INT argc, char ** argv)
{
# Ifdef def_sniffer_dbg_en
Argc = 4;
// Guniffer.exe/T/u/F:
Argv [0] = "guniffer.exe ";
Argv [1] = "/t ";
Argv [2] = "/u ";
Argv [3] = "/F: 192.168.0.103 ";
# Endif
Int ierrorcode;
Char recvbuf [max_pack_len] = {0 };
Usage ();
If (get1_line (argc, argv) = pai_param_help) 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 local IP Address
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 (1)
{
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 [max_proto_text_len];
Char szsourceip [max_addr_len], szdestip [max_addr_len];
Sockaddr_in sasource, sadest;
Pipheader = (ip_header *) BUF;
// Check proto
Iprotocol = pipheader-> proto;
Strncpy (szprotocol, checkprotocol (iprotocol), max_proto_text_len );
If (iprotocol = ipproto_tcp )&&(! Paramtcp) return true;
If (iprotocol = ipproto_udp )&&(! Paramudp) return true;
If (iprotocol = ipproto_icmp )&&(! Paramicmp) return true;
// 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;
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, UDP, ICMP, etc
Switch (iprotocol)
{
Case ipproto_tcp: decodetcppack (BUF + iiphlen); break;
Case ipproto_udp: decodeudppack (BUF + iiphlen); break;
Case ipproto_icmp: decodeicmppack (BUF + iiphlen); break;
Default: break;
}
// Printf ("/N ");
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 );
}
}
// Protocol Identification Program
Char * checkprotocol (INT iprotocol)
{
For (INT I = 0; I <max_proto_num; I ++)
If (protomap [I]. protonum = iprotocol)
Return protomap [I]. prototext;
Return "";
}
// TCP unpacking program
Int decodetcppack (char * tcpbuf)
{
Tcp_header * ptcpheader;
Int I;
Ptcpheader = (tcp_header *) tcpbuf;
Printf ("port: % d-> % d", ntohs (ptcpheader-> th_sport), ntohs (ptcpheader-> th_dport ));
Unsigned char flagmask = 1;
For (I = 0; I <6; I ++)
{
If (ptcpheader-> th_flag) & flagmask) printf ("% C", tcpflag [I]);
Else printf ("-");
Flagmask = flagmask <1;
}
Printf ("/N ");
Return true;
}
// UDP unpacking program
Int decodeudppack (char * udpbuf)
{
Udp_header * pudpheader;
Pudpheader = (udp_header *) udpbuf;
Printf ("port: % d-> % d", ntohs (pudpheader-> uh_sport), ntohs (pudpheader-> uh_dport ));
Printf ("Len = % d/N", ntohs (pudpheader-> uh_len ));
Return true;
}
// ICMP unpacket handling program
Int decodeicmppack (char * icmpbuf)
{
Icmp_header * picmpheader;
Picmpheader = (icmp_header *) icmpbuf;
Printf ("type: % d, % d", picmpheader-> I _type, picmpheader-> I _code );
Printf ("ID = % d seq = % d/N", picmpheader-> I _id, picmpheader-> I _seq );
Return true;
}
// Command line parameter Processing
Bool getcmdline (INT argc, char ** argv)
{
If (argc <2) return param_param_help;
For (INT I = 1; I <argc; I ++)
{
If (argv [I] [0]! = '/') Return parameter _param_help;
Else switch (argv [I] [1])
{
Case 'T ':
Case 'T': paramtcp = true; break;
Case 'U ':
Case 'U': paramudp = true; break;
Case 'I ':
Case 'I': paramicmp = true; break;
Case 'p ':
Case 'p': paramdecode = true; break;
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;
}
}
}
Printf ("/nwill sniffer ");
If (paramtcp) printf ("TCP ");
If (paramudp) printf ("UDP ");
If (paramicmp) printf ("ICMP ");
If (strfromipfilter) printf ("fromip: % s", strfromipfilter );
If (strdestipfilter) printf ("destip: % s", strdestipfilter );
Printf ("/n/tctrl + C to quit/nstart:/N ");
Return (! __Param_help );
}
// Instructions for use
Void usage (void)
{
Printf ("guniffer/N ");
Printf ("/tsinffer for Win2k by shotgun (ver 0.2)/n ");
Printf ("/tShotgun@Xici.net/N ");
Printf ("/thttp: // it. xici. Net/N ");
Printf ("/thttp: // www. Patching. Net/n ");
Printf ("Usage:/N ");
Printf ("/T output TCP packets/N ");
Printf ("/T/u output UDP packets/N ");
Printf ("/T/I output ICMP packets/N ");
Printf ("/T/P decode packets (default Off)/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 ("/tgunifer.exe/D> ippack. log/N ");
Printf ("/tgunifer.exe/T/u/F: 192.168.15.231/N ");
}