<?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; C</title>
	<atom:link href="http://www.binarytides.com/blog/category/c/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>Raw Sockets C Source Code on Linux</title>
		<link>http://www.binarytides.com/blog/raw-sockets-c-code-on-linux/</link>
		<comments>http://www.binarytides.com/blog/raw-sockets-c-code-on-linux/#comments</comments>
		<pubDate>Wed, 06 May 2009 04:55:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=60</guid>
		<description><![CDATA[The structure of IP Header as given by RFC 791 is :

0                   1                   2      [...]]]></description>
			<content:encoded><![CDATA[<p>The structure of IP Header as given by RFC 791 is :</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><span id="more-60"></span></p>
<p>The structure of a TCP header as given by RFC 793 :</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>To create a raw socket :</p>
<pre class="brush: cpp;">
int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
</pre>
<p>Another option to make sure the kernel uses the raw headers :</p>
<pre class="brush: cpp;">
 {
  int one = 1;
  const int *val = &amp;one;
  if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) &lt; 0)
   printf (&quot;Warning: Cannot set HDRINCL!\n&quot;);
 }
</pre>
<p>Below is an example code which constructs a raw TCP packet :<br />
<strong>Code :</strong></p>
<pre class="brush: cpp;">
/*
 Raw Sockets with LINUX
*/
#include&lt;stdio.h&gt;
#include&lt;netinet/tcp.h&gt; //Provides declarations for tcp header
#include&lt;netinet/ip.h&gt; //Provides declarations for ip header

//Checksum calculation function
unsigned short csum (unsigned short *buf, int nwords)
{
 unsigned long sum;

 for (sum = 0; nwords &gt; 0; nwords--)
  sum += *buf++;

 sum = (sum &gt;&gt; 16) + (sum &amp; 0xffff);
 sum += (sum &gt;&gt; 16);

 return ~sum;
}

