<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Binary Tides &#187; Winsock</title>
	<atom:link href="http://www.binarytides.com/blog/category/winsock/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.binarytides.com/blog</link>
	<description></description>
	<lastBuildDate>Sat, 24 Jul 2010 05:31:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>TCP Connect Port Scanner Source Code in C with Winsock</title>
		<link>http://www.binarytides.com/blog/tcp-connect-port-scanner-code-in-c-with-winsock/</link>
		<comments>http://www.binarytides.com/blog/tcp-connect-port-scanner-code-in-c-with-winsock/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 10:16:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Winsock]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=52</guid>
		<description><![CDATA[TCP connect() scanning is the most basic form of TCP scanning. The program performs a connect() command on those ports of the target machine which are to be checked. If the port is open then the connect() command will succeed and a connection will be established. If the port is closed the connect() function would [...]]]></description>
			<content:encoded><![CDATA[<p>TCP connect() scanning is the most basic form of TCP scanning. The program performs a connect() command on those ports of the target machine which are to be checked. If the port is open then the connect() command will succeed and a connection will be established. If the port is closed the connect() function would simply timeout in the connection attempt.</p>
<p><span id="more-52"></span></p>
<p>The simple steps would be :<br />
1. Start a loop for the port number range to be scanned.<br />
2. Create a Socket inside the loop.<br />
3. Call the connect function using the socket and the port number to connect to the host.<br />
4. If connect returns SOCKET_ERROR then the connection failed hence port closed, otherwise connection established and port open.</p>
<p>The following code does the same. It should be noted that it scans only TCP ports. For a linux version of the same code view this <a href="http://prasshhant.blogspot.com/2009/04/tcp-connect-port-scanner-with-linux.html">post</a>.</p>
<p><strong>Code</strong> :</p>
<pre class="brush: cpp;">
/*
 TCP Connect portscanner with winsock
*/

#include&lt;stdio.h&gt;
#include&lt;winsock2.h&gt;
#pragma comment(lib, &quot;ws2_32.lib&quot;); //To link the winsock library  

int main(int argc, char **argv)
{
 WSADATA firstsock;
 SOCKET s;
 struct hostent *host;
 int err,i, startport , endport;
 struct sockaddr_in sa; //this stores the destination address
 char hostname[100];

 strncpy((char *)&amp;sa,&quot;&quot;,sizeof sa);
 sa.sin_family = AF_INET; //this line must be like this coz internet

 //Initialise winsock
 if (WSAStartup(MAKEWORD(2,0),&amp;firstsock) != 0)  //CHECKS FOR WINSOCK VERSION 2.0
 {
  fprintf(stderr,&quot;WSAStartup() failed&quot;); //print formatted data specify stream and options
  exit(EXIT_FAILURE);        //or exit(1);
 } 

 printf(&quot;Enter hostname or ip to scan : &quot;);
 gets(hostname);

 printf(&quot;Enter starting port : &quot;);
 scanf(&quot;%d&quot; , &amp;startport);

 printf(&quot;Enter ending port : &quot;);
 scanf(&quot;%d&quot; , &amp;endport);

 if(isdigit(hostname[0]))
 {
  printf(&quot;Doing inet_addr...&quot;);
  sa.sin_addr.s_addr = inet_addr(hostname); //get ip into s_addr
  printf(&quot;Done\n&quot;);
 }
 else if( (host=gethostbyname(hostname)) != 0)
 {
  printf(&quot;Doing gethostbyname()...&quot;);
  strncpy((char *)&amp;sa.sin_addr , (char *)host-&gt;h_addr_list[0] , sizeof sa.sin_addr);
  printf(&quot;Done\n&quot;);
 }
 else
 {
    printf(&quot;Error resolving hostname&quot;);
       exit(EXIT_FAILURE);
 }

 //Start the portscan loop
 printf(&quot;Starting the scan loop...\n&quot;);
 for(i = startport ; i&lt;= endport ; i++)
 {

  s = socket(AF_INET , SOCK_STREAM , 0); //make net a valid socket handle
  if(s &lt; 0)  //if not a socket
  {
   perror(&quot;\nSocket creation failed&quot;);  // perror function prints an error message to stderr
   exit(EXIT_FAILURE);       //or exit(0);
  }

  sa.sin_port = htons(i);
  //connect to the server with that socket
  err = connect(s , (struct sockaddr *)&amp;sa , sizeof sa);

  if(err == SOCKET_ERROR) //connection not accepted
  {
   printf(&quot;%s %-5d Winsock Error Code : %d\n&quot; , hostname , i , WSAGetLastError());
   fflush(stdout);
  }
  else  //connection accepted
  {
   printf(&quot;%s %-5d accepted            \n&quot; , hostname , i);
   if( shutdown( s ,SD_BOTH ) == SOCKET_ERROR )
   {
    perror(&quot;\nshutdown&quot;);// perror function prints an error message to stderr
    exit(EXIT_FAILURE);
   }
  }
  closesocket(s);   //closes the net socket
 }

 fflush(stdout); //clears the contents of a buffer or flushes a stream
 return(0);
}
</pre>
<p>The above can be compiled with vc++ 6.0 for example. Simply create a project and add this file to the project and click run.</p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=52&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/tcp-connect-port-scanner-code-in-c-with-winsock/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Raw Sockets &#8211; Packets with Winpcap</title>
		<link>http://www.binarytides.com/blog/raw-sockets-packets-with-winpcap/</link>
		<comments>http://www.binarytides.com/blog/raw-sockets-packets-with-winpcap/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 09:56:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Winsock]]></category>
		<category><![CDATA[winpcap]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=20</guid>
		<description><![CDATA[A previous post mentions how to send raw packets using winsock api on windows xp. Winpcap is a packet driver useful for packet capturing and sending raw packets on the windows platform.
Raw means we have to cook the whole packet ourselves. A TCP packet for example consists of:
1. Ethernet header
2. IP header
3. TCP header
4. The [...]]]></description>
			<content:encoded><![CDATA[<p>A previous post mentions how to send raw packets using winsock api on windows xp. Winpcap is a packet driver useful for packet capturing and sending raw packets on the windows platform.</p>
<p>Raw means we have to cook the whole packet ourselves. A TCP packet for example consists of:<br />
1. Ethernet header<br />
2. IP header<br />
3. TCP header<br />
4. The data supposed to be send</p>
<p><span id="more-20"></span></p>
<p>Each header has its own job to do in the whole transmission process.</p>
<p>Code :</p>
<pre class="brush: cpp;">
u_char packet[65536];
char *dump = &quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;;
</pre>
<p>Winpcap gives us one function called pcap_sendpacket() to throw the packet on the network  adapter which forwards it. We have to responsibly construct the ethernet , ip and tcp headers and attach the data.</p>
<p>1. Ethernet header looks like</p>
<pre class="brush: cpp;">

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |       Ethernet destination address (first 32 bits)            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | Ethernet dest (last 16 bits)  |Ethernet source (first 16 bits)|
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |       Ethernet source address (last 32 bits)                  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |        Type code              |                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<p>Ethernet destination address is the mac-address of the primary gateway of the network interface being used.<br />
Ethernet source is the mac-address of the network interface itself.<br />
Type field determines the type of the packet e.g. IP , ARP etc.</p>
<p>Now our first task is to get the source and destination mac address.<br />
Winpcap gives the ip-addresses of all available network interfaces that can be used.</p>
<p>now if srcip has the source ip in in_addr or long format then we can get the mac-address of this ip address using the function</p>
<pre class="brush: cpp;">

GetMacAddress(s_mac , srcip);
printf(&quot;Selected device has mac address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X&quot;,s_mac[0],s_mac[1],s_mac[2],s_mac[3],s_mac[4],s_mac[5]);
</pre>
<p>GetMacAddress is like :</p>
<pre class="brush: cpp;">
void GetMacAddress(unsigned char *mac , in_addr destip) {
    DWORD ret;
    in_addr srcip;
    ULONG MacAddr[2];
    ULONG PhyAddrLen = 6;  /* default to length of six bytes */

    srcip.s_addr=0;

    //Now print the Mac address also
    ret = SendArp(destip , srcip , MacAddr , &amp;PhyAddrLen);
    if(PhyAddrLen) {
        BYTE *bMacAddr = (BYTE *) &amp; MacAddr;
        for (int i = 0; i &lt; (int) PhyAddrLen; i++)
            mac[i] = (char)bMacAddr[i];
    }
}
</pre>
<p>SendArp is the method that is used to retrieve the &#8220;mac-address of a IP&#8221; ;simple!<br />
The above demonstration is mostly self-explaining. We got the mac-address of the network interface we want to use. Next we need the IP address of the primary gateway of this interface and then it mac-address.</p>
<p>GetGateway gets the gateway :</p>
<pre class="brush: cpp;">
void GetGateway(struct in_addr ip , char *sgatewayip , int *gatewayip) {
    char pAdapterInfo[5000];
    PIP_ADAPTER_INFO  AdapterInfo;
    ULONG OutBufLen = sizeof(pAdapterInfo) ;

    GetAdaptersInfo((PIP_ADAPTER_INFO) pAdapterInfo, &amp;OutBufLen);
    for(AdapterInfo = (PIP_ADAPTER_INFO)pAdapterInfo; AdapterInfo ; AdapterInfo = AdapterInfo-&gt;Next) {
        if(ip.s_addr == inet_addr(AdapterInfo-&gt;IpAddressList.IpAddress.String))
     strcpy(sgatewayip , AdapterInfo-&gt;GatewayList.IpAddress.String);
    }
    *gatewayip = inet_addr(sgatewayip);
}
</pre>
<p>GetAdaptersInfo is the function that retrieves a lot of information about a adapter.<br />
This and SendArp are inside iphlpapi.dll ; IP helper api which we shall load and get the function pointers inside!</p>
<p>Buzz!</p>
<pre class="brush: cpp;">
void loadiphlpapi() {
    HINSTANCE hDll = LoadLibrary(&quot;iphlpapi.dll&quot;);

    GetAdaptersInfo = (pgetadaptersinfo)GetProcAddress(hDll,&quot;GetAdaptersInfo&quot;);
    if(GetAdaptersInfo==NULL)
        printf(&quot;Error in iphlpapi.dll%d&quot;,GetLastError());
    SendArp = (psendarp)GetProcAddress(hDll,&quot;SendARP&quot;);
    if(SendArp==NULL)
 printf(&quot;Error in iphlpapi.dll%d&quot;,GetLastError());
}
</pre>
<p>So by now the source-ip , its mac-address , primary-gateway-mac should be into their respective variables. So now we have enough information to build our ethernet header.</p>
<p>Enjoy!</p>
<pre class="brush: cpp;">
ETHER_HDR *ehdr;
    memcpy(ehdr-&gt;source , s_mac , 6); //Source Mac address
    memcpy(ehdr-&gt;dest,d_mac,6); //Destination MAC address
    ehdr-&gt;type = htons(0x0800); //IP Frames
</pre>
<p>Next comes the IP Header</p>
<p>RFC 791 gives the structure of an IP header as:</p>
<pre class="brush: cpp;">
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<p>and our structure for this header :</p>
<pre class="brush: cpp;">
typedef struct ip_hdr
{
    unsigned char  ip_header_len:4;  // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
    unsigned char  ip_version   :4;  // 4-bit IPv4 version
    unsigned char  ip_tos;           // IP type of service
    unsigned short ip_total_length;  // Total length
    unsigned short ip_id;            // Unique identifier 

    unsigned char  ip_frag_offset   :5;        // Fragment offset field

    unsigned char  ip_more_fragment :1;
    unsigned char  ip_dont_fragment :1;
    unsigned char  ip_reserved_zero :1;

    unsigned char  ip_frag_offset1;    //fragment offset

    unsigned char  ip_ttl;           // Time to live
    unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
    unsigned short ip_checksum;      // IP checksum
    unsigned int   ip_srcaddr;       // Source address
    unsigned int   ip_destaddr;      // Source address
}   IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR , IPHeader;
</pre>
<p>and then the TCP Header</p>
<pre class="brush: cpp;">
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<p>and our structure for this header :</p>
<pre class="brush: cpp;">
// TCP header
typedef struct tcp_header
{
 unsigned short source_port;   // source port
 unsigned short dest_port;     // destination port
 unsigned int sequence;        // sequence number - 32 bits
 unsigned int acknowledge;     // acknowledgement number - 32 bits

 unsigned char ns :1;          //Nonce Sum Flag Added in RFC 3540.
 unsigned char reserved_part1:3; //according to rfc
 unsigned char data_offset:4;    /*The number of 32-bit words
                                   in the TCP header.
                                   This indicates where the data begins.
                                   The length of the TCP header
                                   is always a multiple
                                   of 32 bits.*/

 unsigned char fin :1; //Finish Flag
 unsigned char syn :1; //Synchronise Flag
 unsigned char rst :1; //Reset Flag
 unsigned char psh :1; //Push Flag
 unsigned char ack :1; //Acknowledgement Flag
 unsigned char urg :1; //Urgent Flag

 unsigned char ecn :1; //ECN-Echo Flag
 unsigned char cwr :1; //Congestion Window Reduced Flag

 ////////////////////////////////

 unsigned short window; // window
 unsigned short checksum; // checksum
 unsigned short urgent_pointer; // urgent pointer
} TCP_HDR , *PTCP_HDR , FAR * LPTCP_HDR , TCPHeader , TCP_HEADER;
</pre>
<p>Now the headers can be build easily :</p>
<pre class="brush: cpp;">
// *******************  IP Header *****************
    iphdr = (PIPV4_HDR)(packet + sizeof(ETHER_HDR));

    iphdr-&gt;ip_version = 4;
    iphdr-&gt;ip_header_len = 5; //In double words thats 4 bytes
    iphdr-&gt;ip_tos = 0;
    iphdr-&gt;ip_total_length = htons (sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));
    iphdr-&gt;ip_id = htons(2);
    iphdr-&gt;ip_frag_offset = 0;
    iphdr-&gt;ip_reserved_zero=0;
    iphdr-&gt;ip_dont_fragment=1;
    iphdr-&gt;ip_more_fragment=0;
    iphdr-&gt;ip_frag_offset1 = 0;
    iphdr-&gt;ip_ttl    = 3;
    iphdr-&gt;ip_protocol = IPPROTO_TCP;
    iphdr-&gt;ip_srcaddr  = inet_addr(&quot;1.2.3.4&quot;);   //srcip.s_addr;
    iphdr-&gt;ip_destaddr = inet_addr(&quot;1.2.3.5&quot;);
    iphdr-&gt;ip_checksum =0;
    iphdr-&gt;ip_checksum = in_checksum((unsigned short*)iphdr, sizeof(IPV4_HDR));

    // *******************  TCP Header *****************
    tcphdr = (PTCP_HDR)(packet + sizeof(ETHER_HDR) + sizeof(IPV4_HDR));

    tcphdr-&gt;source_port = htons(SOURCE_PORT);
    tcphdr-&gt;dest_port = htons(80);
    tcphdr-&gt;sequence=0;
    tcphdr-&gt;acknowledge=0;
    tcphdr-&gt;reserved_part1=0;
    tcphdr-&gt;data_offset=5;
    tcphdr-&gt;fin=0;
    tcphdr-&gt;syn=1;
    tcphdr-&gt;rst=0;
    tcphdr-&gt;psh=0;
    tcphdr-&gt;ack=0;
    tcphdr-&gt;urg=0;
    tcphdr-&gt;ecn=0;
    tcphdr-&gt;cwr=0;
    tcphdr-&gt;window = htons(64240);
    tcphdr-&gt;checksum=0;
    tcphdr-&gt;urgent_pointer = 0;
</pre>
<p>almost done</p>
<pre class="brush: cpp;">
data = (char*)(packet + sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR));
strcpy(data,dump);

pcap_sendpacket(fp , packet , sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));
</pre>
<p>Thats should send the packet. Use Ethereal to check whether the packet was successfully transmitted. The above was an example of a TCP packet, similarly UDP ICMP or any other packet can be build.</p>
<p><strong>Source Code</strong> : <a href="http://www.binarytides.com/download/raw-sockets-packets-with-winpcap/"><br />
Download<br />
</a></p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=20&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/raw-sockets-packets-with-winpcap/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Tcp Syn Portscan with Winpcap and Raw Sockets</title>
		<link>http://www.binarytides.com/blog/tcp-syn-portscan-with-winpcap-and-raw-sockets/</link>
		<comments>http://www.binarytides.com/blog/tcp-syn-portscan-with-winpcap-and-raw-sockets/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 09:35:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Winsock]]></category>
		<category><![CDATA[winpcap]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=19</guid>
		<description><![CDATA[Port Scanning searches for open ports on a remote system. The basic logic for a portscanner would be to connect to the port we want to check. If the socket gives a valid connection without any error then the port is open , closed otherwise (or inaccessible, or filtered).

This basic technique is called TCP Connect [...]]]></description>
			<content:encoded><![CDATA[<p>Port Scanning searches for open ports on a remote system. The basic logic for a portscanner would be to connect to the port we want to check. If the socket gives a valid connection without any error then the port is open , closed otherwise (or inaccessible, or filtered).</p>
<p><span id="more-19"></span></p>
<p>This basic technique is called TCP Connect Port Scanning in which we use something like a loop to connect to ports one by one and check for valid connections on the socket. But this technique has many drawbacks.
<div>It is slow as well as detectable. Slow means that it takes some time for connect() function to return and detectable since this technique leaves a lot of entries in the firewall logs of the remote system. </p>
<p>TCP-Syn Port scanning is a technique which intends to cure these two problems. The mechanism behind it is the handshaking which takes place while establishing a connection. It sends syn packets and waits for an syn+ack reply. If such a reply is received then the port is open otherwise keep waiting till timeout and report the port as closed. Quite simple! In the TCP connect technique the connect() function sends a ack after receiving syn+ack and this establishes a complete connection. But in Syn scanning the complete connection is not made. This results in :<br />1. Faster scans<br />2. Incomplete connections so less detectable</p>
<p>TCP Connect Port Scan looks like :</p>
<p>You -> Send Syn packet -> Host:port<br />Host -> send syn/ack packet -> You<br />You -> send ack packet -> Host<br />&#8230; and connection is established</p>
<p>TCP-Syn Port scan looks like<br />You -> send syn packet ->Host:port<br />Host -> send syn/ack or rst packet or nothing depending on the port status -> You<br />&#8230; stop and analyse the reply the host send : if syn/ack then port open closed/filtered otherwise.</p>
<p>Results are almost as accurate as that of TCP connection and the scan is extremely faster.</p>
<p>So the process is :<br />1. Send a Syn packet to a port A<br />2. Wait for a reply of Syn+Ack till timeout<br />3. Syn+Ack reply means the port is open , Rst packet means port is closed , and otherwise it might be inaccessible or in a filtered state.</p>
<p>Coding>></p>
<p>We shall code a TCP-Syn Port scanner on windows using winsock api. The tools we need are :<br />VC++ 6.0 , Winpcap and Ethereal(Optional : for better understanding).</p>
<p>Winpcap is a raw packet driver for windows platform which has features for sniffing(packet capturing) and sending raw packets.</p>
<p><span class="Apple-style-span" style="font-weight: bold;">Now onto the program logic.</span></p>
<p>1. Take  a hostname to scan.<br />2. Start a sniffer thread of winpcap sniffer which shall sniff for all incoming packets and pick up those which are from hostname and are syn+ack packets.<br />3. start sending syn packets to ports in a loop. to make syn packets we need raw packet feature of winpcap</div>
<div>4. if the sniffer thread receives a syn/ack packet from the host then get the source port of the packet and report the packet as open.</div>
<div>5. Keep looping as long as you have nothing else to do.</div>
<div></div>
<div><span class="Apple-style-span" style="font-weight: bold;">The Code</span></div>
<div><span class="Apple-style-span" style="font-weight: bold;"><br /></span></div>
<div>Coming Soon&#8230;</div>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=19&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/tcp-syn-portscan-with-winpcap-and-raw-sockets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DNS Query Code in C with winsock and linux sockets</title>
		<link>http://www.binarytides.com/blog/dns-query-code-in-c-with-winsock-and-linux-sockets/</link>
		<comments>http://www.binarytides.com/blog/dns-query-code-in-c-with-winsock-and-linux-sockets/#comments</comments>
		<pubDate>Mon, 19 Mar 2007 12:03:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Winsock]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=7</guid>
		<description><![CDATA[Introduction
Its no new fact that when we type a web address in our browser a dns request is immediately send by our browser to a DNS server to get the IP address of that web address.In winsock applications we achieve this by gethostbyname() and things are pretty simple.In this article we shall do this simple [...]]]></description>
			<content:encoded><![CDATA[<h4>Introduction</h4>
<p>Its no new fact that when we type a web address in our browser a dns request is immediately send by our browser to a DNS server to get the IP address of that web address.In winsock applications we achieve this by gethostbyname() and things are pretty simple.In this article we shall do this simple thing without the help of gethostbyname().We shall be sending DNS queries and receive the reply and extract the ipv4 address of the specified hostname.</p>
<p><span id="more-7"></span></p>
<p>RFC 1035 shows the structure of DNS message as follows</p>
<pre class="brush: cpp;">

+---------------------+
| Header              |
+---------------------+
| Question            | the question for the name server
+---------------------+
| Answer              | RRs answering the question
+---------------------+
| Authority           | RRs pointing toward an authority
+---------------------+
| Additional          | RRs holding additional information
+---------------------+
</pre>
<p>Pretty simple to understand that queries wont have the answer, authority and additional fields.Packets are ofcourse UDP and DNS servers feel comfortable to operate on port 53. So the first thing is to send a query containing the hostname.</p>
<p>Next task is to receive the reply which is expected to contain the information we are expecting. DNS queries are used for a variety of purpose. Apart from getting the ipv4 address of a host we also use DNS for getting the mail exchange/server of a specified domain and etc. All type of queries and response packets are build nearly on the same structure depicted above.</p>
<p>When a DNS server replies it sends the question as it is and along with that are a bunch of RR’s or resource records.All RR’s stand in a queue and certain fields of the header tell that how many of the RR’s are answers , how many authority and how many additionals.</p>
<p>This is the structure of a DNS header :</p>
<pre class="brush: cpp;">

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     ID                        |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode    |AA|TC|RD|RA| Z      |  RCODE    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                   QDCOUNT                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                   ANCOUNT                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                   NSCOUNT                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                   ARCOUNT                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p><span style="color: #ff6666;">ID :the identifier</span><br />
<span style="color: #ff6666;">QDCOUNT : how many question are there in the packet.</span><br />
<span style="color: #ff6666;">ANCOUNT : how many answers in the RR queue.</span><br />
<span style="color: #ff6666;">NSCOUNT : Authority RR count</span><br />
<span style="color: #ff6666;">ARCOUNT : Additional Count</span></p>
<p>for explanation of the other fields lookup the RFC</p>
<p>A DNS packet typically looks like this Header-Query-RR-RR-RR-RR-RR-RR<span style="font-weight: bold;">&#8230;&#8230;..……..</span></p>
<p>A Query structure looks like this</p>
<pre class="brush: cpp;">

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                                               |
/                    QNAME                      /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QTYPE                      |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QCLASS                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p>Note : QNAME is a variable length field to fit the hostname<br />
QCLASS should be 1 since we are on internet<br />
QTYPE determines what you want to know ;  ipv4 address , mx etc.</p>
<p>Resource Record(RR) field looks like this</p>
<pre class="brush: cpp;">

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                                               |
/                                               /
/                     NAME                      /
|                                               |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     TYPE                      |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     CLASS                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                     TTL                       |
|                                               |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  RDLENGTH                     |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/                     RDATA                     /
/                                               /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
</pre>
<p>Note again : NAME and RDATA are variable length field</p>
<p>Type field tells how RDATA relates to NAME. e.g. if TYPE is 1 then RDATA<br />
contains the ipv4 address of the NAME.</p>
<p>That’s all about the structures we need.</p>
<p>Now some more food for thought:</p>
<p>1. In DNS query and responses www.google.com is represented as<br />
3www6google3com0 &lt;&lt;hope you got it <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
if u didnt get that send me a mail <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>2. And there is a compression scheme followed which is like this -&gt; if<br />
google.com were to occur 10 times in the packet then it will written as<br />
google.com for the first time and after that a pointer will be placed at every<br />
next occurence of google.com to the position offset of the beginning of the<br />
first occurence.The starting of the dns header being the offset 0. For example<br />
if www.google.com is written starting at a offset of say 12 and some where later<br />
ns.google.com is to be written then it will be written as ns.16 which means<br />
point to offset 16(where g of google is).To implement this pointer technique 2<br />
bytes are used where the first 2 bits are 1 and the rest 14 bits are the<br />
offset.so for 16 as offset the number u wud need is 1100000000000000 + 1000 &lt;&lt;thats<br />
it.</p>
<h4><span style="color: #3333ff;">Code</span></h4>
<p>The structure for DNS header</p>
<pre class="brush: cpp;">

typedef struct
{
unsigned short id;       // identification number
unsigned char rd :1;     // recursion desired
unsigned char tc :1;     // truncated message
unsigned char aa :1;     // authoritive answer
unsigned char opcode :4; // purpose of message
unsigned char qr :1;     // query/response flag
unsigned char rcode :4;  // response code
unsigned char cd :1;     // checking disabled
unsigned char ad :1;     // authenticated data
unsigned char z :1;      // its z! reserved
unsigned char ra :1;     // recursion available
unsigned short q_count;  // number of question entries
unsigned short ans_count; // number of answer entries
unsigned short auth_count; // number of authority entries
unsigned short add_count; // number of resource entries
} DNS_HEADER;
</pre>
<p>Structure for the query ( we wont keep the name in this structure since size<br />
is variable)</p>
<pre class="brush: cpp;">
typedef struct
{
unsigned short qtype;
unsigned short qclass;
} QUESTION;
</pre>
<p>Resource Record</p>
<pre class="brush: cpp;">

typedef struct
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
} R_DATA;
</pre>
<p>Once again name and rdata have been kept out.<br />
These two structures will help</p>
<pre class="brush: cpp;">

typedef struct
{
unsigned char *name;
R_DATA *resource;
unsigned char *rdata;
} RES_RECORD;

typedef struct
{
unsigned char *name;
QUESTION *ques;
} QUERY;
</pre>
<p>The working will be like</p>
<pre class="brush: cpp;">
SOCKET s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //UDP packet for DNS queries
RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
sockaddr_in dest;

dest.sin_family=AF_INET;

dest.sin_port=htons(53);
dest.sin_addr.s_addr=inet_addr(dns_servers[0]); //use the first dns server

unsigned char buf[65536],*qname,*reader;
DNS_HEADER *dns = NULL;
QUESTION *qinfo = NULL;

//Set the DNS structure to standard queries
dns=(DNS_HEADER*)&amp;buf;

//set up the header
dns-&gt;id = (unsigned short)htons(GetCurrentProcessId());
dns-&gt;qr = 0; //This is a query
dns-&gt;opcode = 0; //This is a standard query
dns-&gt;aa = 0; //Not Authoritative
dns-&gt;tc = 0; //This message is not truncated
dns-&gt;rd = 1; //Recursion Desired
dns-&gt;ra = 0; //Recursion not available! hey we dont have it (lol)
dns-&gt;z = 0;
dns-&gt;ad = 0;
dns-&gt;cd = 0;
dns-&gt;rcode = 0;
dns-&gt;q_count = htons(1); //we have only 1 question
dns-&gt;ans_count = 0;
dns-&gt;auth_count = 0;
dns-&gt;add_count = 0;

//point to the query portion
qname =(unsigned char*)&amp;buf[sizeof(DNS_HEADER)];
ChangetoDnsNameFormat(qname,host);

qinfo =(QUESTION*)&amp;buf[sizeof(DNS_HEADER) + (strlen((const char*)qname) + 1)];

//fill it
qinfo-&gt;qtype = htons(1); //we are requesting the ipv4 address
qinfo-&gt;qclass = htons(1); //its internet (lol)

sendto(s,(char*)buf,sizeof(DNS_HEADER) + (strlen((const char*)qname)+1) +
sizeof(QUESTION),0,(sockaddr*)&amp;dest,sizeof(dest))==SOCKET_ERROR)
int i=sizeof(dest);
recvfrom (s,(char*)buf,65536,0,(sockaddr*)&amp;dest,&amp;amp;i);
dns=(DNS_HEADER*)buf;

//move ahead of the dns header and the query field
reader=&amp;buf[sizeof(DNS_HEADER) + (strlen((const char*)qname)+1) +
sizeof(QUESTION)];

printf(&quot;nThe response contains : &quot;);
printf(&quot;n %d Questions.&quot;,ntohs(dns-&gt;q_count));
printf(&quot;n %d Answers.&quot;,ntohs(dns-&gt;ans_count));
printf(&quot;n %d Authoritative Servers.&quot;,ntohs(dns-&gt;auth_count));
printf(&quot;n %d Additional records.nn&quot;,ntohs(dns-&gt;add_count));

//reading answers
int stop=0;
for(i=0;i&lt;ntohs(dns-&gt;ans_count);i++)
{
answers[i].name=ReadName(reader,buf,stop);
reader+=stop;
answers[i].resource=(R_DATA*)(reader);
reader+=sizeof(R_DATA);
if(ntohs(answers[i].resource-&gt;type)==1)
{
    answers[i].rdata=new unsigned char[ntohs(answers[i].resource-&gt;data_len)];
    for(int j=0;j&lt;ntohs(answers[i].resource-&gt;data_len);j++)
        answers[i].rdata[j]=reader[j];
    answers[i].rdata[ntohs(answers[i].resource-&gt;data_len)]='';
    reader+=ntohs(answers[i].resource-&gt;data_len);
}
else
{
    answers[i].rdata=ReadName(reader,buf,stop);
    reader+=stop;
}
}
</pre>
<p>and so on&#8230;.<br />
The IP address in the rdata section will be as numbers which must be converted<br />
to a string and then to the dotted format using inet_ntoa like this</p>
<pre class="brush: cpp;">
sockaddr_in a;
long *p;
p=(long*)addit[i].rdata;
a.sin_addr.s_addr=(*p);
printf(&quot;has IPv4 address : %s&quot;,inet_ntoa(a.sin_addr));
</pre>
<p>Authority RR’s and Additional RR’s need to be read just like we read Answer<br />
RR’s ChangetoDnsNameFormat(qname,host) function will convert the normal<br />
www.google.com in host to 3www6google3com0 and store the result in qname.</p>
<p>The ReadName() functions reads a NAME for query and RR blocks keeping in mind<br />
the compression strategy.</p>
<p>Another function RetrieveDnsServersFromRegistry() in dns.cpp retrieves the DNS<br />
server IP’s stored in the system. DNS servers are stored in the registry.<br />
HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces<br />
contains the subkeys for the interfaces and each may contain a field called<br />
nameserver whose value will have the dns server fed by either you or stored<br />
dynamically in case of dialup connections.multiple DNS ip’s may be present in<br />
one nameserver entry and then they are separated by a comma or simply a space.</p>
<p><span class="messagetitle">dfelippa read this post on codeproject and suggested and made some improvements to the code which include :</span></p>
<p><span class="messagetitle">1. Better memory management<br />
2. Support for MX Query</span></p>
<p><span class="messagetitle">He modified the code and put it up at :</span></p>
<p><span class="messagetitle">http://www.infologika.com.br/public/dnsquery_main.cpp</span></p>
<p><span class="messagetitle">Check it out!<br />
</span></p>
<p><strong>Source Code :</strong><br />
Windows :</p>
<pre class="brush: cpp;">
//DNS Query Program
//Author : Prasshhant Pugalia (prasshhant.p@gmail.com)
//Dated : 26/2/2007

//Header Files
#include &quot;winsock2.h&quot;
#include &quot;windows.h&quot;
#include &quot;stdio.h&quot;
#include &quot;conio.h&quot;

#pragma comment(lib,&quot;ws2_32.lib&quot;) //Winsock Library

//List of DNS Servers registered on the system
char dns_servers[10][100];

//Type field of Query and Answer
#define T_A 1 /* host address */
#define T_NS 2 /* authoritative server */
#define T_CNAME 5 /* canonical name */
#define T_SOA 6 /* start of authority zone */
#define T_PTR 12 /* domain name pointer */
#define T_MX 15 /* mail routing information */

//Function Prototypes
void ngethostbyname (unsigned char*);
void ChangetoDnsNameFormat (unsigned char*,unsigned char*);
unsigned char* ReadName (unsigned char*,unsigned char*,int*);
void RetrieveDnsServersFromRegistry(void);
unsigned char* PrepareDnsQueryPacket (unsigned char*);

//DNS header structure
struct DNS_HEADER
{
unsigned short id; // identification number

unsigned char rd :1; // recursion desired
unsigned char tc :1; // truncated message
unsigned char aa :1; // authoritive answer
unsigned char opcode :4; // purpose of message
unsigned char qr :1; // query/response flag

unsigned char rcode :4; // response code
unsigned char cd :1; // checking disabled
unsigned char ad :1; // authenticated data
unsigned char z :1; // its z! reserved
unsigned char ra :1; // recursion available

unsigned short q_count; // number of question entries
unsigned short ans_count; // number of answer entries
unsigned short auth_count; // number of authority entries
unsigned short add_count; // number of resource entries
};

//Constant sized fields of query structure
struct QUESTION
{
unsigned short qtype;
unsigned short qclass;
};

//Constant sized fields of the resource record structure
#pragma pack(push, 1)
struct R_DATA
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack(pop)

//Pointers to resource record contents
struct RES_RECORD
{
unsigned char *name;
struct R_DATA *resource;
unsigned char *rdata;
};

//Structure of a Query
typedef struct
{
unsigned char *name;
struct QUESTION *ques;
} QUERY;

int main() //do you know what is int main() ?
{
unsigned char hostname[100];

WSADATA firstsock;

RetrieveDnsServersFromRegistry();

printf(&quot;\nInitialising Winsock...&quot;);
if (WSAStartup(MAKEWORD(2,2),&amp;firstsock) != 0)
{
printf(&quot;Failed. Error Code : %d&quot;,WSAGetLastError());
return 1;
}
printf(&quot;Initialised.&quot;);

printf(&quot;\nEnter Hostname to Lookup : &quot;);
gets((char*)hostname);
ngethostbyname(hostname);

_getch();
return 0;
}

void ngethostbyname(unsigned char *host)
{
unsigned char buf[65536],*qname,*reader;
int i , j , stop;

SOCKET s;
struct sockaddr_in a;

struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
struct sockaddr_in dest;

struct DNS_HEADER *dns = NULL;
struct QUESTION *qinfo = NULL;

s = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //UDP packet for DNS queries

dest.sin_family=AF_INET;
dest.sin_port=htons(53);
dest.sin_addr.s_addr=inet_addr(dns_servers[0]); //dns servers

//Set the DNS structure to standard queries
dns = (struct DNS_HEADER *)&amp;buf;

dns-&gt;id = (unsigned short) htons(GetCurrentProcessId());
dns-&gt;qr = 0; //This is a query
dns-&gt;opcode = 0; //This is a standard query
dns-&gt;aa = 0; //Not Authoritative
dns-&gt;tc = 0; //This message is not truncated
dns-&gt;rd = 1; //Recursion Desired
dns-&gt;ra = 0; //Recursion not available! hey we dont have it (lol)
dns-&gt;z = 0;
dns-&gt;ad = 0;
dns-&gt;cd = 0;
dns-&gt;rcode = 0;
dns-&gt;q_count = htons(1); //we have only 1 question
dns-&gt;ans_count = 0;
dns-&gt;auth_count = 0;
dns-&gt;add_count = 0;

//point to the query portion
qname =(unsigned char*)&amp;buf[sizeof(struct DNS_HEADER)];

ChangetoDnsNameFormat(qname,host);
qinfo =(struct QUESTION*)&amp;buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it

qinfo-&gt;qtype = htons(1); //we are requesting the ipv4 address
qinfo-&gt;qclass = htons(1); //its internet (lol)

printf(&quot;\nSending Packet...&quot;);
if(sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&amp;dest,sizeof(dest))==SOCKET_ERROR)
{
printf(&quot;%d error&quot;,WSAGetLastError());
}
printf(&quot;Sent&quot;);

i=sizeof(dest);
printf(&quot;\nReceiving answer...&quot;);
if(recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&amp;dest,&amp;i)==SOCKET_ERROR)
{
printf(&quot;Failed. Error Code : %d&quot;,WSAGetLastError());
}
printf(&quot;Received.&quot;);

dns=(struct DNS_HEADER*)buf;

//move ahead of the dns header and the query field
reader=&amp;buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];

printf(&quot;\nThe response contains : &quot;);
printf(&quot;\n %d Questions.&quot;,ntohs(dns-&gt;q_count));
printf(&quot;\n %d Answers.&quot;,ntohs(dns-&gt;ans_count));
printf(&quot;\n %d Authoritative Servers.&quot;,ntohs(dns-&gt;auth_count));
printf(&quot;\n %d Additional records.\n\n&quot;,ntohs(dns-&gt;add_count));

//reading answers
stop=0;

for(i=0;i&lt;ntohs(dns-&gt;ans_count);i++)
{
answers[i].name=ReadName(reader,buf,&amp;stop);
reader = reader + stop;

answers[i].resource = (struct R_DATA*)(reader);
reader = reader + sizeof(struct R_DATA);

if(ntohs(answers[i].resource-&gt;type) == 1) //if its an ipv4 address
{
answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource-&gt;data_len));

for(j=0 ; j&lt;ntohs(answers[i].resource-&gt;data_len) ; j++)
answers[i].rdata[j]=reader[j];

answers[i].rdata[ntohs(answers[i].resource-&gt;data_len)] = '\0';

reader = reader + ntohs(answers[i].resource-&gt;data_len);

}
else
{
answers[i].rdata = ReadName(reader,buf,&amp;stop);
reader = reader + stop;
}

}

