Showing posts with label Coding. Show all posts
Showing posts with label Coding. Show all posts

Monday, March 31, 2008

Print hex stream byte array & ASCII representation (Java)

I have found it useful to print the raw hex stream & it's ASCII representation of the network traffic to help debug some protocol issues.

Here is a Java function to take a hex byte array and print it out to the STDOUT_FILENO



public static void prettyPrintHex(byte[] data) {

    int i = 0, j = 0;   // loop counters

    int line_addr = 0;  // memmory address printed on the left

    String line_to_print = "";

    if (data.length == 0) {

        return;

    }

 

    StringBuilder _sbbuffer = new StringBuilder();

 

    //Loop through every input byte

    String _hexline = "";

    String _asciiline = "";

    for (i = 0, line_addr = 0; i < data.length; i++, line_addr++) {

        //Print the line numbers at the beginning of the line

        if ((i % 16) == 0) {

            if (i != 0) {

                _sbbuffer.append(_hexline);

                _sbbuffer.append("\t...\t");

                _sbbuffer.append(_asciiline + "\n");

            }

            _asciiline = "";

            _hexline = String.format("%#06x ", line_addr);

        }

 

        _hexline = _hexline.concat(String.format("%#04x ", data[i]));

        if (data[i] > 31 && data[i] < 127) {

            _asciiline = _asciiline.concat(String.valueOf((char) data[i]));

        } else {

            _asciiline = _asciiline.concat(".");

        }

    }

    // Handle the ascii for the final line, which may not be completely filled.

    if (i % 16 > 0) {

        for (j = 0; j < 16 - (i % 16); j++) {

            _hexline = _hexline.concat("     ");

        }

        _sbbuffer.append(_hexline);

        _sbbuffer.append("\t...\t");

        _sbbuffer.append(_asciiline);

    }

    System.out.println(_sbbuffer.toString());

}

Saturday, March 15, 2008

VM On USB: Carry your OS on USB!

Ever wanted to carry your desktop environment with you?

An easy way would be to put your desktop environment(s) on a mass storage device along with the VMPlayer MSI and have a small executable that would take care of install/uninstall of VMWare Player and launching your VM(s).

Here is a small tool in C# for doing this. Here is how it looks:





These images above show the following sequence:

1. Installs VMWare Player.
2. Launches VM(s)
3. Uninstalls VmWare Player.

The code follows the same sequence as well.

The directory structure on the USB would look like:



Here are some files associated with it:

USB-OS(F:)
|---- autorun.inf
|---- config.icon
|---- VMOnUSB.exe
|---- LICENSE.txt
|---- vmplayer-installer
     |----VMware Player.msi
|---- images
     |---- DamnSmallLinux3.4
          |---- DamnSmallLinux3.4.png
          |---- dsl.vmx

Source can be downloaded from [http://tomaranand.googlepages.com/VMOnUSB-src.zip]

VM(s) can be downloaded from [http://www.vmware.com/appliances/]

Sunday, November 25, 2007

Using Libpcap

Libpcap (pcap) is a high level OpenSource API for packet-capturing framework. I was surprised to find out how ridiculously easy it is to use :-)

libpcap can be downloaded at: http://www.tcpdump.org/

To do packet-sniffing using libpcap you need to:
  1. Setup an interface to listen on. You can listen on all the available interfaces if you like.
  2. Filtering network traffic.
  3. Doing the real sniffing.
The people at Berkley did a great job in making this API so easy to use.

Setting up an interface.
This is very easy. You have 2 options:
  • pcap_lookupdev



    char *dev, errbuf[PCAP_ERRBUF_SIZE];

    dev = pcap_lookupdev(errbuf);

    if (dev == NULL)

    {

      fprintf(stderr, "Couldn't find default device: %s\n", errbuf);

      return(2);

    }

    printf("Device: %s\n", dev);




  • pcap_findalldevs


    char *dev, errbuf[PCAP_ERRBUF_SIZE];

    int udev;

    pcap_if_t *alldevsp;

    if(pcap_findalldevs(&alldevsp, errbuf))

    {

      fprintf(stderr, "Couldn't find devices: %s\n", errbuf);

      return(3);

    }

    char *trav = alldevsp;

    printf("Available Device(s): \n");

    while(trav != NULL)

    {

      printf("\t%d) %s\n\t\t%s\n",i++,trav->name,trav->description);

      trav = trav->next;

    }

    printf("Capture on Device (1 - %d): ", (i-1));

    scanf ("%d",&udev);

     

    trav = alldevsp;

    while((udev-1) > 0)

    {

      trav = trav->next;

      udev--;

    }

    dev = trav->name;

    printf("Device: %s\n",dev);



    I am sure there are better ways of doing this. I thought this was the easiest to understand.

    Remember to free the memory:


    pcap_freealldevs(alldevsp);



One really cool thing about pcap is that it provides all the functions with a char ptr to a error string. errbuff should be of size PCAP_ERRBUF_SIZE.

After this you just need to open the device for sniffing.


int promiscuous= 1;

pcap_t *handle = pcap_open_live(dev, BUFSIZ, promiscuous, 1000, errbuf);

if (handle == NULL)

{

  fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);

  return(2);

}


Good practice to close the handle:


pcap_close(handle);



Filtering network traffic.
Yes you can get all the packets and then decide what packets you want to look at OR HAVE BPF DO IT FOR YOU!!!!

This is a two step process.
  1. Compile the filter.
  2. Set the filter.
Easily done :


char *FILTER = "tcp";

struct bpf_program filter_code;

bpf_u_int32 local_net, netmask;

/* Lookup the subnet and mask for the device */

if(pcap_lookupnet(dev, &local_net, &netmask, errbuf) == -1)

  return(3);

/* Compile the BPF filter expression */

if(pcap_compile(handle, &filter_code, FILTER, 1, netmask) == -1)

  return(4);

/* Apply the BPF filter */

if(pcap_setfilter(handle, &filter_code) == -1)

  return(5);



Sniff
Starting sniffing is fairly easy. I am just interested in indefinitely looping (-1) for packets.


pcap_loop(handle, -1, packet_handler, NULL);


packet_handler is the callback function.

Now What
cast cast cast! Do as much casting as possible :)
Here is some snippet form the callback function:


void packet_handler(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet)

{

  printf("length of this packet (off wire): %d\n", pkthdr->len);

  struct ether_header *ethheader;

  struct iphdr *ipheader;

  struct tcphdr *tcpheader;

  struct in_addr source, dest;

 

  ethheader = (struct ether_header *)packet;

  ipheader = (struct iphdr *)(packet + sizeof(struct ether_header));

  tcpheader = (struct tcphdr *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr));

  const char *payload = (u_char *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr));

 

  source.s_addr = ipheader->saddr;

  dest.s_addr = ipheader->daddr;

 

  printf("From: %s:%i\t", inet_ntoa(source), ntohs(tcpheader->source));

  printf("To: %s:%i\n", inet_ntoa(dest), ntohs(tcpheader->dest));

  ........



Now you have the payload do whatever you want to do with it!