int main (void)
{
 //Create a raw socket
 int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);
 //Datagram to represent the packet
 char datagram[4096];
 //IP header
 struct iphdr *iph = (struct iphdr *) datagram;
 //TCP header
 struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
 struct sockaddr_in sin;

 sin.sin_family = AF_INET;
 sin.sin_port = htons(40);
 sin.sin_addr.s_addr = inet_addr (&quot;60.61.62.63&quot;);

 memset (datagram, 0, 4096); /* zero out the buffer */

 //Fill in the IP Header
 iph-&gt;ihl = 5;
 iph-&gt;version = 4;
 iph-&gt;tos = 0;
 iph-&gt;tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
 iph-&gt;id = htonl (54321); //Id of this packet
 iph-&gt;frag_off = 0;
 iph-&gt;ttl = 255;
 iph-&gt;protocol = 6;
 iph-&gt;check = 0;  //Set to 0 before calculating checksum
 iph-&gt;saddr = inet_addr (&quot;1.2.3.4&quot;); //Spoof the source ip address
 iph-&gt;daddr = sin.sin_addr.s_addr;

 //TCP Header
 tcph-&gt;source = htons (1234);
 tcph-&gt;dest = htons (85);
 tcph-&gt;seq = random ();
 tcph-&gt;ack_seq = 0;
 tcph-&gt;doff = 0;  /* first and only tcp segment */
 tcph-&gt;syn = 1;
 tcph-&gt;window = htonl (65535); /* maximum allowed window size */
 tcph-&gt;check = 0;/* if you set a checksum to zero, your kernel's IP stack
    should fill in the correct checksum during transmission */
 tcph-&gt;urg_ptr = 0;
 //Now the IP checksum
 iph-&gt;check = csum ((unsigned short *) datagram, iph-&gt;tot_len &gt;&gt; 1);

 //IP_HDRINCL to tell the kernel that headers are included in the packet
 {
  int one = 1;
  const int *val = &amp;one;
  if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) &lt; 0)
   printf (&quot;Warning: Cannot set HDRINCL!\n&quot;);
 }

 while (1)
 {
  //Send the packet
  if (sendto (s,  /* our socket */
     datagram, /* the buffer containing headers and data */
     iph-&gt;tot_len, /* total length of our datagram */
     0,  /* routing flags, normally always 0 */
     (struct sockaddr *) &amp;sin, /* socket addr, just like in */
     sizeof (sin)) &lt; 0)  /* a normal send() */
   printf (&quot;error\n&quot;);
  else
   printf (&quot;.&quot;);
 }

 return 0;
}
</pre>
<p>Remember to run the above code with root privileges. Raw sockets require root privileges</p>
<p>User wireshark to check the output.</p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=60&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/raw-sockets-c-code-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>TCP Connect Port Scanner with Linux Sockets (BSD)</title>
		<link>http://www.binarytides.com/blog/tcp-connect-port-scanner-with-linux-sockets-bsd/</link>
		<comments>http://www.binarytides.com/blog/tcp-connect-port-scanner-with-linux-sockets-bsd/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 17:24:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=51</guid>
		<description><![CDATA[TCP Connect Port Scanner works by trying to establish a connection with every port that is being scanned. If a connectio is established then the port is open otherwise closed.
The steps are simple :

1. Create a socket2. Run a Loop to connect with each port on the remote system ; if connection established then port [...]]]></description>
			<content:encoded><![CDATA[<p>TCP Connect Port Scanner works by trying to establish a connection with every port that is being scanned. If a connectio is established then the port is open otherwise closed.</p>
<p>The steps are simple :</p>
<p><span id="more-51"></span></p>
<p>1. Create a socket<br />2. Run a Loop to connect with each port on the remote system ; if connection established then port open otherwise closed.</p>
<p><b>Code</b> :</p>
<pre class="brush: cpp;">
#include&lt;stdio.h&gt;
#include&lt;sys/socket.h&gt;
#include&lt;netinet/in.h&gt;
#include&lt;errno.h&gt;
#include&lt;netdb.h&gt;
#include&lt;string.h&gt;

int main(int argc , char **argv)
{
 struct hostent *host;
 int err, i , net ,start , end;
 char hostname[100];
 struct sockaddr_in sa;
 //Get the hostname to scan
 printf(&quot;Enter hostname or IP : &quot;);
 gets(hostname);
 //Get start port number
 printf(&quot;\nEnter start port number : &quot;);
 scanf(&quot;%d&quot; , &amp;start);
 //Get end port number
 printf(&quot;\nEnter end port number : &quot;);
 scanf(&quot;%d&quot; , &amp;end);

 //Initialise the sockaddr_in structure
 strncpy((char*)&amp;sa , &quot;&quot; , sizeof sa);
 sa.sin_family = AF_INET;

 if(isdigit(hostname[0]))
 {
  printf(&quot;Doing inet_addr...&quot;);
  sa.sin_addr.s_addr = inet_addr(hostname);
  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 , sizeof sa.sin_addr);
  printf(&quot;Done\n&quot;);
 }
 else
 {
  herror(hostname);
  exit(2);
 }
 //Start the port scan loop
 printf(&quot;Starting the portscan loop : \n&quot;);
 for(i=start ; i&lt;=end ; i++)
 {
  //Fill in the port number
  sa.sin_port = htons(i);
  //Create a socket of type internet
  net = socket(AF_INET , SOCK_STREAM , 0);
  //Check whether socket created fine or not
  if(net &lt; 0)
  {
   perror(&quot;\nSocket&quot;);
   exit(1);
  }
  //Connect using that socket and sockaddr structure
  err = connect(net , (struct sockaddr*)&amp;sa , sizeof sa);

  if(err&lt;0)
  {
   printf(&quot;%s %-5d %s\r&quot; , hostname , i, strerror(errno));
   fflush(stdout);
  }
  else
  {
   printf(&quot;%s %-5d accepted. \n&quot;,  hostname , i);
   //Now shutdown the read and write operations on this socket
   if(shutdown(net , SHUT_RDWR) &lt; 0)
   {
    //Print error with error message mapped from err_no
    perror(&quot;\nShutdown&quot;);
    exit(1);
   }
  }
  close(net);
 }
 printf(&quot;\r&quot;);
 fflush(stdout);
 return(0);
}
</pre>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=51&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/tcp-connect-port-scanner-with-linux-sockets-bsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C Packet Sniffer Code with Libpcap and Linux Sockets (BSD)</title>
		<link>http://www.binarytides.com/blog/c-packet-sniffer-code-with-libpcap-and-linux-sockets-bsd/</link>
		<comments>http://www.binarytides.com/blog/c-packet-sniffer-code-with-libpcap-and-linux-sockets-bsd/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 13:51:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=49</guid>
		<description><![CDATA[Libpcap is a packe capture library which can be used to sniff packets or network traffic over a network interface. Pcap Documentation gives a description of the methods and data structures available in the libpcap library.

To install libpcap on your linux distro you can either download the source from the website and compile it and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.tcpdump.org/">Libpcap</a> is a packe capture library which can be used to sniff packets or network traffic over a network interface. <a href="http://www.tcpdump.org/pcap3_man.html">Pcap Documentation</a> gives a description of the methods and data structures available in the libpcap library.</p>
<p><span id="more-49"></span></p>
<p>To install libpcap on your linux distro you can either download the source from the <a href="http://www.tcpdump.org/">website</a> and compile it and install. Or if you are on a distro like ubuntu then it can be installed from synaptic package manager. In the list of packages in Synaptic Package Manager look for 2 packages named as libpcap0.8 and libpcap0.8-dev. Install both of them.</p>
<p>To start with the C program the simple steps would be :</p>
<p>1. Find all available devices &#8211; find_alldevs()</p>
<p>find_alldevs() is the function which can be used to get a list of all available network devices or interfaces present on the machine or which can be opened by pcap_open_live() for sniffing purpose.</p>
<p>The prototype is as :</p>
<p>int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)</p>
<p>where alldevsp is a pointer to an array of of pcap_if_t structures and errbuf is a character pointer and will contain any error message that occured during the function call.</p>
<p>2. Select a device for sniffing data &#8211; pcap_open_live()</p>
<p>pcap_open_live() is the function to get a packet capture descriptor or a handle to a device which has been opened up for sniffing. The protoype is as :</p>
<p>pcap_t *pcap_open_live(const char *device, int snaplen,int promisc, int to_ms, char *errbuf)</p>
<p>device &#8211; is the name of the device as obtained from the call to pcap_findalldevs.<br />
snaplen &#8211; is the maximum amount of data to be captured. 65536 should be sufficient length.<br />
promisc &#8211; 0 or 1 to indicate whether to open the device in promiscuous mode.<br />
to_ms &#8211; the timeout in milliseconds , 0 for no timeout<br />
errbuf &#8211; buffer to contain any error message</p>
<p>It returns a device handler in the form of the structure pcap_t which can be used by pcap_loop() to capture data from.</p>
<p>3. Start sniffing the device &#8211; pcap_loop()<br />
4. Process the sniffed packet &#8211; user defined callback method</p>
<p><strong>Code</strong> :</p>
<pre class="brush: cpp;">

 /*
 Packet sniffer using libpcap library
*/
#include&lt;pcap.h&gt;
#include&lt;stdio.h&gt;
#include&lt;net/ethernet.h&gt;
#include&lt;netinet/ip_icmp.h&gt; //Provides declarations for icmp header
#include&lt;netinet/udp.h&gt; //Provides declarations for udp header
#include&lt;netinet/tcp.h&gt; //Provides declarations for tcp header
#include&lt;netinet/ip.h&gt; //Provides declarations for ip header

void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
void process_ip_packet(unsigned char* , int);
void print_ip_header(unsigned char* , int);
void print_tcp_header(unsigned char* buffer , int size);
void print_udp_header(unsigned char* , int);

FILE *logfile;
struct sockaddr_in source,dest;

int main()
{
 pcap_if_t alldevsp[100] , *device;
 pcap_t *handle; //Handle of the device that shall be sniffed

 char errbuf[100] , *devname , **devs;
 int count = 1 , n;
 //First get the list of available devices
 printf(&quot;Finding available devices ... &quot;);
 if(pcap_findalldevs(&amp;alldevsp, errbuf))
 {
  printf(&quot;Error finding devices : %s&quot; , errbuf);
  exit(1);
 }
 printf(&quot;Done&quot;);
 //Print the available devices
 printf(&quot;\nAvailable Devices are :\n&quot;);
 device = alldevsp;
 while(device != NULL)
 {
  *(devs + count) = device-&gt;name;
  printf(&quot;%d. %s - %s\n&quot;, count++ , device-&gt;name , device-&gt;description);
  device = device-&gt;next;

 }
 //Ask user which device to sniff
 printf(&quot;Enter the number of the device you want to sniff : &quot;);
 scanf(&quot;%d&quot; , &amp;n);
 devname = *(devs + count - 1);
 //Open the device for sniffing
 printf(&quot;Opening device for sniffing ... &quot;);
 handle = pcap_open_live(&quot;eth0&quot; , 65536 , 1 , 0 , errbuf);
 if (handle == NULL) {
  fprintf(stderr, &quot;Couldn't open device eth0 : %s\n&quot; , errbuf);
  exit(1);
 }
 printf(&quot;Done\n&quot;);

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

 //Put the device in sniff loop
 pcap_loop(handle , -1 , process_packet , NULL);
 return 0;
}

void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
 int size = header-&gt;len;
 struct ether_header *ethh;
 ethh = (struct ether_header *)packet;
 //Print the ethernet header in the log file

 if(ntohs(ethh-&gt;ether_type) == ETHERTYPE_IP)
 {

  process_ip_packet(packet + sizeof *ethh , size - sizeof ethh);
  printf(&quot;%d&quot; , sizeof *ethh);
  fflush(stdout);
 }
 return 0;
}

void process_ip_packet(unsigned char* buffer, int size)
{
 //Get the IP Header part of this packet
 struct iphdr *iph = (struct iphdr*)buffer;
 switch (iph-&gt;protocol) //Check the Protocol and do accordingly...
 {
  case 1:  //ICMP Protocol
   //PrintIcmpPacket(Buffer,Size);
   break;
  case 2:  //IGMP Protocol
   break;
  case 6:  //TCP Protocol
   print_tcp_packet(buffer , size);
   break;
  case 17: //UDP Protocol
   print_udp_packet(buffer , size);
   break;
  default: //Some Other Protocol like ARP etc.
   break;
 }
}

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

 struct iphdr *iph = (struct iphdr *)Buffer;
 iphdrlen =iph-&gt;ihl*4;

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

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

 fprintf(logfile,&quot;\n&quot;);
 fprintf(logfile,&quot;IP Header\n&quot;);
 fprintf(logfile,&quot;   |-IP Version        : %d\n&quot;,(unsigned int)iph-&gt;version);
 fprintf(logfile,&quot;   |-IP Header Length  : %d DWORDS or %d Bytes\n&quot;,(unsigned int)iph-&gt;ihl,((unsigned int)(iph-&gt;ihl))*4);
 fprintf(logfile,&quot;   |-Type Of Service   : %d\n&quot;,(unsigned int)iph-&gt;tos);
 fprintf(logfile,&quot;   |-IP Total Length   : %d  Bytes(Size of Packet)\n&quot;,ntohs(iph-&gt;tot_len));
 fprintf(logfile,&quot;   |-Identification    : %d\n&quot;,ntohs(iph-&gt;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)iph-&gt;ttl);
 fprintf(logfile,&quot;   |-Protocol : %d\n&quot;,(unsigned int)iph-&gt;protocol);
 fprintf(logfile,&quot;   |-Checksum : %d\n&quot;,ntohs(iph-&gt;check));
 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 print_tcp_packet(unsigned char* Buffer, int Size)
{
 unsigned short iphdrlen;

 struct iphdr *iph = (struct iphdr *)Buffer;
 iphdrlen = iph-&gt;ihl*4;

 struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen);

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

 print_ip_header(Buffer,Size);

 fprintf(logfile,&quot;\n&quot;);
 fprintf(logfile,&quot;TCP Header\n&quot;);
 fprintf(logfile,&quot;   |-Source Port      : %u\n&quot;,ntohs(tcph-&gt;source));
 fprintf(logfile,&quot;   |-Destination Port : %u\n&quot;,ntohs(tcph-&gt;dest));
 fprintf(logfile,&quot;   |-Sequence Number    : %u\n&quot;,ntohl(tcph-&gt;seq));
 fprintf(logfile,&quot;   |-Acknowledge Number : %u\n&quot;,ntohl(tcph-&gt;ack_seq));
 fprintf(logfile,&quot;   |-Header Length      : %d DWORDS or %d BYTES\n&quot; ,(unsigned int)tcph-&gt;doff,(unsigned int)tcph-&gt;doff*4);
 //fprintf(logfile,&quot;   |-CWR Flag : %d\n&quot;,(unsigned int)tcph-&gt;cwr);
 //fprintf(logfile,&quot;   |-ECN Flag : %d\n&quot;,(unsigned int)tcph-&gt;ece);
 fprintf(logfile,&quot;   |-Urgent Flag          : %d\n&quot;,(unsigned int)tcph-&gt;urg);
 fprintf(logfile,&quot;   |-Acknowledgement Flag : %d\n&quot;,(unsigned int)tcph-&gt;ack);
 fprintf(logfile,&quot;   |-Push Flag            : %d\n&quot;,(unsigned int)tcph-&gt;psh);
 fprintf(logfile,&quot;   |-Reset Flag           : %d\n&quot;,(unsigned int)tcph-&gt;rst);
 fprintf(logfile,&quot;   |-Synchronise Flag     : %d\n&quot;,(unsigned int)tcph-&gt;syn);
 fprintf(logfile,&quot;   |-Finish Flag          : %d\n&quot;,(unsigned int)tcph-&gt;fin);
 fprintf(logfile,&quot;   |-Window         : %d\n&quot;,ntohs(tcph-&gt;window));
 fprintf(logfile,&quot;   |-Checksum       : %d\n&quot;,ntohs(tcph-&gt;check));
 fprintf(logfile,&quot;   |-Urgent Pointer : %d\n&quot;,tcph-&gt;urg_ptr);
 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,tcph-&gt;doff*4);

 fprintf(logfile,&quot;Data Payload\n&quot;);
 PrintData(Buffer + iphdrlen + tcph-&gt;doff*4 , (Size - tcph-&gt;doff*4-iph-&gt;ihl*4) );

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

void print_udp_packet(unsigned char *Buffer , int Size)
{

 unsigned short iphdrlen;

 struct iphdr *iph = (struct iphdr *)Buffer;
 iphdrlen = iph-&gt;ihl*4;

 struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen);

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

 print_ip_header(Buffer,Size);   

 fprintf(logfile,&quot;\nUDP Header\n&quot;);
 fprintf(logfile,&quot;   |-Source Port      : %d\n&quot; , ntohs(udph-&gt;source));
 fprintf(logfile,&quot;   |-Destination Port : %d\n&quot; , ntohs(udph-&gt;dest));
 fprintf(logfile,&quot;   |-UDP Length       : %d\n&quot; , ntohs(udph-&gt;len));
 fprintf(logfile,&quot;   |-UDP Checksum     : %d\n&quot; , ntohs(udph-&gt;check));

 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 udph);

 fprintf(logfile,&quot;Data Payload\n&quot;);
 PrintData(Buffer + iphdrlen + sizeof udph ,( Size - sizeof udph - iph-&gt;ihl * 4 ));

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

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

 struct iphdr *iph = (struct iphdr *)Buffer;
 iphdrlen = iph-&gt;ihl*4;

 struct icmphdr *icmph = (struct icmphdr *)(Buffer + iphdrlen);

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

 print_ip_header(Buffer , Size);

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

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

 if((unsigned int)(icmph-&gt;type) == 11)
  fprintf(logfile,&quot;  (TTL Expired)\n&quot;);
 else if((unsigned int)(icmph-&gt;type) == ICMP_ECHOREPLY)
  fprintf(logfile,&quot;  (ICMP Echo Reply)\n&quot;);
 fprintf(logfile,&quot;   |-Code : %d\n&quot;,(unsigned int)(icmph-&gt;code));
 fprintf(logfile,&quot;   |-Checksum : %d\n&quot;,ntohs(icmph-&gt;checksum));
 //fprintf(logfile,&quot;   |-ID       : %d\n&quot;,ntohs(icmph-&gt;id));
 //fprintf(logfile,&quot;   |-Sequence : %d\n&quot;,ntohs(icmph-&gt;sequence));
 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 icmph);

 fprintf(logfile,&quot;Data Payload\n&quot;);
 PrintData(Buffer + iphdrlen + sizeof icmph , (Size - sizeof icmph - iph-&gt;ihl * 4));

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

void PrintData (unsigned char* data , int Size)
{
 int i,j;
 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;);
  fprintf(logfile,&quot; %02X&quot;,(unsigned int)data[i]);

  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;);
  }
 }
}   
</pre>
<p>Compile : gcc sniffer.c -lpcap -o sniffer<br />
Run : sudo ./sniffer</p>
<p>The program requires superuser or root privileges to be able to sniff the packets.<br />
Wireshark(previously ethereal) and tcpdump are examples of applications which use the libpcap library on linux to capture packet data.</p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=49&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/c-packet-sniffer-code-with-libpcap-and-linux-sockets-bsd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Packet Sniffer Code in C using Linux Sockets (BSD)</title>
		<link>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd/</link>
		<comments>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 08:50:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=48</guid>
		<description><![CDATA[To code a sniffer in C (Linux) the steps would be :
1. Create a Raw Socket.
2. Put it in a recvfrom loop.
A raw socket when put in recvfrom receives all incoming packets. The following code shows an example of such a sniffer. Note that it sniffs only incoming packets. For sniffing all traffic on a [...]]]></description>
			<content:encoded><![CDATA[<p>To code a sniffer in C (Linux) the steps would be :</p>
<p>1. Create a Raw Socket.<br />
2. Put it in a recvfrom loop.</p>
<p>A raw socket when put in recvfrom receives all incoming packets. The following code shows an example of such a sniffer. Note that it sniffs only incoming packets. For sniffing all traffic on a network a packet capture library like libpcap can be used.</p>
<p><span id="more-48"></span></p>
<p><strong>Code </strong> : sniffer.c</p>
<pre class="brush: cpp;">
#include&lt;netinet/in.h&gt;
#include&lt;errno.h&gt;
#include&lt;netdb.h&gt;
#include&lt;stdio.h&gt;	//For standard things
#include&lt;netinet/ip_icmp.h&gt;	//Provides declarations for icmp header
#include&lt;netinet/udp.h&gt;	//Provides declarations for udp header
#include&lt;netinet/tcp.h&gt;	//Provides declarations for tcp header
#include&lt;netinet/ip.h&gt;	//Provides declarations for ip header
#include&lt;sys/socket.h&gt;
#include&lt;arpa/inet.h&gt;
#include&lt;sys/ioctl.h&gt;
#include&lt;sys/time.h&gt;
#include&lt;sys/types.h&gt;
#include&lt;unistd.h&gt;

void ProcessPacket(unsigned char* , int);
void print_ip_header(unsigned char* , int);
void print_tcp_header(unsigned char* buffer , int size);
void print_udp_header(unsigned char* , int);

int sock_raw;
FILE *logfile;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct sockaddr_in source,dest;

int main()
{
	int saddr_size , data_size;
	struct sockaddr_in saddr;
	struct in_addr in;

	unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!

	logfile=fopen(&quot;log.txt&quot;,&quot;w&quot;);
	if(logfile==NULL) printf(&quot;Unable to create file.&quot;);
	printf(&quot;Starting...\n&quot;);
	//Create a raw socket that shall sniff
	sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
	if(sock_raw &lt; 0)
	{
		printf(&quot;Socket Error\n&quot;);
		return 1;
	}
	while(1)
	{
		saddr_size = sizeof saddr;
		//Receive a packet
		data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &amp;saddr , &amp;saddr_size);
		if(data_size &lt;0 )
		{
			printf(&quot;Recvfrom error , failed to get packets\n&quot;);
			return 1;
		}
		//Now process the packet
		ProcessPacket(buffer , data_size);
	}
	close(sock_raw);
	printf(&quot;Finished&quot;);
	return 0;
}

void ProcessPacket(unsigned char* buffer, int size)
{
	//Get the IP Header part of this packet
	struct iphdr *iph = (struct iphdr*)buffer;
	++total;
	switch (iph-&gt;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;
			print_tcp_packet(buffer , size);
			break;

		case 17: //UDP Protocol
			++udp;
			print_udp_packet(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 print_ip_header(unsigned char* Buffer, int Size)
{
	unsigned short iphdrlen;

	struct iphdr *iph = (struct iphdr *)Buffer;
	iphdrlen =iph-&gt;ihl*4;

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

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

	fprintf(logfile,&quot;\n&quot;);
	fprintf(logfile,&quot;IP Header\n&quot;);
	fprintf(logfile,&quot;   |-IP Version        : %d\n&quot;,(unsigned int)iph-&gt;version);
	fprintf(logfile,&quot;   |-IP Header Length  : %d DWORDS or %d Bytes\n&quot;,(unsigned int)iph-&gt;ihl,((unsigned int)(iph-&gt;ihl))*4);
	fprintf(logfile,&quot;   |-Type Of Service   : %d\n&quot;,(unsigned int)iph-&gt;tos);
	fprintf(logfile,&quot;   |-IP Total Length   : %d  Bytes(Size of Packet)\n&quot;,ntohs(iph-&gt;tot_len));
	fprintf(logfile,&quot;   |-Identification    : %d\n&quot;,ntohs(iph-&gt;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)iph-&gt;ttl);
	fprintf(logfile,&quot;   |-Protocol : %d\n&quot;,(unsigned int)iph-&gt;protocol);
	fprintf(logfile,&quot;   |-Checksum : %d\n&quot;,ntohs(iph-&gt;check));
	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 print_tcp_packet(unsigned char* Buffer, int Size)
{
	unsigned short iphdrlen;

	struct iphdr *iph = (struct iphdr *)Buffer;
	iphdrlen = iph-&gt;ihl*4;

	struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen);

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

	print_ip_header(Buffer,Size);

	fprintf(logfile,&quot;\n&quot;);
	fprintf(logfile,&quot;TCP Header\n&quot;);
	fprintf(logfile,&quot;   |-Source Port      : %u\n&quot;,ntohs(tcph-&gt;source));
	fprintf(logfile,&quot;   |-Destination Port : %u\n&quot;,ntohs(tcph-&gt;dest));
	fprintf(logfile,&quot;   |-Sequence Number    : %u\n&quot;,ntohl(tcph-&gt;seq));
	fprintf(logfile,&quot;   |-Acknowledge Number : %u\n&quot;,ntohl(tcph-&gt;ack_seq));
	fprintf(logfile,&quot;   |-Header Length      : %d DWORDS or %d BYTES\n&quot; ,(unsigned int)tcph-&gt;doff,(unsigned int)tcph-&gt;doff*4);
	//fprintf(logfile,&quot;   |-CWR Flag : %d\n&quot;,(unsigned int)tcph-&gt;cwr);
	//fprintf(logfile,&quot;   |-ECN Flag : %d\n&quot;,(unsigned int)tcph-&gt;ece);
	fprintf(logfile,&quot;   |-Urgent Flag          : %d\n&quot;,(unsigned int)tcph-&gt;urg);
	fprintf(logfile,&quot;   |-Acknowledgement Flag : %d\n&quot;,(unsigned int)tcph-&gt;ack);
	fprintf(logfile,&quot;   |-Push Flag            : %d\n&quot;,(unsigned int)tcph-&gt;psh);
	fprintf(logfile,&quot;   |-Reset Flag           : %d\n&quot;,(unsigned int)tcph-&gt;rst);
	fprintf(logfile,&quot;   |-Synchronise Flag     : %d\n&quot;,(unsigned int)tcph-&gt;syn);
	fprintf(logfile,&quot;   |-Finish Flag          : %d\n&quot;,(unsigned int)tcph-&gt;fin);
	fprintf(logfile,&quot;   |-Window         : %d\n&quot;,ntohs(tcph-&gt;window));
	fprintf(logfile,&quot;   |-Checksum       : %d\n&quot;,ntohs(tcph-&gt;check));
	fprintf(logfile,&quot;   |-Urgent Pointer : %d\n&quot;,tcph-&gt;urg_ptr);
	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,tcph-&gt;doff*4);

	fprintf(logfile,&quot;Data Payload\n&quot;);
	PrintData(Buffer + iphdrlen + tcph-&gt;doff*4 , (Size - tcph-&gt;doff*4-iph-&gt;ihl*4) );

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

void print_udp_packet(unsigned char *Buffer , int Size)
{

	unsigned short iphdrlen;

	struct iphdr *iph = (struct iphdr *)Buffer;
	iphdrlen = iph-&gt;ihl*4;

	struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen);

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

	print_ip_header(Buffer,Size);			

	fprintf(logfile,&quot;\nUDP Header\n&quot;);
	fprintf(logfile,&quot;   |-Source Port      : %d\n&quot; , ntohs(udph-&gt;source));
	fprintf(logfile,&quot;   |-Destination Port : %d\n&quot; , ntohs(udph-&gt;dest));
	fprintf(logfile,&quot;   |-UDP Length       : %d\n&quot; , ntohs(udph-&gt;len));
	fprintf(logfile,&quot;   |-UDP Checksum     : %d\n&quot; , ntohs(udph-&gt;check));

	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 udph);

	fprintf(logfile,&quot;Data Payload\n&quot;);
	PrintData(Buffer + iphdrlen + sizeof udph ,( Size - sizeof udph - iph-&gt;ihl * 4 ));

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

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

	struct iphdr *iph = (struct iphdr *)Buffer;
	iphdrlen = iph-&gt;ihl*4;

	struct icmphdr *icmph = (struct icmphdr *)(Buffer + iphdrlen);

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

	print_ip_header(Buffer , Size);

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

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

	if((unsigned int)(icmph-&gt;type) == 11)
		fprintf(logfile,&quot;  (TTL Expired)\n&quot;);
	else if((unsigned int)(icmph-&gt;type) == ICMP_ECHOREPLY)
		fprintf(logfile,&quot;  (ICMP Echo Reply)\n&quot;);
	fprintf(logfile,&quot;   |-Code : %d\n&quot;,(unsigned int)(icmph-&gt;code));
	fprintf(logfile,&quot;   |-Checksum : %d\n&quot;,ntohs(icmph-&gt;checksum));
	//fprintf(logfile,&quot;   |-ID       : %d\n&quot;,ntohs(icmph-&gt;id));
	//fprintf(logfile,&quot;   |-Sequence : %d\n&quot;,ntohs(icmph-&gt;sequence));
	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 icmph);

	fprintf(logfile,&quot;Data Payload\n&quot;);
	PrintData(Buffer + iphdrlen + sizeof icmph , (Size - sizeof icmph - iph-&gt;ihl * 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;);
			fprintf(logfile,&quot; %02X&quot;,(unsigned int)data[i]);

		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;);
		}
	}
}
</pre>
<p>Compile : gcc sniffer.c</p>
<p>The program must be run as root user or superuser privileges. e.g. sudo ./a.out in ubuntu<br />
The program creates raw sockets which require root access.</p>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=48&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/packet-sniffer-code-in-c-using-linux-sockets-bsd/feed/</wfw:commentRss>
		<slash:comments>3</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>Permutations of a String</title>
		<link>http://www.binarytides.com/blog/permutations-of-a-string/</link>
		<comments>http://www.binarytides.com/blog/permutations-of-a-string/#comments</comments>
		<pubDate>Sun, 18 Mar 2007 12:11:00 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.binarytides.com/blog/?p=4</guid>
		<description><![CDATA[If the length of a string is n and the total number of places is r then the number of possible permutations is nPr or n!/(n-r)! . That is ofcourse a very simple mathematical relation. Only loops would not be a good idea to generate the permutations when n , r are both unbounded and [...]]]></description>
			<content:encoded><![CDATA[<p>If the length of a string is n and the total number of places is r then the number of possible permutations is nPr or n!/(n-r)! . That is ofcourse a very simple mathematical relation. Only loops would not be a good idea to generate the permutations when n , r are both unbounded and variable. Recursion helps.</p>
<p><span id="more-4"></span></p>
<p>The following program does the task :</p>
<p></p>
<pre class="brush: cpp;">
#include&lt;stdio.h&gt;
#include&lt;conio.h&gt;
#include&lt;string.h&gt;

void permute(char *str,int l,int pos,int r);
void swap(char &amp;a,char &amp;b);
void print_string(char *str,int r);

int main()
{
  char str[10]=&quot;&quot;;
  int l,r;
  printf(&quot;Enter The String : &quot;);
  gets(str);
  l=strlen(str);
  printf(&quot;Enter The Number Of Places To permute on : &quot;);
  scanf(&quot;%d&quot;,&amp;r);
  printf(&quot;The Following Permuations are possible : \n\n&quot;);
  permute(str,l,1,r);
  getch();
  return 0;
}

void permute(char *str,int l,int pos,int r)
{
  //If lock position is on the next character
  //than the limit
  if(pos==r+1)
  {
      print_string(str,r); //print - these are the elements//
      printf(&quot; &quot;);
      return; //and return//
  }
  //true subscript of character in array is pos-1//
  for(int i=pos-1;i&lt;=l-1;i++)
  {
      //swap the first letter with all next letters
      str[pos-1]=str[pos-1]+str[i]-(str[i]=str[pos-1]);
      permute(str,l,pos+1,r);
      //restore the swap{swap : a=a+b-(b=a)}
      str[pos-1]=str[pos-1]+str[i]-(str[i]=str[pos-1]);
  }
}

void print_string(char *str,int r)
{
  for(int i=0;i&lt;r;i++)
      printf(&quot;%c&quot;,str[i]);
}
</pre>
<p>An Output like this comes :</p>
<pre class="brush: cpp;">
Enter The String : abcdef
Enter The Number Of Places To permute on : 4
The Following Permuations are possible :

abcd abce abcf abdc abde abdf abed abec abef abfd abfe abfc acbd acbe acbf acdb
acde acdf aced aceb acef acfd acfe acfb adcb adce adcf adbc adbe adbf adeb adec
adef adfb adfe adfc aecd aecb aecf aedc aedb aedf aebd aebc aebf aefd aefb aefc
afcd afce afcb afdc afde afdb afed afec afeb afbd afbe afbc bacd bace bacf badc
bade badf baed baec baef bafd bafe bafc bcad bcae bcaf bcda bcde bcdf bced bcea
bcef bcfd bcfe bcfa bdca bdce bdcf bdac bdae bdaf bdea bdec bdef bdfa bdfe bdfc
becd beca becf bedc beda bedf bead beac beaf befd befa befc bfcd bfce bfca bfdc
bfde bfda bfed bfec bfea bfad bfae bfac cbad cbae cbaf cbda cbde cbdf cbed cbea
cbef cbfd cbfe cbfa cabd cabe cabf cadb cade cadf caed caeb caef cafd cafe cafb
cdab cdae cdaf cdba cdbe cdbf cdeb cdea cdef cdfb cdfe cdfa cead ceab ceaf ceda
cedb cedf cebd ceba cebf cefd cefb cefa cfad cfae cfab cfda cfde cfdb cfed cfea
cfeb cfbd cfbe cfba dbca dbce dbcf dbac dbae dbaf dbea dbec dbef dbfa dbfe dbfc
dcba dcbe dcbf dcab dcae dcaf dcea dceb dcef dcfa dcfe dcfb dacb dace dacf dabc
dabe dabf daeb daec daef dafb dafe dafc deca decb decf deac deab deaf deba debc
debf defa defb defc dfca dfce dfcb dfac dfae dfab dfea dfec dfeb dfba dfbe dfbc
ebcd ebca ebcf ebdc ebda ebdf ebad ebac ebaf ebfd ebfa ebfc ecbd ecba ecbf ecdb
ecda ecdf ecad ecab ecaf ecfd ecfa ecfb edcb edca edcf edbc edba edbf edab edac
edaf edfb edfa edfc eacd eacb eacf eadc eadb eadf eabd eabc eabf eafd eafb eafc
efcd efca efcb efdc efda efdb efad efac efab efbd efba efbc fbcd fbce fbca fbdc
fbde fbda fbed fbec fbea fbad fbae fbac fcbd fcbe fcba fcdb fcde fcda fced fceb
fcea fcad fcae fcab fdcb fdce fdca fdbc fdbe fdba fdeb fdec fdea fdab fdae fdac
fecd fecb feca fedc fedb feda febd febc feba fead feab feac facd face facb fadc
fade fadb faed faec faeb fabd fabe fabc
</pre>
<img src="http://www.binarytides.com/blog/?ak_action=api_record_view&id=4&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.binarytides.com/blog/permutations-of-a-string/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