//read authorities
for(i=0;i&lt;ntohs(dns-&gt;auth_count);i++)
{
auth[i].name=ReadName(reader,buf,&amp;stop);
reader+=stop;

auth[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

auth[i].rdata=ReadName(reader,buf,&amp;stop);
reader+=stop;
}

//read additional
for(i=0;i&lt;ntohs(dns-&gt;add_count);i++)
{
addit[i].name=ReadName(reader,buf,&amp;stop);
reader+=stop;

addit[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

if(ntohs(addit[i].resource-&gt;type)==1)
{
addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource-&gt;data_len));
for(j=0;j&lt;ntohs(addit[i].resource-&gt;data_len);j++)
addit[i].rdata[j]=reader[j];

addit[i].rdata[ntohs(addit[i].resource-&gt;data_len)]='\0';
reader+=ntohs(addit[i].resource-&gt;data_len);

}
else
{
addit[i].rdata=ReadName(reader,buf,&amp;stop);
reader+=stop;
}
}

//print answers
for(i=0;i&lt;ntohs(dns-&gt;ans_count);i++)
{
//printf(&quot;\nAnswer : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,answers[i].name);

if(ntohs(answers[i].resource-&gt;type)==1) //IPv4 address
{

long *p;
p=(long*)answers[i].rdata;
a.sin_addr.s_addr=(*p); //working without ntohl
printf(&quot;has IPv4 address : %s&quot;,inet_ntoa(a.sin_addr));
}
if(ntohs(answers[i].resource-&gt;type)==5) //Canonical name for an alias
printf(&quot;has alias name : %s&quot;,answers[i].rdata);

printf(&quot;\n&quot;);
}

