My Proxy

There are many HTTP proxies available on the Internet, probably the most well-known of which is Squid. Most of them can use external “filter” programs to define how the HTTP request is handled, which would be a fine way to spoof a response. I didn’t really fancy running something as heavy as Squid just for the rabbit, and I already had Apache running, so I’ve just tweaked the Apache config file a little and written a simple PHP script to define what happens to the HTTP requests from the rabbit.

For testing (to make sure that proxying worked as a concept, and to see how the Nabaztag interacted with a proxy) I installed Tinyproxy and made it listen on port 4453 (which is where I told my Nabaztag to send it’s HTTP requests). This worked well, and whenever I suspected that my proxy wasn’t working, I could stop Apache and start Tinyproxy to see if that worked any better.

My Apache config basically makes Apache listen listen on port 4453 and send all requests made to this port to a particular PHP script:

Listen 4453
NameVirtualHost *:4453
<VirtualHost *:4453>
  ServerName rivendell.local
  DocumentRoot /home/nabaztag/
  <Directory /home/nabaztag/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
  </Directory>

  RewriteEngine On
  RewriteRule .* /home/nabaztag/proxy.php/$0

  ErrorLog /home/nabaztag/error.log
  LogLevel warn
  CustomLog /home/nabaztag/access.log combined

</VirtualHost>

UPDATE: I’ve modified the proxy, and made a new page for it at My Nabaztag Proxy. This page is here for historical interest, or something like that.

My Apache/PHP proxy script currently looks like this:

<?php
    logmsg( '['.date('H:i:s').'] Request: '.$_SERVER['REQUEST_URI']."\n");
 
    if ($_GET['st'] == '00') {
        $data = getfromlive();
    } else {
        $data = getfromlive();
#        $data = getpacket();
    }
    echo $data;
 
    for( $i=0; $i<strlen($data); $i++ ) {
        logmsg( dechex(ord(substr($data,$i,1)))." " );
    }
    logmsg("\n");
 
    function logmsg($msg) {
#        return true;
        $fp = @fopen( 'log.txt', 'a' );
        if ($fp) {
            fwrite( $fp, $msg );
            fclose( $fp );
        }
    }
 
    function getfromfile() {
        $data = file_get_contents('program.hex');
        $storedhash = file_get_contents('hash.firmware');
        if (md5($data) == $storedhash) {
            return '';
        } else {
            $storedhash = md5($data);
            file_put_contents('hash.firmware', $storedhash);
            return $data;
        }
    }
 
    function getfromlive() {
        logmsg( '* ' );
        $url = $_SERVER['REQUEST_URI'];
        return file_get_contents($url);
    }
 
    function getping() {
        $res = array();
        $res[] = 0x3; // 0 3
        $res[] = 0x0;
        $res[] = 0x0;
        $res[] = 0x1;
        $res[] = 0x1;   // Time * 10secs until next request
        return array_reduce($res, 'reduceArray');
    }
 
    function reduceArray($cumulative, $element) {
        $cumulative.= chr($element);
        return $cumulative;
    }
 
    function getsrc() {
        $data = file_get_contents('src.values');
        $storedhash = file_get_contents('hash.src');
        if (md5($data) == $storedhash) {
            return '';
        } else {
            $storedhash = md5($data);
            file_put_contents('hash.src', $storedhash);
            $data = trim($data);
            $lines = explode("\n", $data);
            $res = array();
            foreach($lines as $line) {
                $val = hexdec(trim($line));
                $res[] = $val;
            }
            return array_reduce($res, 'reduceArray');
        }
    }
 
    function getpacket() {
        $data = chr(0x7f);
        $data.= getfromfile();
        $data.= getsrc();
        $data.= getping();
        $data.= chr(0xff).chr(0xd).chr(0xa).chr(0xd).chr(0xa);
        return $data;
    }
 

This script is, erm, somewhat hacky, but it works. With the call to the “getfromlive()” function uncommented and the call to the “getpacket()” commented, the script will just pass the request straight on to the Violet server (and proxy the response back to the rabbit). With those function calls commented the other way around, the script will deliver an HTTP response with up to 3 things in it:

  1. A new firmware to run on the rabbit’s virtual machine
  2. A new set of data for the VM’s “SRC” registers
  3. An instruction for when to make the next HTTP request

These requests are all sourced locally, apart from the initial bootup packet. You can make the response to the bootup packet to be sourced locally by changing the “if ($_GET[’st’] == ‘00’)” bit of the code (the Nabaztag sets st=00 on bootup, and st=01 at all other times).

The last of these is always sent, and the above PHP script tells the rabbit to make a new request in 10 seconds’ time. You can change this (I think in increments of seconds) by changing the line commented in the “getping()” function. Making this 0 will cause the rabbit to flood the network with requests, which could be useful when testing, except for some reason the rabbit isn’t very good at talking to my wireless network.

The firmware is sourced from a file called “program.hex”. The script keeps an MD5 hash of this firmware in a file (”hash.firmware”) so it doesn’t have to send the firmware in every response. To cause the proxy to re-send the firmware, just reset the contents of this file by running:

echo -n > hash.firmware

The contents of the (up to) 63 memory locations which can be set remotely are stored in a file called “src.values”. Again, an MD5 hash is used to decide whether to re-send this information. The src.values file stores the entire type 4 packet to send - I haven’t used this functionality very much; I’ll probably refine this (to just specify a byte per line without the packet header) when I do start using this packet.

This script will also log every request and response into a file called “log.txt”. You can disable this by uncommenting the “return true” line in the “logmsg” function.

 
my-proxy.txt · Last modified: 2007/04/21 18:37
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki