# Include <winsock2.h>
# Include <ws2tcpip. h>
# Include <stdio. h>
# Include <time. h>
# Include "mstcpip. H"
# Pragma comment (Lib, "ws2_32.lib ")
# Define seq 0x28376839
Socket sockraw = invalid_socket,
Socklisten = invalid_socket;
Struct sockaddr_in DEST;
Bool scanok = false;
Char * dest_host;
Int dest_port;
Int dest_portend;
Int play = 0;
Clock_t start, end ;//ProgramStart Time and end time of Running
Float costtime; // time consumed by the program
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;
Struct // define the TCP pseudo Header
{
Unsigned long saddr; // Source Address
Unsigned long daddr; // Destination Address
Char mbz;
Char ptcl; // protocol type
Unsigned short tcpl; // TCP Length
} Psd_header;
// Sock error handling program
Void checksockerror (INT ierrorcode, char * perrormsg)
{
If (ierrorcode = socket_error)
{
Printf ("% s error: % d/N", perrormsg, getlasterror ());
Closesocket (sockraw );
Exitprocess (-1 );
}
}
// Computing test and
Ushort checksum (ushort * buffer, int size)
{
Unsigned long cksum = 0;
While (size> 1)
{
Cksum + = * buffer ++;
Size-= sizeof (ushort );
}
If (size)
{
Cksum + = * (uchar *) buffer;
}
Cksum = (cksum> 16) + (cksum & 0 xFFFF );
Cksum + = (cksum> 16 );
Return (ushort )(~ Cksum );
}
// Ip address unpacking program
Bool decodeipheader (char * Buf, int bytes)
{
Ip_header * iphdr;
Tcp_header * tcphdr;
Unsigned short iphdrlen;
Iphdr = (ip_header *) BUF;
Iphdrlen = sizeof (unsigned long) * (iphdr-> h_lenver & 0xf );
Tcphdr = (tcp_header *) (BUF + iphdrlen );
// Whether the IP address is from the target IP Address
If (iphdr-> sourceip! = DeST. sin_addr.s_addr) return false;
// Check whether the serial number is correct
If (ntohl (tcphdr-> th_ack )! = (SEQ + 1) & (ntohl (tcphdr-> th_ack )! = SEQ) return false;
// If (tcphdr-> th_flag = 20) return true;
// SYN/ack-scan a port
If (tcphdr-> th_flag = 18)
{
Printf ("/T % d/t open/N", ntohs (tcphdr-> th_sport ));
Return true;
}
Return true;
}
Void usage (void)
{
Printf ("/T ============================= SYN portscaner ================== =========/N ");
Printf ("/T =============== gxisone@hotmail.com 2004/7/6 ===================/N ");
Printf ("/tusage: synscan domainname [IP] startport-endport/N ");
Printf ("/texample: synscan www.163.com 1-139/N ");
Printf ("/texample: synscan 192.168.1.1 8000-9000/N ");
}
DWORD winapi recvthread (lpvoid para) // receives the data thread function
{
Int ierrorcode;
Struct hostent * HP;
Char recvbuf [65535] = {0 };
Socklisten = socket (af_inet, sock_raw, ipproto_ip );
Checksockerror (socklisten, "socket ");
// Set the IP header operation options
Bool bopt = true;
Ierrorcode = setsockopt (sockraw, ipproto_ip, ip_hdrincl, (char *) & bopt, sizeof (bopt ));
Checksockerror (ierrorcode, "setsockopt ()");
// Obtain the local IP Address
Sockaddr_in SA;
Unsigned char localname [256];
Ierrorcode = gethostname (char *) localname, sizeof (localname)-1 );
Checksockerror (ierrorcode, "gethostname ()");
If (HP = gethostbyname (char *) localname) = NULL)
{
Checksockerror (socket_error, "gethostbyname ()");
}
Memcpy (& SA. sin_addr.s_un.s_addr, HP-> h_addr_list [1], HP-> h_length );
SA. sin_family = af_inet;
SA. sin_port = htons (7000 );
Ierrorcode = BIND (socklisten, (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 (socklisten, sio_rcvall, & dwbufferinlen, sizeof (dwbufferinlen), & dwbufferlen, sizeof (dwbufferlen), & dwbytesreturned, null, null );
Checksockerror (ierrorcode, "IOCTL ");
Memset (recvbuf, 0, sizeof (recvbuf ));
// Receive data
For (;;)
{
Ierrorcode = Recv (socklisten, recvbuf, sizeof (recvbuf), 0 );
// Checksockerror (ierrorcode, "Recv ");
Decodeipheader (recvbuf, ierrorcode );
}
If (scanok)
{
Closesocket (socklisten );
Return 0;
}
}
Void playx (void) // defines the status prompt Function
{
// Progress bar
Char * plays [12] =
{
"| ",
"/",
"-",
"//",
"| ",
"/",
"-",
"//",
"| ",
"/",
"-",
"//",
};
Printf ("= % s =/R", plays [play]);
Play = (play = 11 )? 0: Play + 1;
Sleep (2 );
}
// Main Function
Int main (INT argc, char ** argv)
{
Char * P;
If (argc! = 3)
{
Usage ();
Return 0;
}
P = argv [2]; // process port Parameters
If (strstr (argv [2], "-")
{Dest_port = atoi (argv [2]);
For (; * P ;)
If (* (p ++) = '-') break;
Dest_portend = atoi (P );
If (dest_port <1 | dest_portend> 65535)
{Printf ("port error! /N ");
Return 0;
}
}
Dest_host = argv [1];
Usage ();
Int ierrorcode;
Int datasize;
Struct hostent * HP;
Ip_header;
Tcp_header;
Char sendbuf [128] = {0 };
// Initialize the socket
Wsadata;
Ierrorcode = wsastartup (makeword (2, 2), & wsadata );
Checksockerror (ierrorcode, "wsastartup ()");
Sockraw = socket (af_inet, sock_raw, ipproto_ip );
Checksockerror (sockraw, "socket ()");
Socklisten = socket (af_inet, sock_raw, ipproto_ip );
Checksockerror (socklisten, "socket ");
// Set the IP header operation options
Bool bopt = true;
Ierrorcode = setsockopt (sockraw, ipproto_ip, ip_hdrincl, (char *) & bopt, sizeof (bopt ));
Checksockerror (ierrorcode, "setsockopt ()");
// Obtain the local IP Address
Sockaddr_in SA;
Unsigned char localname [256];
Ierrorcode = gethostname (char *) localname, sizeof (localname)-1 );
Checksockerror (ierrorcode, "gethostname ()");
If (HP = gethostbyname (char *) localname) = NULL)
{
Checksockerror (socket_error, "gethostbyname ()");
}
Memcpy (& SA. sin_addr.s_un.s_addr, HP-> h_addr_list [1], HP-> h_length );
SA. sin_family = af_inet;
SA. sin_port = htons (7000 );
Ierrorcode = BIND (socklisten, (psockaddr) & SA, sizeof (SA ));
Checksockerror (ierrorcode, "bind ");
// Obtain the IP address of the target host
Memset (& DEST, 0, sizeof (DEST ));
DeST. sin_family = af_inet;
DeST. sin_port = htons (dest_port );
If (DEST. sin_addr.s_addr = inet_addr (dest_host) = inaddr_none)
{
If (HP = gethostbyname (dest_host ))! = NULL)
{
Memcpy (& (DEST. sin_addr), HP-> h_addr_list [1], HP-> h_length );
DeST. sin_family = hp-> h_addrtype;
Printf ("DeST. sin_addr = % s/n", inet_ntoa (DEST. sin_addr ));
}
Else
{
Checksockerror (socket_error, "gethostbyname ()");
}
}
// Enable the listening thread
Handle thread = createthread (null, 0, recvthread, 0, 0 );
// Fill in the IP Header
Ip_header.h_lenver = (4 <4 | sizeof (ip_header)/sizeof (unsigned long ));
// The version number of the four-digit IP address, and the length of the four-digit Header
Ip_header.total_len = htons (sizeof (ip_header) + sizeof (tcp_header); // The total length of 16 bits (in bytes)
Ip_header.ident = 1; // 16-bit ID
Ip_header.frag_and_flags = 0; // 3-digit flag
Ip_header.ttl = 128; // 8-bit TTL
Ip_header.proto = ipproto_tcp; // 8-bit protocol (TCP, UDP ...)
Ip_header.checksum = 0; // 16-bit IP header checksum
Ip_header.sourceip = sa. sin_addr.s_addr; // 32-bit source IP address
Ip_header.destip = DeST. sin_addr.s_addr; // 32-bit destination IP address
// Fill the TCP Header
Tcp_header.th_sport = htons (7000); // source port number
Tcp_header.th_lenres = (sizeof (tcp_header)/4 <4 | 0); // TCP length and Reserved Bit
Tcp_header.th_win = htons (16384 );
// Fill in the TCP pseudo header (used for calculating the checksum and not actually sending it)
Psd_header.saddr = ip_header.sourceip;
Psd_header.daddr = ip_header.destip;
Psd_header.mbz = 0;
Psd_header.ptcl = ipproto_tcp;
Psd_header.tcpl = htons (sizeof (tcp_header ));
Sleep (500 );
Printf ("/N ");
Printf ("scaning % s/n", dest_host );
Start = clock (); // start timing
For (; dest_port <dest_portend; dest_port ++)
{
Playx ();
Tcp_header.th_dport = htons (dest_port); // the destination port number.
Tcp_header.th_ack = 0; // sets the ACK serial number to 0.
Tcp_header.th_flag = 2; // SYN flag
Tcp_header.th_seq = htonl (SEQ); // SYN serial number
Tcp_header.th_urp = 0; // offset
Tcp_header.th_sum = 0; // checksum
// Calculate the TCP Checksum. The calculation checksum and the TCP pseudo header must be included.
Memcpy (sendbuf, & psd_header, sizeof (psd_header ));
Memcpy (sendbuf + sizeof (psd_header), & tcp_header, sizeof (tcp_header ));
Tcp_header.th_sum = checksum (ushort *) sendbuf, sizeof (psd_header) + sizeof (tcp_header ));
// Calculate IP checksum
Memcpy (sendbuf, & ip_header, sizeof (ip_header ));
Memcpy (sendbuf + sizeof (ip_header), & tcp_header, sizeof (tcp_header ));
Memset (sendbuf + sizeof (ip_header) + sizeof (tcp_header), 0, 4 );
Datasize = sizeof (ip_header) + sizeof (tcp_header );
Ip_header.checksum = checksum (ushort *) sendbuf, datasize );
// Fill the sending Buffer
Memcpy (sendbuf, & ip_header, sizeof (ip_header ));
// Send TCP Packets
Ierrorcode = sendto (sockraw, sendbuf, datasize, 0, (struct sockaddr *) & DEST,
Sizeof (DEST ));
Checksockerror (ierrorcode, "sendto ()");
}
End = clock (); // time end
Scanok = true;
Printf ("closeing thread.../N ");
Waitforsingleobject (thread, 5000 );
Closehandle (thread );
Costtime = (float) (end-Start)/clocks_per_sec; // convert the time format
Printf ("cost time: % F sec", costtime); // display time consumption
// Clear before exiting
If (sockraw! = Invalid_socket) closesocket (sockraw );
Wsacleanup ();
Return 0;
}