//print authorities
for(i=0;i&lt;ntohs(dns-&gt;auth_count);i++)
{
//printf(&quot;\nAuthorities : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,auth[i].name);
if(ntohs(auth[i].resource-&gt;type)==2)
printf(&quot;has authoritative nameserver : %s&quot;,auth[i].rdata);
printf(&quot;\n&quot;);
}

//print additional resource records
for(i=0;i&lt;ntohs(dns-&gt;add_count);i++)
{
//printf(&quot;\nAdditional : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,addit[i].name);
if(ntohs(addit[i].resource-&gt;type)==1)
{
long *p;
p=(long*)addit[i].rdata;
a.sin_addr.s_addr=(*p); //working without ntohl
printf(&quot;has IPv4 address : %s&quot;,inet_ntoa(a.sin_addr));
}
printf(&quot;\n&quot;);
}

return;
}

unsigned char* ReadName(unsigned char* reader,unsigned char* buffer,int* count)
{
unsigned char *name;
unsigned int p=0,jumped=0,offset;
int i , j;

*count = 1;
name = (unsigned char*)malloc(256);

name[0]='\0';

//read the names in 3www6google3com format
while(*reader!=0)
{
if(*reader&gt;=192)
{
offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
reader = buffer + offset - 1;
jumped = 1; //we have jumped to another location so counting wont go up!
}
else
name[p++]=*reader;

reader=reader+1;

if(jumped==0) *count = *count + 1; //if we havent jumped to another location then we can count up
}

name[p]='\0'; //string complete
if(jumped==1) *count = *count + 1; //number of steps we actually moved forward in the packet

//now convert 3www6google3com0 to www.google.com
for(i=0;i&lt;(int)strlen((const char*)name);i++)
{
p=name[i];
for(j=0;j&lt;(int)p;j++)
{
name[i]=name[i+1];
i=i+1;
}
name[i]='.';
}
name[i-1]='\0'; //remove the last dot
return name;
}

//Retrieve the DNS servers from the registry
void RetrieveDnsServersFromRegistry()
{
HKEY hkey=0;
char name[256];
char *path=&quot;SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces&quot;;
char *fullpath[256];
unsigned long s=sizeof(name);
int dns_count=0 , err , i , j;
HKEY inter;
unsigned long count;

//Open the registry folder
RegOpenKeyEx(HKEY_LOCAL_MACHINE , path , 0 , KEY_READ , &amp;hkey );

//how many interfaces
RegQueryInfoKey(hkey, 0 , 0 , 0 , &amp;count , 0 , 0 , 0 , 0 , 0 , 0 , 0 );

for(i=0;i&lt;count;i++)
{
s=256;
//Get the interface subkey name
RegEnumKeyEx(hkey , i , (char*)name , &amp;s , 0 , 0 , 0 , 0 );

//Make the full path
strcpy((char*)fullpath,path);
strcat((char*)fullpath,&quot;\\&quot;);
strcat((char*)fullpath,name);

//Open the full path name
RegOpenKeyEx(HKEY_LOCAL_MACHINE , (const char*)fullpath , 0 , KEY_READ , &amp;inter );

//Extract the value in Nameserver field
s=256;
err=RegQueryValueEx(inter , &quot;NameServer&quot; , 0 , 0 , (unsigned char*)name , &amp;s );

if(err==ERROR_SUCCESS &amp;&amp; strlen(name)&gt;0) strcpy(dns_servers[dns_count++],name);
}

for(i=0;i&lt;dns_count;i++)
{
for(j=0;j&lt;strlen(dns_servers[i]);j++)
{
if(dns_servers[i][j]==',' || dns_servers[i][j]==' ')
{
strcpy(dns_servers[dns_count++],dns_servers[i]+j+1);
dns_servers[i][j]=0;
}
}
}

printf(&quot;\nThe following DNS Servers were found on your system...&quot;);
for(i=0;i&lt;dns_count;i++)
{
printf(&quot;\n%d) %s&quot;,i+1,dns_servers[i]);
}
}

//this will convert www.google.com to 3www6google3com ;got it <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host)
{
int lock=0 , i;

strcat((char*)host,&quot;.&quot;);

for(i=0;i&lt;(int)strlen((char*)host);i++)
{
if(host[i]=='.')
{
*dns++=i-lock;
for(;lock&lt;i;lock++)
{
*dns++=host[lock];
}
lock++; //or lock=i+1;
}
}
*dns++='\0';
}
</pre>
<p><strong>Linux</strong> :</p>
<pre class="brush: cpp;">
//DNS Query Program on Linux
//Author : Prasshhant Pugalia (prasshhant.p@gmail.com)
//Dated : 29/4/2009

//Header Files
#include&lt;stdio.h&gt;
#include&lt;sys/socket.h&gt;
#include&lt;netinet/in.h&gt;

//List of DNS Servers registered on the system
char dns_servers[10][100];

//Type field of Query and Answer
#define T_A 1 /* host address */
#define T_NS 2 /* authoritative server */
#define T_CNAME 5 /* canonical name */
#define T_SOA 6 /* start of authority zone */
#define T_PTR 12 /* domain name pointer */
#define T_MX 15 /* mail routing information */

//Function Prototypes
void ngethostbyname (unsigned char*);
void ChangetoDnsNameFormat (unsigned char*,unsigned char*);
unsigned char* ReadName (unsigned char*,unsigned char*,int*);
void get_dns_servers();

//DNS header structure
struct DNS_HEADER
{
unsigned short id; // identification number

unsigned char rd :1; // recursion desired
unsigned char tc :1; // truncated message
unsigned char aa :1; // authoritive answer
unsigned char opcode :4; // purpose of message
unsigned char qr :1; // query/response flag

unsigned char rcode :4; // response code
unsigned char cd :1; // checking disabled
unsigned char ad :1; // authenticated data
unsigned char z :1; // its z! reserved
unsigned char ra :1; // recursion available

unsigned short q_count; // number of question entries
unsigned short ans_count; // number of answer entries
unsigned short auth_count; // number of authority entries
unsigned short add_count; // number of resource entries
};

//Constant sized fields of query structure
struct QUESTION
{
unsigned short qtype;
unsigned short qclass;
};

//Constant sized fields of the resource record structure
#pragma pack(push, 1)
struct R_DATA
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack(pop)

//Pointers to resource record contents
struct RES_RECORD
{
unsigned char *name;
struct R_DATA *resource;
unsigned char *rdata;
};

//Structure of a Query
typedef struct
{
unsigned char *name;
struct QUESTION *ques;
} QUERY;

int main()
{
unsigned char hostname[100];

//Get the DNS servers from the resolv.conf file
get_dns_servers();
//Get the hostname
printf(&quot;\nEnter Hostname to Lookup : &quot;);
gets((char*)hostname);
//Now get the ip of this hostname
ngethostbyname(hostname);

return 0;
}

void ngethostbyname(unsigned char *host)
{
unsigned char buf[65536],*qname,*reader;
int i , j , stop , s;

struct sockaddr_in a;

struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
struct sockaddr_in dest;

struct DNS_HEADER *dns = NULL;
struct QUESTION *qinfo = NULL;

s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries

dest.sin_family = AF_INET;
dest.sin_port = htons(53);
dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers

//Set the DNS structure to standard queries
dns = (struct DNS_HEADER *)&amp;buf;

dns-&gt;id = (unsigned short) htons(getpid());
dns-&gt;qr = 0; //This is a query
dns-&gt;opcode = 0; //This is a standard query
dns-&gt;aa = 0; //Not Authoritative
dns-&gt;tc = 0; //This message is not truncated
dns-&gt;rd = 1; //Recursion Desired
dns-&gt;ra = 0; //Recursion not available! hey we dont have it (lol)
dns-&gt;z = 0;
dns-&gt;ad = 0;
dns-&gt;cd = 0;
dns-&gt;rcode = 0;
dns-&gt;q_count = htons(1); //we have only 1 question
dns-&gt;ans_count = 0;
dns-&gt;auth_count = 0;
dns-&gt;add_count = 0;

//point to the query portion
qname =(unsigned char*)&amp;buf[sizeof(struct DNS_HEADER)];

ChangetoDnsNameFormat(qname , host);
qinfo =(struct QUESTION*)&amp;buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it

qinfo-&gt;qtype = htons(1); //we are requesting the ipv4 address
qinfo-&gt;qclass = htons(1); //its internet (lol)

printf(&quot;\nSending Packet...&quot;);
if(sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&amp;dest,sizeof(dest)) == 0)
{
printf(&quot;Error sending socket&quot;);
}
printf(&quot;Sent&quot;);

i = sizeof dest;
printf(&quot;\nReceiving answer...&quot;);
if(recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&amp;dest,&amp;i) == 0)
{
printf(&quot;Failed. Error Code &quot;);
}
printf(&quot;Received.&quot;);

dns = (struct DNS_HEADER*) buf;

//move ahead of the dns header and the query field
reader = &amp;buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];

printf(&quot;\nThe response contains : &quot;);
printf(&quot;\n %d Questions.&quot;,ntohs(dns-&gt;q_count));
printf(&quot;\n %d Answers.&quot;,ntohs(dns-&gt;ans_count));
printf(&quot;\n %d Authoritative Servers.&quot;,ntohs(dns-&gt;auth_count));
printf(&quot;\n %d Additional records.\n\n&quot;,ntohs(dns-&gt;add_count));

//reading answers
stop=0;

for(i=0;i&lt;ntohs(dns-&gt;ans_count);i++)
{
answers[i].name=ReadName(reader,buf,&amp;stop);
reader = reader + stop;

answers[i].resource = (struct R_DATA*)(reader);
reader = reader + sizeof(struct R_DATA);

if(ntohs(answers[i].resource-&gt;type) == 1) //if its an ipv4 address
{
answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource-&gt;data_len));

for(j=0 ; j&lt;ntohs(answers[i].resource-&gt;data_len) ; j++)
answers[i].rdata[j]=reader[j];

answers[i].rdata[ntohs(answers[i].resource-&gt;data_len)] = '\0';

reader = reader + ntohs(answers[i].resource-&gt;data_len);
}
else
{
answers[i].rdata = ReadName(reader,buf,&amp;stop);
reader = reader + stop;
}
}

//read authorities
for(i=0;i&lt;ntohs(dns-&gt;auth_count);i++)
{
auth[i].name=ReadName(reader,buf,&amp;stop);
reader+=stop;

auth[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

auth[i].rdata=ReadName(reader,buf,&amp;stop);
reader+=stop;
}

//read additional
for(i=0;i&lt;ntohs(dns-&gt;add_count);i++)
{
addit[i].name=ReadName(reader,buf,&amp;stop);
reader+=stop;

addit[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

if(ntohs(addit[i].resource-&gt;type)==1)
{
addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource-&gt;data_len));
for(j=0;j&lt;ntohs(addit[i].resource-&gt;data_len);j++)
addit[i].rdata[j]=reader[j];

addit[i].rdata[ntohs(addit[i].resource-&gt;data_len)]='\0';
reader+=ntohs(addit[i].resource-&gt;data_len);
}
else
{
addit[i].rdata=ReadName(reader,buf,&amp;stop);
reader+=stop;
}
}

//print answers
for(i=0;i&lt;ntohs(dns-&gt;ans_count);i++)
{
//printf(&quot;\nAnswer : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,answers[i].name);

if(ntohs(answers[i].resource-&gt;type)==1) //IPv4 address
{

long *p;
p=(long*)answers[i].rdata;
a.sin_addr.s_addr=(*p); //working without ntohl
printf(&quot;has IPv4 address : %s&quot;,inet_ntoa(a.sin_addr));
}
if(ntohs(answers[i].resource-&gt;type)==5) //Canonical name for an alias
printf(&quot;has alias name : %s&quot;,answers[i].rdata);

printf(&quot;\n&quot;);
}

//print authorities
for(i=0;i&lt;ntohs(dns-&gt;auth_count);i++)
{
//printf(&quot;\nAuthorities : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,auth[i].name);
if(ntohs(auth[i].resource-&gt;type)==2)
printf(&quot;has authoritative nameserver : %s&quot;,auth[i].rdata);
printf(&quot;\n&quot;);
}

//print additional resource records
for(i=0;i&lt;ntohs(dns-&gt;add_count);i++)
{
//printf(&quot;\nAdditional : %d&quot;,i+1);
printf(&quot;Name : %s &quot;,addit[i].name);
if(ntohs(addit[i].resource-&gt;type)==1)
{
long *p;
p=(long*)addit[i].rdata;
a.sin_addr.s_addr=(*p); //working without ntohl
printf(&quot;has IPv4 address : %s&quot;,inet_ntoa(a.sin_addr));
}
printf(&quot;\n&quot;);
}
return;
}

unsigned char* ReadName(unsigned char* reader,unsigned char* buffer,int* count)
{
unsigned char *name;
unsigned int p=0,jumped=0,offset;
int i , j;

*count = 1;
name = (unsigned char*)malloc(256);

name[0]='\0';

//read the names in 3www6google3com format
while(*reader!=0)
{
if(*reader&gt;=192)
{
offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
reader = buffer + offset - 1;
jumped = 1; //we have jumped to another location so counting wont go up!
}
else
name[p++]=*reader;

reader=reader+1;

if(jumped==0)
*count = *count + 1; //if we havent jumped to another location then we can count up
}

name[p]='\0'; //string complete
if(jumped==1)
*count = *count + 1; //number of steps we actually moved forward in the packet

//now convert 3www6google3com0 to www.google.com
for(i=0;i&lt;(int)strlen((const char*)name);i++) {
p=name[i];
for(j=0;j&lt;(int)p;j++) {
name[i]=name[i+1];
i=i+1;
}
name[i]='.';
}
name[i-1]='\0'; //remove the last dot
return name;
}

//Retrieve the DNS servers from the registry
void get_dns_servers()
{
/*
for(i=0;i&lt;dns_count;i++)
{
for(j=0;j&lt;strlen(dns_servers[i]);j++)
{
if(dns_servers[i][j]==',' || dns_servers[i][j]==' ')
{
strcpy(dns_servers[dns_count++],dns_servers[i]+j+1);
dns_servers[i][j]=0;
}
}
}

printf(&quot;\nThe following DNS Servers were found on your system...&quot;);
for(i=0;i&lt;dns_count;i++)
{
printf(&quot;\n%d) %s&quot;,i+1,dns_servers[i]);
}
*/
strcpy(dns_servers[0],&quot;208.67.222.222&quot;);
strcpy(dns_servers[1],&quot;208.67.220.220&quot;);
}

//this will convert www.google.com to 3www6google3com ;got it <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host) {
int lock = 0 , i;
strcat((char*)host,&quot;.&quot;);
for(i = 0 ; i &lt; (int)strlen((char*)host) ; i++) {
if(host[i]=='.') {
*dns++=i-lock;
for(;lock&lt;i;lock++) {
*dns++=host[lock];
}
lock++; //or lock=i+1;
}
}
*dns++='\0';
}
</pre>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=7&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/dns-query-code-in-c-with-winsock-and-linux-sockets/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Packet Sniffer Code in C using Winsock</title>
		<link>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-winsock/</link>
		<comments>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-winsock/#comments</comments>
		<pubDate>Mon, 19 Mar 2007 11:51:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Winsock]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=6</guid>
		<description><![CDATA[Introduction
Ever since windows 2000/XP when IP_HDRINCL became a valid option for setsockopt() , WSAIoctl() had another option called SIO_RCVALL which enabled a raw socket to sniff all incoming traffic over the selected interface to whose IP the socket was bound.Hence to make a sniffer in Winsock he simple steps are :

1. Create a raw socket.
2. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong><br />
Ever since windows 2000/XP when IP_HDRINCL became a valid option for setsockopt() , WSAIoctl() had another option called SIO_RCVALL which enabled a raw socket to sniff all incoming traffic over the selected interface to whose IP the socket was bound.Hence to make a sniffer in Winsock he simple steps are :</p>
<p><span id="more-6"></span></p>
<p>1. Create a raw socket.<br />
2. Bind the socket to the local IP over which the traffic is to be sniffed.<br />
3. WSAIoctl() the socket with SIO_RCVALL to give it sniffing powers.<br />
4. Put the socket in an infinite loop of recvfrom.<br />
5. n’ joy! the Buffer from recvfrom.</p>
<p>Now this feature of winsock is available on all 2000/XP and higher windows. But as usual  drawbacks are there.If you have used sniffers like Ethereal then you would realise that ethernet header is not available in winsock sniffing.Secondly you can only sniff incoming data on XP and XP+SP1 but both incoming and outgoing on XP+SP1+SP2 (as far as i could see-actual behavior may vary).I have not checked higher versions of windows. Moreover non IP packets (e.g. arp) may not be captured at all.So if full fledged sniffing is required then packet drivers like winpcap should help.</p>
<p>In the following source code all packets are assumed to be IP packets. VC++ 6.0<br />
on Win XP used here.</p>
<p><strong>Code</strong></p>
<pre class="brush: cpp;">

SOCKET sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
bind(sniffer,(struct sockaddr *)&amp;dest,sizeof(dest))
dest must have the details as follows :

memcpy(&amp;dest.sin_addr.s_addr,local-&gt;h_addr_list[in],
sizeof(dest.sin_addr.s_addr));
dest.sin_family = AF_INET;
dest.sin_port = 0;
dest.sin_zero = 0;
</pre>
<p>where HOSTENT *local should have the local IPs</p>
<pre class="brush: cpp;">
WSAIoctl(sniffer, SIO_RCVALL, &amp;j, sizeof(j), 0, 0, &amp;in,0, 0);
</pre>
<p>where j must be 1 and in can be any integer</p>
<pre class="brush: cpp;">
while(1)
{
 recvfrom(sniffer,Buffer,65536,0,0,0); //ring-a-ring-a roses
}
</pre>
<p>To get the local IP’s associated with the machine all that needs to be done<br />
is:</p>
<pre class="brush: cpp;">
gethostname(hostname, sizeof(hostname); //its a char hostname[100] for local hostname
HOSTENT *local = gethostbyname(hostname); //now local will have all local ips
</pre>
<p>Now socket sniffer will receive all incoming packets along with their headers<br />
and all that will be stored in the Buffer.After that some typecasting with<br />
structures representing the headers will help.</p>
<pre class="brush: cpp;">
typedef struct ip_hdr
{
 unsigned char  ip_header_len:4;  // 4-bit header length (in 32-bit words)
 unsigned char  ip_version   :4;  // 4-bit IPv4 version
 unsigned char  ip_tos;           // IP type of service
 unsigned short ip_total_length;  // Total length
 unsigned short ip_id;            // Unique identifier

 unsigned char  ip_frag_offset   :5; // Fragment offset field

 unsigned char  ip_more_fragment :1;
 unsigned char  ip_dont_fragment :1;
 unsigned char  ip_reserved_zero :1;

 unsigned char  ip_frag_offset1;    //fragment offset

 unsigned char  ip_ttl;           // Time to live
 unsigned char  ip_protocol;      // Protocol(TCP,UDP etc)
 unsigned short ip_checksum;      // IP checksum
 unsigned int   ip_srcaddr;       // Source address
 unsigned int   ip_destaddr;      // Source address
}   IPV4_HDR;

typedef struct udp_hdr
{
 unsigned short source_port;     // Source port no.
 unsigned short dest_port;       // Dest. port no.
 unsigned short udp_length;      // Udp packet length
 unsigned short udp_checksum;    // Udp checksum (optional)
}   UDP_HDR;

typedef struct tcp_header
{
 unsigned short source_port;  // source port
 unsigned short dest_port;    // destination port
 unsigned int   sequence;     // sequence number - 32 bits
 unsigned int   acknowledge;  // acknowledgement number - 32 bits

 unsigned char  ns   :1;          //Nonce Sum Flag Added in RFC 3540.
 unsigned char  reserved_part1:3; //according to rfc
 unsigned char  data_offset:4;    //number of dwords in the TCP header.

 unsigned char  fin  :1;      //Finish Flag
 unsigned char  syn  :1;      //Synchronise Flag
 unsigned char  rst  :1;      //Reset Flag
 unsigned char  psh  :1;      //Push Flag
 unsigned char  ack  :1;      //Acknowledgement Flag
 unsigned char  urg  :1;      //Urgent Flag

 unsigned char  ecn  :1;      //ECN-Echo Flag
 unsigned char  cwr  :1;      //Congestion Window Reduced Flag

 unsigned short window;          // window
 unsigned short checksum;        // checksum
 unsigned short urgent_pointer;  // urgent pointer
}   TCP_HDR;

typedef struct icmp_hdr
{
 BYTE type;          // ICMP Error type
 BYTE code;          // Type sub code
 USHORT checksum;
 USHORT id;
 USHORT seq;
}   ICMP_HDR;
</pre>
<p>The ip_protocol field of the ip header determines the type of the packet; for<br />
e.g 1 means a icmp packet and 2-igmp 6-tcp 17-udp and so on.RFC 1340 should help<br />
more. Another function in the source code is PrintData() which prints the data<br />
dumps in a hex view fashion as done by other sniffers and looks like this :</p>
<pre class="brush: cpp;">
IP Header
45 00 03 19 D8 17 00 00 FC 06 85 C0 42 F9 59 63       E...........B.Yc
C0 A8 01 02                                           ....
TCP Header
00 50 0C E4 D6 2B 77 70 9F 0D B1 8D 50 18 1A A8       .P...+wp....P...
71 C1 00 00                                           q...
Data Payload
48 54 54 50 2F 31 2E 31 20 32 30 30 20 4F 4B 0D       HTTP/1.1 200 OK.
0A 53 65 74 2D 43 6F 6F 6B 69 65 3A 20 47 6F 6F       .Set-Cookie: Goo
67 6C 65 41 63 63 6F 75 6E 74 73 4C 6F 63 61 6C       gleAccountsLocal
65 5F 73 65 73 73 69 6F 6E 3D 65 6E 0D 0A 53 65       e_session=en..Se
74 2D 43 6F 6F 6B 69 65 3A 20 53 49 44 3D 45 58       t-Cookie: SID=EX
50 49 52 45 44 3B 44 6F 6D 61 69 6E 3D 2E 67 6F       PIRED;Domain=.go
6F 67 6C 65 2E 63 6F 2E 69 6E 3B 50 61 74 68 3D       ogle.co.in;Path=
2F 3B 45 78 70 69 72 65 73 3D 4D 6F 6E 2C 20 30       /;Expires=Mon, 0
31 2D 4A 61 6E 2D 31 39 39 30 20 30 30 3A 30 30       1-Jan-1990 00:00
3A 30 30 20 47 4D 54 0D 0A 43 6F 6E 74 65 6E 74       :00 GMT..Content
2D 54 79 70 65 3A 20 74 65 78 74 2F 68 74 6D 6C       -Type: text/html
3B 20 63 68 61 72 73 65 74 3D 55 54 46 2D 38 0D       ; charset=UTF-8.
0A 43 61 63 68 65 2D 63 6F 6E 74 72 6F 6C 3A 20       .Cache-control:
70 72 69 76 61 74 65 0D 0A 43 6F 6E 74 65 6E 74       private..Content
</pre>
<p>……………….and so on To the right we only print the characters which are either<br />
an alphabet or a number.Everything is saved in a log file named log.txt.</p>
<p><span style="color: #3333ff; font-weight: bold;">Conclusion</span></p>
<p>The source code demonstrates simple concepts which can be used to develop a<br />
protocol analyzer like Ethereal.In the source code only tcp,udp and icmp packets<br />
have been broken into fields and that too according to normal situations.<br />
Variations in packet structures (for e.g. in case of icmp) are there to which<br />
the program might give inaccurate results.So you have to develop the program in<br />
the relevant way and implement all necessary error checking algorithms etc.<br />
Minor changes in the source code will adapt it to the winpcap environment so<br />
that everything on the wire can be sniffed!</p>
<p>Happy Sniffing!</p>
<p><strong>Source Code :</strong></p>
<pre class="brush: cpp;">
//Author : Prasshhant Pugalia
//prashant.pugalia@gmail.com
//Simple Sniffer in winsock
//Sniffs only incoming packets//

#include &quot;stdio.h&quot;
#include &quot;winsock2.h&quot;

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //this removes the need of mstcpip.h

void StartSniffing (SOCKET Sock); //This will sniff here and there
void ProcessPacket (unsigned char* , int); //This will decide how to digest
void PrintIpHeader (unsigned char* , int);
void PrintIcmpPacket (unsigned char* , int);
void PrintUdpPacket (unsigned char* , int);
void PrintTcpPacket (unsigned char* , int);
void ConvertToHex (unsigned char* , unsigned int);
void PrintData (unsigned char* , int);

typedef struct ip_hdr
{
unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
unsigned char ip_version :4; // 4-bit IPv4 version
unsigned char ip_tos; // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id; // Unique identifier

unsigned char ip_frag_offset :5; // Fragment offset field

unsigned char ip_more_fragment :1;
unsigned char ip_dont_fragment :1;
unsigned char ip_reserved_zero :1;

unsigned char ip_frag_offset1; //fragment offset

unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Source address
} IPV4_HDR;

typedef struct udp_hdr
{
unsigned short source_port; // Source port no.
unsigned short dest_port; // Dest. port no.
unsigned short udp_length; // Udp packet length
unsigned short udp_checksum; // Udp checksum (optional)
} UDP_HDR;

// TCP header
typedef struct tcp_header
{
unsigned short source_port; // source port
unsigned short dest_port; // destination port
unsigned int sequence; // sequence number - 32 bits
unsigned int acknowledge; // acknowledgement number - 32 bits

unsigned char ns :1; //Nonce Sum Flag Added in RFC 3540.
unsigned char reserved_part1:3; //according to rfc
unsigned char data_offset:4; /*The number of 32-bit words in the TCP header.
This indicates where the data begins.
The length of the TCP header is always a multiple
of 32 bits.*/

unsigned char fin :1; //Finish Flag
unsigned char syn :1; //Synchronise Flag
unsigned char rst :1; //Reset Flag
unsigned char psh :1; //Push Flag
unsigned char ack :1; //Acknowledgement Flag
unsigned char urg :1; //Urgent Flag

unsigned char ecn :1; //ECN-Echo Flag
unsigned char cwr :1; //Congestion Window Reduced Flag

////////////////////////////////

unsigned short window; // window
unsigned short checksum; // checksum
unsigned short urgent_pointer; // urgent pointer
} TCP_HDR;

typedef struct icmp_hdr
{
BYTE type; // ICMP Error type
BYTE code; // Type sub code
USHORT checksum;
USHORT id;
USHORT seq;
} ICMP_HDR;

FILE *logfile;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct sockaddr_in source,dest;
char hex[2];

//Its free!
IPV4_HDR *iphdr;
TCP_HDR *tcpheader;
UDP_HDR *udpheader;
ICMP_HDR *icmpheader;

int main()
{
SOCKET sniffer;
struct in_addr addr;
int in;

char hostname[100];
struct hostent *local;
WSADATA wsa;

logfile=fopen(&quot;log.txt&quot;,&quot;w&quot;);
if(log==NULL) printf(&quot;Unable to create file.&quot;);

//Initialise Winsock
printf(&quot;\nInitialising Winsock...&quot;);
if (WSAStartup(MAKEWORD(2,2), &amp;wsa) != 0)
{
printf(&quot;WSAStartup() failed.\n&quot;);
return 1;
}
printf(&quot;Initialised&quot;);

//Create a RAW Socket
printf(&quot;\nCreating RAW Socket...&quot;);
sniffer = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sniffer == INVALID_SOCKET)
{
printf(&quot;Failed to create raw socket.\n&quot;);
return 1;
}
printf(&quot;Created.&quot;);

//Retrive the local hostname
if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR)
{
printf(&quot;Error : %d&quot;,WSAGetLastError());
return 1;
}
printf(&quot;\nHost name : %s \n&quot;,hostname);

//Retrive the available IPs of the local host
local = gethostbyname(hostname);
printf(&quot;\nAvailable Network Interfaces : \n&quot;);
if (local == NULL)
{
printf(&quot;Error : %d.\n&quot;,WSAGetLastError());
return 1;
}

for (i = 0; local-&gt;h_addr_list[i] != 0; ++i)
{
memcpy(&amp;addr, local-&gt;h_addr_list[i], sizeof(struct in_addr));
printf(&quot;Interface Number : %d Address : %s\n&quot;,i,inet_ntoa(addr));
}

printf(&quot;Enter the interface number you would like to sniff : &quot;);
scanf(&quot;%d&quot;,&amp;in);

memset(&amp;dest, 0, sizeof(dest));
memcpy(&amp;dest.sin_addr.s_addr,local-&gt;h_addr_list[in],sizeof(dest.sin_addr.s_addr));
dest.sin_family = AF_INET;
dest.sin_port = 0;

printf(&quot;\nBinding socket to local system and port 0 ...&quot;);
if (bind(sniffer,(struct sockaddr *)&amp;dest,sizeof(dest)) == SOCKET_ERROR)
{
printf(&quot;bind(%s) failed.\n&quot;, inet_ntoa(addr));
return 1;
}
printf(&quot;Binding successful&quot;);

//Enable this socket with the power to sniff : SIO_RCVALL is the key Receive ALL <img src='http://www.binarytides.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> 

j=1;
printf(&quot;\nSetting socket to sniff...&quot;);
if (WSAIoctl(sniffer, SIO_RCVALL, &amp;j, sizeof(j), 0, 0, &amp;in,0, 0) == SOCKET_ERROR)
{
printf(&quot;WSAIoctl() failed.\n&quot;);
return 1;
}
printf(&quot;Socket set.&quot;);

//Begin
printf(&quot;\nStarted Sniffing\n&quot;);
printf(&quot;Packet Capture Statistics...\n&quot;);
StartSniffing(sniffer); //Happy Sniffing

//End
closesocket(sniffer);
WSACleanup();

return 0;
}

void StartSniffing(SOCKET sniffer)
{
unsigned char *Buffer = (char *)malloc(65536); //Its Big!
int mangobyte;

if (Buffer == NULL)
{
printf(&quot;malloc() failed.\n&quot;);
return;
}

do
{
mangobyte = recvfrom(sniffer,Buffer,65536,0,0,0); //Eat as much as u can
if(mangobyte &gt; 0) ProcessPacket(Buffer, mangobyte);
else printf( &quot;recvfrom() failed.\n&quot;);
}
while (mangobyte &gt; 0);

free(Buffer);
}

void ProcessPacket(unsigned char* Buffer, int Size)
{
iphdr = (IPV4_HDR *)Buffer;
++total;
switch (iphdr-&gt;ip_protocol) //Check the Protocol and do accordingly...
{
case 1: //ICMP Protocol
++icmp;
PrintIcmpPacket(Buffer,Size);
break;

case 2: //IGMP Protocol
++igmp;
break;

case 6: //TCP Protocol
++tcp;
PrintTcpPacket(Buffer,Size);
break;

case 17: //UDP Protocol
++udp;
PrintUdpPacket(Buffer,Size);
break;

default: //Some Other Protocol like ARP etc.
++others;
break;
}
printf(&quot;TCP : %d UDP : %d ICMP : %d IGMP : %d Others : %d Total : %d\r&quot;,tcp,udp,icmp,igmp,others,total);
}

void PrintIpHeader (unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;

iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr-&gt;ip_header_len*4;

memset(&amp;source, 0, sizeof(source));
source.sin_addr.s_addr = iphdr-&gt;ip_srcaddr;

memset(&amp;dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iphdr-&gt;ip_destaddr;

fprintf(logfile,&quot;\n&quot;);
fprintf(logfile,&quot;IP Header\n&quot;);
fprintf(logfile,&quot; |-IP Version : %d\n&quot;,(unsigned int)iphdr-&gt;ip_version);
fprintf(logfile,&quot; |-IP Header Length : %d DWORDS or %d Bytes\n&quot;,(unsigned int)iphdr-&gt;ip_header_len,((unsigned int)(iphdr-&gt;ip_header_len))*4);
fprintf(logfile,&quot; |-Type Of Service : %d\n&quot;,(unsigned int)iphdr-&gt;ip_tos);
fprintf(logfile,&quot; |-IP Total Length : %d Bytes(Size of Packet)\n&quot;,ntohs(iphdr-&gt;ip_total_length));
fprintf(logfile,&quot; |-Identification : %d\n&quot;,ntohs(iphdr-&gt;ip_id));
fprintf(logfile,&quot; |-Reserved ZERO Field : %d\n&quot;,(unsigned int)iphdr-&gt;ip_reserved_zero);
fprintf(logfile,&quot; |-Dont Fragment Field : %d\n&quot;,(unsigned int)iphdr-&gt;ip_dont_fragment);
fprintf(logfile,&quot; |-More Fragment Field : %d\n&quot;,(unsigned int)iphdr-&gt;ip_more_fragment);
fprintf(logfile,&quot; |-TTL : %d\n&quot;,(unsigned int)iphdr-&gt;ip_ttl);
fprintf(logfile,&quot; |-Protocol : %d\n&quot;,(unsigned int)iphdr-&gt;ip_protocol);
fprintf(logfile,&quot; |-Checksum : %d\n&quot;,ntohs(iphdr-&gt;ip_checksum));
fprintf(logfile,&quot; |-Source IP : %s\n&quot;,inet_ntoa(source.sin_addr));
fprintf(logfile,&quot; |-Destination IP : %s\n&quot;,inet_ntoa(dest.sin_addr));
}

void PrintTcpPacket(unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;

iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr-&gt;ip_header_len*4;

tcpheader=(TCP_HDR*)(Buffer+iphdrlen);

fprintf(logfile,&quot;\n\n***********************TCP Packet*************************\n&quot;);

PrintIpHeader(Buffer,Size);

fprintf(logfile,&quot;\n&quot;);
fprintf(logfile,&quot;TCP Header\n&quot;);
fprintf(logfile,&quot; |-Source Port : %u\n&quot;,ntohs(tcpheader-&gt;source_port));
fprintf(logfile,&quot; |-Destination Port : %u\n&quot;,ntohs(tcpheader-&gt;dest_port));
fprintf(logfile,&quot; |-Sequence Number : %u\n&quot;,ntohl(tcpheader-&gt;sequence));
fprintf(logfile,&quot; |-Acknowledge Number : %u\n&quot;,ntohl(tcpheader-&gt;acknowledge));
fprintf(logfile,&quot; |-Header Length : %d DWORDS or %d BYTES\n&quot;
,(unsigned int)tcpheader-&gt;data_offset,(unsigned int)tcpheader-&gt;data_offset*4);
fprintf(logfile,&quot; |-CWR Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;cwr);
fprintf(logfile,&quot; |-ECN Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;ecn);
fprintf(logfile,&quot; |-Urgent Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;urg);
fprintf(logfile,&quot; |-Acknowledgement Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;ack);
fprintf(logfile,&quot; |-Push Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;psh);
fprintf(logfile,&quot; |-Reset Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;rst);
fprintf(logfile,&quot; |-Synchronise Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;syn);
fprintf(logfile,&quot; |-Finish Flag : %d\n&quot;,(unsigned int)tcpheader-&gt;fin);
fprintf(logfile,&quot; |-Window : %d\n&quot;,ntohs(tcpheader-&gt;window));
fprintf(logfile,&quot; |-Checksum : %d\n&quot;,ntohs(tcpheader-&gt;checksum));
fprintf(logfile,&quot; |-Urgent Pointer : %d\n&quot;,tcpheader-&gt;urgent_pointer);
fprintf(logfile,&quot;\n&quot;);
fprintf(logfile,&quot; DATA Dump &quot;);
fprintf(logfile,&quot;\n&quot;);

fprintf(logfile,&quot;IP Header\n&quot;);
PrintData(Buffer,iphdrlen);

fprintf(logfile,&quot;TCP Header\n&quot;);
PrintData(Buffer+iphdrlen,tcpheader-&gt;data_offset*4);

fprintf(logfile,&quot;Data Payload\n&quot;);
PrintData(Buffer+iphdrlen+tcpheader-&gt;data_offset*4
,(Size-tcpheader-&gt;data_offset*4-iphdr-&gt;ip_header_len*4));

fprintf(logfile,&quot;\n###########################################################&quot;);
}

void PrintUdpPacket(unsigned char *Buffer,int Size)
{
unsigned short iphdrlen;

iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr-&gt;ip_header_len*4;

udpheader = (UDP_HDR *)(Buffer + iphdrlen);

fprintf(logfile,&quot;\n\n***********************UDP Packet*************************\n&quot;);

PrintIpHeader(Buffer,Size);

fprintf(logfile,&quot;\nUDP Header\n&quot;);
fprintf(logfile,&quot; |-Source Port : %d\n&quot;,ntohs(udpheader-&gt;source_port));
fprintf(logfile,&quot; |-Destination Port : %d\n&quot;,ntohs(udpheader-&gt;dest_port));
fprintf(logfile,&quot; |-UDP Length : %d\n&quot;,ntohs(udpheader-&gt;udp_length));
fprintf(logfile,&quot; |-UDP Checksum : %d\n&quot;,ntohs(udpheader-&gt;udp_checksum));

fprintf(logfile,&quot;\n&quot;);
fprintf(logfile,&quot;IP Header\n&quot;);
PrintData(Buffer,iphdrlen);

fprintf(logfile,&quot;UDP Header\n&quot;);
PrintData(Buffer+iphdrlen,sizeof(UDP_HDR));

fprintf(logfile,&quot;Data Payload\n&quot;);
PrintData(Buffer+iphdrlen+sizeof(UDP_HDR)
,(Size - sizeof(UDP_HDR) - iphdr-&gt;ip_header_len*4));

fprintf(logfile,&quot;\n###########################################################&quot;);
}

void PrintIcmpPacket(unsigned char* Buffer , int Size)
{
unsigned short iphdrlen;

iphdr = (IPV4_HDR *)Buffer;
iphdrlen = iphdr-&gt;ip_header_len*4;

icmpheader=(ICMP_HDR*)(Buffer+iphdrlen);

fprintf(logfile,&quot;\n\n***********************ICMP Packet*************************\n&quot;);
PrintIpHeader(Buffer,Size);

fprintf(logfile,&quot;\n&quot;);

fprintf(logfile,&quot;ICMP Header\n&quot;);
fprintf(logfile,&quot; |-Type : %d&quot;,(unsigned int)(icmpheader-&gt;type));

if((unsigned int)(icmpheader-&gt;type)==11) fprintf(logfile,&quot; (TTL Expired)\n&quot;);
else if((unsigned int)(icmpheader-&gt;type)==0) fprintf(logfile,&quot; (ICMP Echo Reply)\n&quot;);

fprintf(logfile,&quot; |-Code : %d\n&quot;,(unsigned int)(icmpheader-&gt;code));
fprintf(logfile,&quot; |-Checksum : %d\n&quot;,ntohs(icmpheader-&gt;checksum));
fprintf(logfile,&quot; |-ID : %d\n&quot;,ntohs(icmpheader-&gt;id));
fprintf(logfile,&quot; |-Sequence : %d\n&quot;,ntohs(icmpheader-&gt;seq));
fprintf(logfile,&quot;\n&quot;);

fprintf(logfile,&quot;IP Header\n&quot;);
PrintData(Buffer,iphdrlen);

fprintf(logfile,&quot;UDP Header\n&quot;);
PrintData(Buffer+iphdrlen,sizeof(ICMP_HDR));

fprintf(logfile,&quot;Data Payload\n&quot;);
PrintData(Buffer+iphdrlen+sizeof(ICMP_HDR)
,(Size - sizeof(ICMP_HDR) - iphdr-&gt;ip_header_len*4));

fprintf(logfile,&quot;\n###########################################################&quot;);
}

void PrintData (unsigned char* data , int Size)
{

for(i=0 ; i &lt; Size ; i++)
{
if( i!=0 &amp;&amp; i%16==0) //if one line of hex printing is complete...
{
fprintf(logfile,&quot; &quot;);
for(j=i-16 ; j&lt;i ; j++)
{
if(data[j]&gt;=32 &amp;&amp; data[j]&lt;=128)
fprintf(logfile,&quot;%c&quot;,(unsigned char)data[j]); //if its a number or alphabet

else fprintf(logfile,&quot;.&quot;); //otherwise print a dot
}
fprintf(logfile,&quot;\n&quot;);
}

if(i%16==0) fprintf(logfile,&quot; &quot;);

ConvertToHex(hex,(unsigned int)data[i]); //now print the hex values
fprintf(logfile,&quot; %s&quot;,hex);

if( i==Size-1) //print the last spaces
{
for(j=0;j&lt;15-i%16;j++) fprintf(logfile,&quot; &quot;); //extra spaces

fprintf(logfile,&quot; &quot;);

for(j=i-i%16 ; j&lt;=i ; j++)
{
if(data[j]&gt;=32 &amp;&amp; data[j]&lt;=128) fprintf(logfile,&quot;%c&quot;,(unsigned char)data[j]);
else fprintf(logfile,&quot;.&quot;);
}
fprintf(logfile,&quot;\n&quot;);
}
}
}

void ConvertToHex(unsigned char *hex , unsigned int decimal)
{
int rem,k=0,p;
p=decimal;
while(decimal!=0)
{
rem=decimal%16;
decimal=decimal/16;
if(rem&gt;=10) hex[k++]=65 + rem - 10; //65 means A
else if(rem&lt;=9) hex[k++]=rem+48; //48 means 0
}
hex[k++]='\0';
if(p==0) strcpy(hex,&quot;00&quot;);
else if(p&lt;16) strcat(hex,&quot;0&quot;);
_strrev(hex);
}
</pre>
<table style="border: 1px solid #353535; padding: 0px; background-color: #5d7cba; font-family: Arial,Helvetica,sans-serif; font-size: 11px;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr style="background-color: #ffffff;">
<td style="padding: 5px;" align="center"><a href="http://www.esnips.com/doc/eaa1a4b5-89f2-49c5-846c-f42f6f5fea59/sniffer_demo/?widget=documentIcon"><img title="click to Viewsniffer_demo" src="http://www.esnips.com//images/thumbs/thumb.zip.gif" border="0" alt="sniffer_demo" /></a></td>
</tr>
<tr style="background-color: #ffffff;">
<td style="padding: 5px;" align="center"><strong><a style="color: #333333;" href="http://www.esnips.com/doc/eaa1a4b5-89f2-49c5-846c-f42f6f5fea59/sniffer_demo/?widget=documentIcon">sniffer_demo.zip</a></strong></td>
</tr>
<tr>
<td style="padding: 5px; font-size: 9px; color: #ffffff;" valign="bottom">Hosted by <a style="color: #ffffff;" href="http://www.esnips.com/">eSnips</a></td>
</tr>
</tbody>
</table>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=6&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-winsock/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Raw Sockets Using Winsock</title>
		<link>http://www.binarytides.com/blog/raw-sockets-using-winsock/</link>
		<comments>http://www.binarytides.com/blog/raw-sockets-using-winsock/#comments</comments>
		<pubDate>Sun, 18 Mar 2007 14:38:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Winsock]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=5</guid>
		<description><![CDATA[Introduction
Raw sockets, or “Raw Packets”, give you the facility to access the entire contents of a packet or datagram, both for reading and writing purpose. In other words, you can fabricate a whole packet according to your likes and dislikes. For example, a TCP packet would contain an IP header, a TCP header, and then [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p style="text-align: justify;">Raw sockets, or “Raw Packets”, give you the facility to access the entire contents of a packet or datagram, both for reading and writing purpose. In other words, you can fabricate a whole packet according to your likes and dislikes. For example, a TCP packet would contain an IP header, a TCP header, and then the actual data that needs to be transmitted. When working with normal sockets, whatever we send to a socket is actually the data part. In such a scenario, the OS network stack takes the responsibility of adding the header with all fields set to relevant values. When we send the data to a destination, the stack adds the headers and sends the packet, and when we receive some data, then the stack removes the headers and hands out the data to our application. So we are saved from the work of designing the headers. For normal internet applications, there is no need to be concerned about the header operations as they are there for the safe transmission and reception of data, and once the transfer is complete, their need is over and they are dumped. But the story doesn’t end there, there are some people who need raw sockets. Raw sockets are widely used in the field of network security for creating both security and insecurity! In this article, we will take a look at the contents of a general TCPpacket, and try to make a raw packet and transmit it. We shall do this on Windows XP using the VC++ 6.0 compiler. OK, so let’s have a look at the IP and TCP headers.</p>
<p><span id="more-5"></span></p>
<p>RFC 791 gives the structure of an IP header as:</p>
<pre class="brush: cpp;">
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|  IHL  |Type of Service|          Total Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Identification        |Flags|      Fragment Offset    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Time to Live |    Protocol   |         Header Checksum       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Source Address                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Destination Address                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<p>Next comes the TCP header for transmission using the TCP protocol. RFC 793 gives the structure.</p>
<pre class="brush: cpp;">
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
</pre>
<p>and at the end is your data, bla bla bla bla bla bla…………………..</p>
<p>———————————————————– &lt;&lt;end of packet</p>
<p>To understand the significance of each field, read up the necessary RFC or some other good TCP/IP tutorial on the net as there are plenty. If you have previous knowledge of socket programming, then the headers are self-explanatory. Now, why is the raw socket feature of importance to network security? Well, one important aspect of network security which needs this feature is scanning. Scanning is of many types. For example, scanning for open ports, scanning the type of OS, scanning for vulnerabilities etc.</p>
<p><strong>Raw Sockets and Windows</strong></p>
<p>First of all, it must be understood very clearly that raw sockets is not a feature of the network API (although it must be present there as an option) but of the OS protocol stack. To implement raw sockets, all we have to do is to inform the OS that the packet buffer we are providing will have the header and so the OS should transmit it as is without “adding any header”; that’s all, nothing more to do. The Unix operating system has raw socket support since ancient times. But the problem is with Windows. None of Windows 95, 98, 98SE supported raw sockets.</p>
<p>Raw sockets became available on Windows from Windows 2000; Windows XP continued this. But suddenly, raw socket support was removed from Windows XP through a patch in SP2. Vista doesn’t have it. A security patch called MS05-019 (<a href="http://support.microsoft.com/kb/897656">http://support.microsoft.com/kb/897656</a>) is what disables raw sockets on XP SP2 and can do the same to even SP1. Probably Windows 2003 SP1 also implements the same the result being the end of raw sockets.</p>
<p>An indepth summary is available at <a href="http://seclists.org/nmap-hackers/2005/0005.html">http://seclists.org/nmap-hackers/2005/0005.html</a>. Windows 95, 98, 98SE do not support raw sockets, but this doesn’t end the story. If you want the facility, then the solution is to use a third party packet driver like Winpcap. Such packet drivers will do your task irrespective of what the OS likes and dislikes. Windows XP and XP SP1 have full raw socket support and so life is easy. So if you want to do raw socketing on Windows, then either use Winpcap or don’t feel desperate to install SP2, or otherwise use Windows 2003 which, as per my knowledge, has raw socket support. <a href="http://technet.microsoft.com/hi-in/library/bb457156%28en-us%29.aspx">http://technet.microsoft.com/hi-in/library/bb457156(en-us).aspx</a> should tell more. So let’s brief up:</p>
<p>1. Windows 95, 98, 98SE, NT4.0 — Only raw ICMP and IGMP with restricted<br />
features.</p>
<p>2. Windows 2000, XP, XP SP1, 2003 — Full raw socket support for both receiving<br />
and sending purposes.</p>
<p>3. Windows XP SP2 — Only raw ICMP, IGMP, and UDP with proper source address<br />
(IP spoofing restricted) can be sent. But, full raw sockets can be received,<br />
which means you can sniff all incoming data and read their headers.</p>
<p>Note : Winsock Ver. &gt;=2.0</p>
<p>So if your system doesn’t support raw sockets, then switch to Linux or use<br />
Winpcap.</p>
<p><strong>The Code</strong></p>
<pre class="brush: cpp;">
SOCKET s;
s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); //Create a RAW socket
int optval=1;
setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&amp;optval,
sizeof optval);  //Set it to include the header
</pre>
<p>The last line, setsockopt, tells the OS that the socket s will have the<br />
header included (IP_HDRINCL) at the IP (IPPROTO_IP) level in the data buffer<br />
it sends. IPPROTO_RAW creates an absolutely raw socket, and you have to write<br />
all headers yourself. IPPROTO_UDP, IPROTO_TCP are also available for the<br />
respective types of packets.</p>
<p>Now, we shall need two structures like this:</p>
<pre class="brush: cpp;">
typedef struct ip_hdr
{
unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words)
// normally=5 (Means 20 Bytes may be 24 also)
unsigned char ip_version :4;   // 4-bit IPv4 version
unsigned char ip_tos;          // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id;          // Unique identifier

unsigned char ip_frag_offset :5; // Fragment offset field

unsigned char ip_more_fragment :1;
unsigned char ip_dont_fragment :1;
unsigned char ip_reserved_zero :1;

unsigned char ip_frag_offset1; //fragment offset

unsigned char ip_ttl;          // Time to live
unsigned char ip_protocol;     // Protocol(TCP,UDP etc)
unsigned short ip_checksum;    // IP checksum
unsigned int ip_srcaddr;       // Source address
unsigned int ip_destaddr;      // Source address
} IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;

// TCP header
typedef struct tcp_header
{
unsigned short source_port;   // source port
unsigned short dest_port;     // destination port
unsigned int sequence;        // sequence number - 32 bits
unsigned int acknowledge;     // acknowledgement number - 32 bits

unsigned char ns :1;          //Nonce Sum Flag Added in RFC 3540.
unsigned char reserved_part1:3; //according to rfc
unsigned char data_offset:4;    /*The number of 32-bit words
in the TCP header.
This indicates where the data begins.
The length of the TCP header
is always a multiple
of 32 bits.*/

unsigned char fin :1; //Finish Flag
unsigned char syn :1; //Synchronise Flag
unsigned char rst :1; //Reset Flag
unsigned char psh :1; //Push Flag
unsigned char ack :1; //Acknowledgement Flag
unsigned char urg :1; //Urgent Flag

unsigned char ecn :1; //ECN-Echo Flag
unsigned char cwr :1; //Congestion Window Reduced Flag

////////////////////////////////

unsigned short window; // window
unsigned short checksum; // checksum
unsigned short urgent_pointer; // urgent pointer
} TCP_HDR , *PTCP_HDR , FAR * LPTCP_HDR , TCPHeader , TCP_HEADER;
</pre>
<p><strong>Little/Big Endian</strong></p>
<p>Did you notice a difference between the RFC specification and the structures declared above? IP header and version have swapped their positions.The urg, ack, and psh flags of the TCP header are all in reverse order? Mistake? Well, this depends on the byte order that is implemented in the machine architecture. There are two types: Little Endian and Big Endian. In Big Endian, the bytes and bits are arranged in their normal order as we read them, which means the MSB (most significant byte) comes first and the LSB (least significant byte) last. But in Little Endian, the thing is totally<br />
reversed. And it must be remembered that all bits are byte wise reversed, which means they are reversed in groups of 8. That’s the rule for making segments of sizes 3 or 5 etc. If it’s a long or int, then a htons() will do the job. Well, enough said, now let’s make our packet.</p>
<pre class="brush: cpp;">
char packet[65536];   //thats big!
IPV4_HDR *v4hdr=NULL;
TCP_HDR *tcphdr=NULL;

v4hdr = (IPV4_HDR *)packet; //lets point to the ip header portion
v4hdr-&gt;ip_version=4;
v4hdr-&gt;ip_header_len=5;
v4hdr-&gt;ip_tos = 0;
v4hdr-&gt;ip_total_length = htons ( sizeof(IPV4_HDR) + sizeof(TCP_HDR) + payload );
v4hdr-&gt;ip_id = htons(2);
</pre>
<p>&#8230;&#8230;&#8230;&#8230;&#8230;and so on</p>
<pre class="brush: cpp;">
tcphdr = (TCP_HDR *)&amp;buf[sizeof(IPV4_HDR)];
//get the pointer to the tcp header in the packet

tcphdr-&gt;source_port = htons(1234);
tcphdr-&gt;dest_port = htons(50000);

tcphdr-&gt;cwr=0;
tcphdr-&gt;ecn=1;
tcphdr-&gt;urg=0;
tcphdr-&gt;ack=0;
</pre>
<p>&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;and so on</p>
<pre class="brush: cpp;">
// Initialize the TCP payload to some rubbish
data = &amp;buf[sizeof(IPV4_HDR) + sizeof(TCP_HDR)];
memset(data, '^', payload);
</pre>
<p>Get the remote host details in a sockaddr_in dest and call:</p>
<pre class="brush: cpp;">
sendto(s , buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR) +
payload, 0,(SOCKADDR *)&amp;dest, sizeof(dest));
</pre>
<p>where payload is the size of the data after the TCP header. That’s it! We<br />
are done.</p>
<p>To check whether the packets went out as you expected them to, use a<br />
sniffer like Ethereal and sniff them. Note: If you have any firewall running,<br />
then raw packets may be blocked.</p>
<p><span style="font-weight: bold;">Source Code :</span></p>
<pre class="brush: cpp;">
//raw tcp packet crafter

#include &quot;stdio.h&quot;
#include &quot;winsock2.h&quot;
#include &quot;ws2tcpip.h&quot; //IP_HDRINCL is here
#include &quot;conio.h&quot;

#pragma comment(lib,&quot;ws2_32.lib&quot;) //winsock 2.2 library

typedef struct ip_hdr
{
unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)
unsigned char ip_version :4; // 4-bit IPv4 version
unsigned char ip_tos; // IP type of service
unsigned short ip_total_length; // Total length
unsigned short ip_id; // Unique identifier

unsigned char ip_frag_offset :5; // Fragment offset field

unsigned char ip_more_fragment :1;
unsigned char ip_dont_fragment :1;
unsigned char ip_reserved_zero :1;

unsigned char ip_frag_offset1; //fragment offset

unsigned char ip_ttl; // Time to live
unsigned char ip_protocol; // Protocol(TCP,UDP etc)
unsigned short ip_checksum; // IP checksum
unsigned int ip_srcaddr; // Source address
unsigned int ip_destaddr; // Source address
} IPV4_HDR, *PIPV4_HDR, FAR * LPIPV4_HDR;

// TCP header
typedef struct tcp_header
{
unsigned short source_port; // source port
unsigned short dest_port; // destination port
unsigned int sequence; // sequence number - 32 bits
unsigned int acknowledge; // acknowledgement number - 32 bits

unsigned char ns :1; //Nonce Sum Flag Added in RFC 3540.
unsigned char reserved_part1:3; //according to rfc
unsigned char data_offset:4; /*The number of 32-bit words in the TCP header.
This indicates where the data begins.
The length of the TCP header is always a multiple
of 32 bits.*/

unsigned char fin :1; //Finish Flag
unsigned char syn :1; //Synchronise Flag
unsigned char rst :1; //Reset Flag
unsigned char psh :1; //Push Flag
unsigned char ack :1; //Acknowledgement Flag
unsigned char urg :1; //Urgent Flag

unsigned char ecn :1; //ECN-Echo Flag
unsigned char cwr :1; //Congestion Window Reduced Flag

////////////////////////////////

unsigned short window; // window
unsigned short checksum; // checksum
unsigned short urgent_pointer; // urgent pointer
} TCP_HDR , *PTCP_HDR , FAR * LPTCP_HDR , TCPHeader , TCP_HEADER;

int main()
{
char host[100],buf[1000],*data=NULL,source_ip[20]; //buf is the complete packet
SOCKET s;
int k=1;

IPV4_HDR *v4hdr=NULL;
TCP_HDR *tcphdr=NULL;

int payload=512 , optval;
SOCKADDR_IN dest;
hostent *server;

//Initialise Winsock
WSADATA wsock;
printf(&quot;\nInitialising Winsock...&quot;);
if (WSAStartup(MAKEWORD(2,2),&amp;wsock) != 0)
{
fprintf(stderr,&quot;WSAStartup() failed&quot;);
exit(EXIT_FAILURE);
}
printf(&quot;Initialised successfully.&quot;);
////////////////////////////////////////////////

//Create Raw TCP Packet
printf(&quot;\nCreating Raw TCP Socket...&quot;);
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==SOCKET_ERROR)
{
printf(&quot;Creation of raw socket failed.&quot;);
return 0;
}
printf(&quot;Raw TCP Socket Created successfully.&quot;);
////////////////////////////////////////////////

//Put Socket in RAW Mode.
printf(&quot;\nSetting the socket in RAW mode...&quot;);
if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&amp;optval, sizeof(optval))==SOCKET_ERROR)
{
printf(&quot;failed to set socket in raw mode.&quot;);
return 0;
}
printf(&quot;Successful.&quot;);
////////////////////////////////////////////////

//Target Hostname
printf(&quot;\nEnter hostname : &quot;);
gets(host);
printf(&quot;\nResolving Hostname...&quot;);
if((server=gethostbyname(host))==0)
{
printf(&quot;Unable to resolve.&quot;);
return 0;
}
dest.sin_family = AF_INET;
dest.sin_port = htons(50000); //your destination port
memcpy(&amp;dest.sin_addr.s_addr,server-&gt;h_addr,server-&gt;h_length);
printf(&quot;Resolved.&quot;);
/////////////////////////////////////////////////

printf(&quot;\nEnter Source IP : &quot;);
gets(source_ip);

v4hdr = (IPV4_HDR *)buf; //lets point to the ip header portion
v4hdr-&gt;ip_version=4;
v4hdr-&gt;ip_header_len=5;
v4hdr-&gt;ip_tos = 0;
v4hdr-&gt;ip_total_length = htons ( sizeof(IPV4_HDR) + sizeof(TCP_HDR) + payload );
v4hdr-&gt;ip_id = htons(2);
v4hdr-&gt;ip_frag_offset = 0;
v4hdr-&gt;ip_frag_offset1 = 0;
v4hdr-&gt;ip_reserved_zero = 0;
v4hdr-&gt;ip_dont_fragment = 1;
v4hdr-&gt;ip_more_fragment = 0;
v4hdr-&gt;ip_ttl = 8;
v4hdr-&gt;ip_protocol = IPPROTO_TCP;
v4hdr-&gt;ip_srcaddr = inet_addr(source_ip);
v4hdr-&gt;ip_destaddr = inet_addr(inet_ntoa(dest.sin_addr));
v4hdr-&gt;ip_checksum = 0;

tcphdr = (TCP_HDR *)&amp;buf[sizeof(IPV4_HDR)]; //get the pointer to the tcp header in the packet

tcphdr-&gt;source_port = htons(1234);
tcphdr-&gt;dest_port = htons(50000);

tcphdr-&gt;cwr=0;
tcphdr-&gt;ecn=1;
tcphdr-&gt;urg=0;
tcphdr-&gt;ack=0;
tcphdr-&gt;psh=0;
tcphdr-&gt;rst=1;
tcphdr-&gt;syn=0;
tcphdr-&gt;fin=0;
tcphdr-&gt;ns=1;

tcphdr-&gt;checksum = 0;

// Initialize the TCP payload to some rubbish
data = &amp;buf[sizeof(IPV4_HDR) + sizeof(TCP_HDR)];
memset(data, '^', payload);

printf(&quot;\nSending packet...\n&quot;);

while(!_kbhit())
{
printf(&quot; %d packets send\r&quot;,k++);
if((sendto(s , buf , sizeof(IPV4_HDR)+sizeof(TCP_HDR) + payload, 0,
(SOCKADDR *)&amp;dest, sizeof(dest)))==SOCKET_ERROR)
{

printf(&quot;Error sending Packet : %d&quot;,WSAGetLastError());
break;
}
}

return 0;
}
</pre>
<p>VC++ can be used to compile this code. Simply create a project and put this file in it and click run.</p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=5&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/raw-sockets-using-winsock/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
