<?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>delx &#187; Technical</title>
	<atom:link href="http://delx.net.au/blog/category/technical/feed/" rel="self" type="application/rss+xml" />
	<link>http://delx.net.au/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Fri, 13 Apr 2012 14:05:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Remote Wipe of Debian Linux Server</title>
		<link>http://delx.net.au/blog/2012/04/remote-wipe-of-debian-linux-server/</link>
		<comments>http://delx.net.au/blog/2012/04/remote-wipe-of-debian-linux-server/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 14:05:00 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=351</guid>
		<description><![CDATA[I recently retired an old server of mine, cerberus. It was hosted in a remote data centre to which I have no physical access. My goal was to zero the drives before powering it off for the last time. To wipe the machine properly the kernel must not be using the hard drives anymore. To [...]]]></description>
			<content:encoded><![CDATA[<p>I recently retired an old server of mine, cerberus. It was hosted in a remote data centre to which I have no physical access. My goal was to zero the drives before powering it off for the last time.</p>
<p><span id="more-351"></span></p>
<p>To wipe the machine properly the kernel must not be using the hard drives anymore. To do this pivot_root into a tmpfs mount and then kill all remaining processes. Here are the steps I used. Note these may or may not work for you. If you don&#8217;t understand what something does you should probably not continue! This is more of a set of rough notes in case I need to do this again than any real guide.</p>
<ol>
<li>Shut down as much stuff as possible, you should only have init, random kernel junk, sshd and your shells running</li>
<li>Run these commands:
<pre>
swapoff -a
mkdir /scrubber
mount -t tmpfs scrubber /scrubber
cd /scrubber
zcat /boot/initrd.img-"$(uname -r)" | cpio --extract
for i in dev proc sys; do
    mkdir "$i"
    mount --bind /"$i" "$i"
done
mount --bind /dev/pts dev/pts
cp -H /bin/{bash,rm,ps,pivot_root,nc} bin/
cp -H /lib/libproc*.so lib/
cp -H /lib/libncurses*.so* lib/
echo -e '#!/bin/sh\nsleep 99999' &gt; sbin/init
chmod 0755 sbin/init
mkdir old_root
</pre>
</li>
<li>Now chroot into /scrubber and make sure all the tools you need are there and working. Depending on your distro and version you may need to copy different libraries or copy them from different directories. Use ldd to find them.</li>
<li>Now start a shell with remote access from inside the root:
<pre>echo 'mkfifo inp; nc -lp 9998 &lt; &lt;(bash &lt;inp 2&gt;&#038;1) &gt;inp &amp;' | chroot . /bin/bash</pre>
</li>
<li>Connect to this shell from another PC with <tt> nc yourhost 9998</tt>. You should have a usable shell, no autocomplete or fancies, but usable. Make sure it works before continuing.</li>
<li>Now pivot_root to the tmpfs and tell init to reload from the dummy version. Run these from the SSH shell:
<pre>
pivot_root . old_root
LD_LIBRARY_PATH=/old_root/lib/ /old_root/sbin/telinit u
</pre>
</li>
<li>Close your SSH shell. Go back to your netcat shell and run ps aux. Kill sshd, now there should be no processes running in old_root anymore.</li>
<li>Now unmount stuff. <tt>cat /proc/mounts</tt> in order to find out what stuff is still mounted in the old root. You can lazy unmount  virtual filesystems like <tt>umount -l /dev/pts</tt> for example. But any filesystems on disk should be properly unmounted to ensure the kernel won&#8217;t try to use them again.</li>
<li>If you&#8217;ve reached this point, you should have <tt>cat /proc/mounts /proc/swaps</tt> showing nothing on any hard drives. Now you can just use <tt>dd if=/dev/zero of=/dev/sda bs=1048576</tt> to erase stuff. Run this for each drive.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2012/04/remote-wipe-of-debian-linux-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hulu and Pandora outside USA</title>
		<link>http://delx.net.au/blog/2011/12/hulu-and-pandora-outside-usa/</link>
		<comments>http://delx.net.au/blog/2011/12/hulu-and-pandora-outside-usa/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 07:15:23 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=340</guid>
		<description><![CDATA[Back in 2009 I wrote up a short guide to using Hulu outside USA. I stopped using it and the necessary voodoo has changed slightly. Since that post is so old I&#8217;ve decided to write a new one with the necessary updates. My approach is different to what most people do. The goal is to [...]]]></description>
			<content:encoded><![CDATA[<p>Back in 2009 I wrote up a short guide to using <a href="/blog/2009/03/who-wants-hulu/">Hulu outside USA</a>. I stopped using it and the necessary voodoo has changed slightly. Since that post is so old I&#8217;ve decided to write a new one with the necessary updates.</p>
<p>My approach is different to what most people do. The goal is to access Hulu and Pandora from outside USA, so obviously we have to use a proxy of some kind. However I don&#8217;t want to proxy all my traffic through the USA, as then I would not be able to access Australian specific content. So what I have is a few hacks on my router that tell it to forward only Hulu and Pandora traffic through my USA server.</p>
<p><span id="more-340"></span></p>
<p>Note for people who followed the old guide, this one requires no CGI, lighttpd or apache configuration. I&#8217;ve completely eliminated that part of it.</p>
<h4>Requirements</h4>
<ul>
<li>A machine in the US that you can run programs and serve web pages from.</li>
<li>A Linux machine at home that shares your net connection</li>
</ul>
<h4>For my friends</h4>
<p>You can skip the USA proxy configuration and just use <tt>72.232.203.84</tt> everywhere you would put that server&#8217;s IP.<br />
Make sure you email me and I&#8217;ll add your local IP address to the allow list for the proxy.</p>
<h4>USA Proxy Configuration</h4>
<p>First we need to set up your US server to forward some selected HTTP sites as well as the Flash RTMP video streams. Do these steps on the server in the US:</p>
<ul>
<li>Create a file, usa_proxy.ini with these contents:
<pre>
[proxy]
mode = proxy
listen_port = 9997

[allowed]
host1 = YOUR_LOCAL_IP_OR_DOMAIN
</pre>
<li>Download <a href="http://delx.net.au/hg/jamesstuff/raw-file/tip/scripts/proxy.py">proxy.py</a> and run this command to start forwarding requests on port 9997 from the allowed hosts.
<pre>proxy.py -d usa_proxy.ini</pre>
</li>
</ul>
<h4>Local network</h4>
<p>If you have a Linux router you can configure it to forward all packets destined for Hulu from inside your network to your US server. This setup is most convenient as it gives all computers on your LAN access with further configuration, regardless of their operating system. Otherwise you must set this up on each Linux client separately.</p>
<p>Follow these steps on your Linux router or any other Linux computer:</p>
<ul>
<li>Download <a href="http://delx.net.au/files/huluhosts.txt">huluhosts.txt</a> and append it to your <tt>/etc/hosts</tt> file.</li>
<li>If you&#8217;re using dnsmasq for your LAN&#8217;s DNS server ensure that it reads these addresses from your and resolves them for hosts on your network.</li>
<li>For Hulu, add this to your firewall config:
<pre>
grep 'HULU$' /etc/hosts | awk '{print $1;}' | while read huluip; do
    iptables -t nat -A PREROUTING -i eth0 -p tcp \
        --destination "$huluip" -j REDIRECT --to-ports 9997
    iptables -t nat -A OUTPUT -p tcp \
        --destination "$huluip" -j REDIRECT --to-ports 9997
done
</pre>
</li>
<li>For Pandora, add this to your firewall config:
<pre>
iptables -t nat -A PREROUTING -i eth0 -p tcp \
    --destination 208.85.40.0/21 -j REDIRECT --to-ports 9997
iptables -t nat -A OUTPUT -p tcp \
    --destination 208.85.40.0/21 -j REDIRECT --to-ports 9997
</pre>
</li>
<li>Depending on your other iptables rules you may need to add this somewhere to make the interceptor port allowed:
<pre>
iptables -A INPUT -i eth0 -p tcp --dport 9997 -j ACCEPT
</pre>
</li>
<li>Create a file, proxy_interceptor.ini with these contents:
<pre>
[proxy]
mode = interceptor
listen_port = 9997
host = XXX.YYY.ZZZ.XXX
port = 9997
</pre>
</li>
<li>Download <a href="http://delx.net.au/hg/jamesstuff/raw-file/tip/scripts/proxy.py">proxy.py</a> and run this command to start capturing and forwarding the Hulu content through your US server.
<pre>proxy.py -d proxy_interceptor.ini</pre>
</li>
</ul>
<p>Some ISPs in Australia (Internode, iiNet and others) override the DNS entries for Akamai servers. This is why the modification to <tt>/etc/hosts</tt> is needed. Note that using the rules above, only traffic to specific Akamai Hulu servers will go through your US server. So unmetered ABC iView content will remain unmetered. However, if Hulu adds new servers to this list, or if I&#8217;ve missed some, then things may not work and the hosts file will need updating. See the last section of the blog on how to automate this with a cron job.</p>
<p>If you are having difficulty viewing videos and you suspect that this is the issue, try running your dnsmasq with the <tt>log-queries</tt> option enabled. Then have a look at <tt>/var/log/syslog</tt> to see what names are being looked up. Try resolving them from within USA and add the result to <tt>/etc/hosts</tt></p>
<h4>Automatic <tt>/etc/hosts</tt> updating</h4>
<p>The <tt>/etc/hosts</tt> file is used to know which IP addresses to route over the tunnel to USA. My USA server resolves the Hulu video hosts that I know about and makes them available at this URL: <a href="http://delx.net.au/files/huluhosts.txt">http://delx.net.au/files/huluhosts.txt</a>. This is automatically updated every hour.</p>
<p>I use a daily cronjob on my client machines in order to keep their hosts file up to date. Adapt this to your needs.</p>
<pre>
#!/bin/bash

cp /etc/hosts /etc/hosts.hulubak &#038;&#038;
grep -v HULU /etc/hosts > /etc/_hosts.new &#038;&#038;
curl -s http://delx.net.au/files/huluhosts.txt >> /etc/_hosts.new &#038;&#038;
chmod 0644 /etc/_hosts.new &#038;&#038;
mv /etc/_hosts.new /etc/hosts &#038;&#038;

# Ensure you clear the previous Hulu firewall rules and restart your
# DNS server (if you use one)
/root/hulutables
/etc/init.d/dnsmasq restart > /dev/null
</pre>
<p>Here&#8217;s the script to generate the huluhosts.txt file. This should be run from a machine in the USA so that you get the correct IP addresses.</p>
<pre>
#!/bin/bash

HOSTS="hulu.com www.hulu.com releasegeo.hulu.com urlcheck.hulu.com p.hulu.com s.hulu.com r.hulu.com assets.hulu.com"
OUTFILE="/var/www/huluhosts.txt"

echo -n > "$OUTFILE"
for host in $HOSTS; do
        echo "$(dig +short $host | tail -n 1) $host # HULU" >> "$OUTFILE"
done
</pre>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/12/hulu-and-pandora-outside-usa/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Fix for Nokia Symbian Anna &#8216;Album Artist&#8217; in Music Player</title>
		<link>http://delx.net.au/blog/2011/12/fix-for-nokia-symbian-anna-album-artist-in-music-player/</link>
		<comments>http://delx.net.au/blog/2011/12/fix-for-nokia-symbian-anna-album-artist-in-music-player/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 22:36:08 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=332</guid>
		<description><![CDATA[I&#8217;m enjoying my new Nokia E7 with Symbian Anna, however I&#8217;ve had a problem with the music player and I thought I&#8217;d share the fix. In the Symbian Anna update, Music Player gained support for the album artist tag on music files. See Nokia&#8217;s FAQ: Why my albums are not shown properly after updating to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m enjoying my new Nokia E7 with Symbian Anna, however I&#8217;ve had a problem with the music player and I thought I&#8217;d share the fix. In the Symbian Anna update, Music Player gained support for the album artist tag on music files. See Nokia&#8217;s FAQ: <a href="http://www.nokia.com/us-en/support/faq/?action=singleFAQ&#038;caseid=FA136025_en_US">Why my albums are not shown properly after updating to Symbian Anna?</a>.</p>
<p>This has caused trouble for a lot of people with incorrectly tagged libraries, and I have a work-around for manually correcting the Music Player database.</p>
<p><span id="more-332"></span></p>
<p>The problem is that if you have a compilation album with tracks from several artists, each artist will show up as a separate albums. For MP3s this can be fixed easily by giving all your compilation album tracks an &#8216;album artist&#8217; tag. They will then be grouped correctly.</p>
<p>However this doesn&#8217;t seem to work for AAC/M4A music files, such as those purchased from the iTunes Store. As far as I can tell the Music Player just ignores the &#8216;aART&#8217; atom which is where the album artist field is stored. I&#8217;ve reported this to Nokia and I&#8217;m waiting for their response.</p>
<p>Music Player conveniently stores all its gathered data in an <a href="http://www.sqlite.org">sqlite</a> database which can be edited. As far as I&#8217;m aware if you stuff up this process you can just delete the folder mentioned in step (2) and Music Player will automatically rescan your library from scratch. Here&#8217;s what to do:</p>
<ol>
<li>Connect your phone in USB Mass Storage mode</li>
<li>Navigate to the <tt>Private/10281e17/</tt> folder, the music database should be in a file named like <tt>[101ffc31]mpxv3_2.db</tt>, probably best to backup this file now.</li>
<li>On Mac OS X or Linux you can edit this file using this command:<br /><tt>$ sqlite3 [101ffc31]mpxv3_2.db</tt></li>
<li>You should get an <tt>sqlite&gt;</tt> prompt where you can enter SQL commands to modify the database.</li>
<li>Copy/paste the following SQL commands below to identify the duplicate albums and merge them into one</li>
<li>Press CTRL-D to exit, and you&#8217;re all done! You&#8217;ll probably have to do this again each time you refresh the music library.</li>
</ol>
<p>This technique works well for me, though I wish Nokia would just fix Music Player to understand &#8216;aART&#8217; on AAC files. Also, it&#8217;s worth checking out <a href="http://www.lonelycatgames.com/?app=lcgjukebox">LCG Jukebox</a>. It&#8217;s a great player that works purely on folders and playlists, so you can use whatever organisation scheme you want. It also plays FLAC &#038; OGG, and has automatic bookmarking which is very useful for podcasts and audiobooks.</p>
<h4>SQL to Merge Albums</h4>
<p><code><br />
create temporary table dupalbum(KeepId INTEGER, DuplicateId INTEGER PRIMARY KEY);<br />
insert into dupalbum(KeepId, DuplicateId) select a2.UniqueId as KeepId, a1.UniqueId as UniqueId from Album a1 join (select Name, UniqueId from Album group by Name having count(*) > 1) a2 on a1.Name = a2.Name where a2.UniqueId != a1.UniqueId;<br />
update Music set Album=(select d.KeepId from dupalbum d where d.DuplicateId = Album) where Album in (select d.DuplicateId from dupalbum d);<br />
delete from Album where Album.UniqueId in (select DuplicateId from dupalbum);<br />
drop table dupalbum;<br />
</code></p>
<h4>SQL to Remove Tracks outside the \Sounds\Music\ folder</h4>
<p><code><br />
delete from Music where not Location like '\Sounds\Music\%';<br />
delete from Album where UniqueId not in (select Album from Music);<br />
delete from Artist where UniqueId not in (select Artist from Music);<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/12/fix-for-nokia-symbian-anna-album-artist-in-music-player/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Audible.com on Linux</title>
		<link>http://delx.net.au/blog/2011/07/audible-com-on-linux/</link>
		<comments>http://delx.net.au/blog/2011/07/audible-com-on-linux/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 15:06:50 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=322</guid>
		<description><![CDATA[I wanted to play some audiobooks from Audible.com on various devices as mp3s. These books are distributed in an encrypted .aa format. You can play these in iTunes or Audible Manager. You can also burn them to audio CDs, which is a pain as they can be 20-40 hours long, that&#8217;s a lot of CDs! [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to play some audiobooks from <a href="http://www.audible.com">Audible.com</a> on various devices as mp3s. These books are distributed in an encrypted <tt>.aa</tt> format. You can play these in iTunes or Audible Manager. You can also burn them to audio CDs, which is a pain as they can be 20-40 hours long, that&#8217;s a lot of CDs!</p>
<p><span id="more-322"></span></p>
<p>The files I&#8217;m converting at the moment are mono, 22.05kHz, 32kbps mp3 audio, so I don&#8217;t mind retranscoding them. As I mentioned, they can be very long so I didn&#8217;t want to tie up any of my computers for the entire time. So I will rip these to wav files in a VNC session on my Ubuntu Linux machine. PulseAudio will capture the output from wine and route it to a dummy output. This lets the machine be used for other things, including audio, while the rip is in progress.</p>
<ol>
<li><tt>$ aptitude install wine tightvncserver</tt></li>
<li>Start <tt>vncserver</tt> and connect</li>
<li><tt>$ padsp winecfg</tt> &#8211; configure audio output to OSS</li>
<li>Go to System-&gt;Prefs-&gt;Sound-&gt;Applications and check you can see wine in there. Turn the volume down a little bit so that it won&#8217;t clip.</li>
<li>Install Audible Manager on Linux using wine then add the audio files, no special hacks here</li>
<li>Sometimes the play button doesn&#8217;t start, in that case try using the fast forward and rewind buttons as well to make it play.</li>
<li>Run my <a href="http://delx.net.au/hg/jamesstuff/raw-file/tip/ripping/pulse_rip">pulse_rip</a> script to read the audio and create an mp3</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/07/audible-com-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenWRT and Guest Networks on the Netgear WNDR3700</title>
		<link>http://delx.net.au/blog/2011/06/openwrt-and-guest-networks-on-the-netgear-wndr3700/</link>
		<comments>http://delx.net.au/blog/2011/06/openwrt-and-guest-networks-on-the-netgear-wndr3700/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 03:45:37 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[openwrt]]></category>
		<category><![CDATA[voip]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=283</guid>
		<description><![CDATA[In my house I have Debian Linux running on an old laptop acting as my router with a Netgear WNDR3700 acting as an access point (WAN port on this is unused). The AP is configured with WPA2 security, but recently I wanted to connect my Nintendo DS to the wifi network. Now the Netgear has [...]]]></description>
			<content:encoded><![CDATA[<p>In my house I have Debian Linux running on an old laptop acting as my router with a Netgear WNDR3700 acting as an access point (WAN port on this is unused). The AP is configured with WPA2 security, but recently I wanted to connect my Nintendo DS to the wifi network. Now the Netgear has guest networks, which is pretty much what I wanted, but it only allows the guest wifi access to the WAN port, which was useless to me. I also wanted to be able to conveniently enable and disable the insecure network with a button on the access point. Knowing that the hardware supported what I wanted to do, and having had good experiences with <a href="http://openwrt.org">OpenWRT</a> on another router in the past, I set out to see if I could make it work.</p>
<p><span id="more-283"></span></p>
<p>Now the Netgear factory firmware actually is a heavily stripped down old version of OpenWRT. After reading a few of forum posts and wiki pages I decided that I should go for a bleeding edge snapshot version of OpenWRT (r27153). It&#8217;s all working very well now :)</p>
<h4>Installation</h4>
<p>First thing, I grabbed <tt>openwrt-ar71xx-generic-wndr3700-squashfs-factory.img</tt> from the website and flashed it onto the router using the stock firmware&#8217;s upgrade page. This process went smoothly and rebooted the router. I then used telnet to connect and was prompted to set a password. That disabled telnetd and enables the dropbear ssh server. I also put an ssh public key into <tt>/etc/dropbear/authorized_keys</tt>. So far so good.</p>
<p>OpenWRT uses a squashfs as the base read-only filesystem, with jffs2 set up as an overlay filesystem so you can write to anywhere. You can use the builtin <tt>opkg</tt> package manager to install a bunch of useful software beyond what is built in. Currently I have 2.3M used with 4.2M free :)</p>
<p>I didn&#8217;t bother installing a web interface, instead preferring to do all the configuration using the UCI config files in <tt>/etc/config</tt>. See the <a href="http://wiki.openwrt.org/doc/uci">UCI docs</a> for a description of what to put in all these files. Whenever you start a service, eg dnsmasq using the <tt>/etc/init.d/dnsmasq</tt> script, the appropriate UCI files are read, a temporary native config file for the service is created (if appropriate) and any necessary command line args are generated to start the service.</p>
<h4>Syslog</h4>
<p>If you&#8217;re trying to debug something, you can view the syslog on the device using the <tt>logread</tt> command. The <tt>logger</tt> command will echo its arguments to syslog.</p>
<h4>Wireless Setup</h4>
<p>Most of the <tt>/etc/config/wireless</tt> settings are automatically detected. Just set the encryption to psk2 (WPA2 AES) and put in your preferred passphrase and ssid.</p>
<p>The radios on this device support multiple SSIDs. Each of these shows up as a separate network interface in Linux. I chose &#8216;guest&#8217; as the name for this interface.</p>
<pre>
config wifi-iface
  option device radio0
  option network guest
  option mode ap
  option wmm 0
  option encryption none
  option ssid 'your-guest-ssid'
</pre>
<p>Quick note, I discovered that leaving wmm (Wireless MultiMedia extensions?) enabled (the default) made SIP VoIP calls from my Nokia wifi clients unusable. It&#8217;s easy to disable as seen above.</p>
<h4>Firewall (iptables)</h4>
<p>Now we have our guest wifi network interface, lets set up some firewall rules to isolate it from the main lan.</p>
<p>I&#8217;m not using the WAN port on my WNDR3700. There are three interfaces that are relevant. The ethernet switch and my main wifi are both bridged as &#8216;lan&#8217;. This network is served by DHCP and DNS from my Debian router. It is 192.168.1.0/24. I also have the &#8216;guest&#8217; network, which is not bridged, and gets DHCP and DNS from dnsmasq on the WNDR3700, it uses 192.168.2.0/24. dnsmasq is set to forward DNS requests onto my main router and to explicitly ignore the &#8216;lan&#8217; interface.</p>
<p>The firewall policy is to disallow everything on the guest network except:</p>
<ul>
<li>ICMP</li>
<li>DHCP/DNS requests to dnsmasq on the WNDR3700</li>
<li>Packets from 192.168.2.0/24 not addressed to 192.168.0.0/16</li>
</ul>
<p>That last rule ensures that anything coming from the guest network must be using one of the expected addresses, and also that the guest network cannot send packets to hosts on my main lan. By default OpenWRT allows all related,established packets using Linux iptables&#8217; conntrack module.</p>
<p>Here&#8217;s the complete firewall config I&#8217;m using: <a href="/blog/wp-content/uploads/2011/06/etc_config_firewall.txt"><tt>/etc/config/firewall</tt></a>.</p>
<h4>Routing</h4>
<p>My Debian router also needs to know how to route back to the guest wlan subnet.</p>
<pre>
# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.1.3
</pre>
<p>This can be put into <tt>/etc/network/interfaces</tt> as a post-up line. It tells the Debian router that whenever it needs to forward traffic from the internet back to the guest wlan it should do so through 192.168.1.3. This is the address of my WNDR3700.</p>
<h4>Cron and Button events</h4>
<p>I wanted to be able to turn the guest network on and off with the push of a button. I also wanted it to automatically disable itself each night at 3am if I forgot to turn it off.</p>
<p>First thing was to write a simple <a href="/blog/wp-content/uploads/2011/06/root_guest-wifi.txt">/root/guest-wifi</a> script to enable/disable the guest wifi network from the command line. Then I&#8217;d hook this up to the button hotplug system and cron.</p>
<p>Cron is installed but not enabled by default:</p>
<pre>
cat &gt; /etc/crontabs/root &lt;&lt;EOT
# m h  dom mon dow   command
  0 3   *   *   *     /root/guest-wifi disable
EOT
ln -s /etc/crontabs/root /etc/crontab
/etc/init.d/cron enable
/etc/init.d/cron start
</pre>
<p>Finally, set up the push button:</p>
<pre>
mkdir /etc/hotplug.d/button
cat &gt; /etc/hotplug.d/button/guest-wifi-toggle &lt;&lt;EOT
#!/bin/sh
if [ "$BUTTON" = "BTN_2" -a "$ACTION" = "pressed" ]; then
  /root/guest-wifi toggle
fi
EOT
chmod +x /etc/hotplug.d/button/guest-wifi-toggle
</pre>
<h4>System upgrades</h4>
<p>You can update and install new packages with opkg, however at some point you may want to upgrade the kernel. Also if you&#8217;re using the squashfs images, anything you upgrade is taking up valuable space on the squashfs and the jffs2 overlay.</p>
<p>OpenWRT has a neat solution: <a href="http://wiki.openwrt.org/doc/howto/generic.sysupgrade">sysupgrade</a>. Always make sure to add any files that you want to keep across upgrades to the <tt>/etc/sysupgrade.conf</tt> file. Any files or directories listed here will be preserved by sysupgrade.</p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/06/openwrt-and-guest-networks-on-the-netgear-wndr3700/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Challenge: Fastest &#8216;atoi&#8217; Implementation</title>
		<link>http://delx.net.au/blog/2011/06/challenge-fastest-atoi-implementation/</link>
		<comments>http://delx.net.au/blog/2011/06/challenge-fastest-atoi-implementation/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 08:22:20 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[challenge]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=267</guid>
		<description><![CDATA[At work recently I was writing some code that needs to parse very large input files consisting of decimal numbers. These need to be converted to binary. My first attempt at doing this with boost::lexical_cast() was laughably slow, so I did some experiments to see how fast I could get it. Update 2011/06/14 &#8211; Add [...]]]></description>
			<content:encoded><![CDATA[<p>At work recently I was writing some code that needs to parse very large input files consisting of decimal numbers. These need to be converted to binary. My first attempt at doing this with boost::lexical_cast() was laughably slow, so I did some experiments to see how fast I could get it.</p>
<p><span id="more-267"></span></p>
<p><em>Update 2011/06/14 &#8211; Add C++ and Java solutions and added new numbers for J2 after improvements</em></p>
<h4>The problem</h4>
<p>Read decimal digits from a file, separated by newline chars, into a 64bit long.<br />
Generate a sample file like this:</p>
<pre>
#!/usr/bin/env python
SIZE=200 * 1024 * 1024
DIGITS=1

MIN=10**(DIGITS-1)
MAX=(10**DIGITS)-1
import random
random.seed(0)
f = open("sample%d" % DIGITS, "w")
for x in xrange(SIZE / (DIGITS+1)):
    f.write("%d\n" % random.randint(MIN, MAX))
f.close()
</pre>
<h4>Results:</h4>
<p>Run your program against the input more than once and ignore the first results until you get the whole input file in the disk cache. Here are the results of running a few tests piped to <tt>/dev/null</tt> on my Intel Core 2 Quad Q8400. The sample code was compiled with gcc 4.4.3 from Ubuntu 10.04 using -O3. Times are measured in seconds and are the result of averaging three runs.</p>
<table>
<thead>
<tr>
<td>Digits</td>
<td>md5</td>
<td>X1</td>
<td>X2</td>
<td>X3</td>
<td>J1</td>
<td>J2</td>
</tr>
</thead>
<tr>
<td>1</td>
<td>9edeadf12e178c93358ee3341048b7d8</td>
<td>8.7</td>
<td>17.7</td>
<td>42</td>
<td>1.1</td>
<td>0.5</td>
</tr>
<tr>
<td>5</td>
<td>a1d9cd533b121427fcb84acd9f54ded8</td>
<td>3.4</td>
<td>8.2</td>
<td>20</td>
<td>1.0</td>
<td>0.4</td>
</tr>
<tr>
<td>10</td>
<td>03d1cf4751f7f3b4526265913d13a028</td>
<td>2.2</td>
<td>5</td>
<td>15</td>
<td>1.0</td>
<td>0.4</td>
</tr>
<tr>
<td>15</td>
<td>cb9acdd57e77f98605815cbc80cf9927</td>
<td>1.8</td>
<td>3.9</td>
<td>13</td>
<td>1.0</td>
<td>0.4</td>
</tr>
</table>
<h4>Discussion</h4>
<p>The goal is to run in less than 2sec, which means we&#8217;re processing ~100MB/sec, which is about how fast a hard disk can feed data to the CPU.</p>
<p>X1, X2 and X3 are what I considered to be obvious and reasonably optimised solutions in C, Java and C++. It was surprising to me that none of these were able to keep up with the disk IO.</p>
<p>J1 and J2 are two more optimised solutions I&#8217;ve written that I&#8217;ll post about later with more discussion. Good luck!</p>
<h4>Sample solutions</h4>
<h5>X1 &#8211; stdcatoi.c</h5>
<pre>
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int main() {
  char line[32]; // 64bit integers have &lt; 20 digits
  long value;
  while(fgets(line, sizeof(line), stdin)) {
    value = atoll(line);
    fwrite(&amp;value, sizeof(value), 1, stdout);
  }
  return 0;
}
</pre>
<h5>X2 &#8211; jatoi.java</h5>
<pre>
import java.io.BufferedReader;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;

public class jatoi {
  public static void main(String[] args) throws Exception {
    DataOutputStream out = new DataOutputStream(new BufferedOutputStream(System.out));
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    String line;
    while((line = in.readLine()) != null) {
      out.writeLong(Long.parseLong(line));
    }
  }
}
</pre>
<h5>X3 &#8211; cppatoi.cpp</h5>
<pre>
#include &lt;iostream&gt;
using namespace std;

int main() {
  long x;
  while(cin &gt;&gt; x) {
    cout.write((char*)&amp;x, 8);
  }
  return 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/06/challenge-fastest-atoi-implementation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SBS Downloader in Python</title>
		<link>http://delx.net.au/blog/2011/05/sbs-downloader-in-python/</link>
		<comments>http://delx.net.au/blog/2011/05/sbs-downloader-in-python/#comments</comments>
		<pubDate>Tue, 10 May 2011 13:33:35 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tv]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=260</guid>
		<description><![CDATA[Just wrote a simple downloader script for SBS&#8217;s website. The SBS Player interface is all in flash and is very hard to use on my TV, so this script lets me download the stuff I&#8217;m interested in and play it however/whenever I want. It has a simple command line interface and requires that you already [...]]]></description>
			<content:encoded><![CDATA[<p>Just wrote a simple downloader script for SBS&#8217;s website. The <a href="http://player.sbs.com.au/programs">SBS Player</a> interface is all in flash and is very hard to use on my TV, so this script lets me download the stuff I&#8217;m interested in and play it however/whenever I want.</p>
<p>It has a simple command line interface and requires that you already have rtmpdump on your path. Get the <a href="http://delx.net.au/hg/jamesstuff/raw-file/tip/ripping/sbs-downloader">sbs-downloader</a> script here.</p>
<p><span id="more-260"></span></p>
<p>Usage example:<br />
<code><br />
$ sbs-downloader<br />
...<br />
 10) Documentary<br />
...<br />
 41) mY generation<br />
 0) Back<br />
Choose> <strong>10</strong><br />
 1) Designer People Ep 11 - Young Baek Min<br />
 2) Designer People Ep 12<br />
 3) Destination Australia - A Family Divided Full Ep<br />
 4) Empire of the Seas Ep 4<br />
 5) Gaddafi - Our Best Enemy Full Ep<br />
....<br />
 0) Back<br />
Choose> <strong>3 5</strong><br />
RTMPDump v2.3<br />
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL<br />
Connecting ...<br />
INFO: Connected...<br />
Starting download at: 0.000 kB<br />
....<br />
</code></p>
<p>The bolded parts are what you type. Note that you can go back on any screen by typing &#8220;0&#8243;. Also at the list of episodes you can download a single episode by typing one number, or multiple episodes by typing several numbers separated by spaces.</p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/05/sbs-downloader-in-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>YouTube Downloader</title>
		<link>http://delx.net.au/blog/2011/05/youtube-downloader/</link>
		<comments>http://delx.net.au/blog/2011/05/youtube-downloader/#comments</comments>
		<pubDate>Sat, 07 May 2011 14:46:31 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=255</guid>
		<description><![CDATA[Just wrote a simple YouTube downloader. You can grab the code for it from here: youtube.cgi It&#8217;s a simple CGI script with a form to submit a YouTube URL. It then streams the video download to the user. If you run this on a machine in the USA then it provides an easy way to [...]]]></description>
			<content:encoded><![CDATA[<p>Just wrote a simple YouTube downloader. You can grab the code for it from here:<br />
<a href="http://delx.net.au/hg/jamesstuff/raw-file/tip/ripping/youtube.cgi">youtube.cgi</a></p>
<p>It&#8217;s a simple CGI script with a form to submit a YouTube URL. It then streams the video download to the user. If you run this on a machine in the USA then it provides an easy way to bypass YouTube&#8217;s region checking.</p>
<p>Ask me if you want the URL for an installed copy.</p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/05/youtube-downloader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TV, Audio, Video &amp; Computer Cable Pictures</title>
		<link>http://delx.net.au/blog/2011/02/tv-audio-video-computer-cable-pictures/</link>
		<comments>http://delx.net.au/blog/2011/02/tv-audio-video-computer-cable-pictures/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 08:44:23 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[cables]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=215</guid>
		<description><![CDATA[I often find that many people have trouble distinguishing the many different kinds of cables that are commonly used in TVs and computers today. There are so many types, some of which do the same or similar tasks and have adaptors to go to and from each other. So, read on for a bunch of [...]]]></description>
			<content:encoded><![CDATA[<p>I often find that many people have trouble distinguishing the many different kinds of cables that are commonly used in TVs and computers today. There are so many types, some of which do the same or similar tasks and have adaptors to go to and from each other. So, read on for a bunch of pictures and descriptions.</p>
<p><span id="more-215"></span></p>
<h4>USB</h4>
<p><div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/USB-300x220.gif" alt="USB" /><p class="wp-caption-text">USB</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/USB-micro-300x225.jpg" alt="MicroUSB" /><p class="wp-caption-text">MicroUSB</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/USB-mini-300x196.jpg" alt="MiniUSB" /><p class="wp-caption-text">MiniUSB</p></div></p>
<p>Everybody will have seen used a <a href="http://en.wikipedia.org/wiki/Usb">USB</a> cable. These cables are very multi-purpose:</p>
<ul>
<li>Simple charging; many new phones now charge over MicroUSB or MiniUSB. They are also often used as chargers for many other gadgets like cheap remote control helicopters. Note that due to protocol issues not all chargers will work with all devices.</li>
<li>File storage; mobile phones, cameras, memory card readers, thumbdrives, external hard drives all usually make their contents accessible using the standard USB mass-storage protocol.</li>
<li>Input devices; all modern keyboards, mice, gamepads, etc work over standard USB protocols so they should work on any computer.</li>
<li>Many other things, such as 3g modems, mobile phone synchronisation, etc</li>
</ul>
<h4>Audio &#038; Video Cables</h4>
<p><div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/35mm-Audio-300x300.jpg" alt="3.5mm Audio" /><p class="wp-caption-text">3.5mm Audio</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RCA-Audio.jpg" alt="RCA-Audio" /><p class="wp-caption-text">RCA-Audio</p></div></p>
<p>A <a href="http://en.wikipedia.org/wiki/TRS_connector">3.5mm audio cable</a> is the standard audio jack that you use for earphones and many analogue audio signals. Most mp3 players, stereo systems and even many cars have a 3.5mm audio socket which you can connect to headphones or speakers.</p>
<p><a href="http://en.wikipedia.org/wiki/Rca_cable">RCA cables</a> are fairly multi-purpose, in the picture it is a 3.5mm audio cable on one end and two RCA cables on the other. Many TVs and some speakers take two RCA cables for a stereo audio signal so this adaptor is useful.</p>
<h4>RCA Video/Audio</h4>
<p><div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RCA-Composite-300x273.jpg" alt="Composite Video/Audio (RCA)" /><p class="wp-caption-text">Composite Video/Audio (RCA)</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RCA-Component-300x300.jpg" alt="Component Video/Audio (RCA)" /><p class="wp-caption-text">Component Video/Audio (RCA)</p></div></p>
<p>You&#8217;ll notice that these are the some plugs as the RCA cables pictured for audio above. That&#8217;s because they&#8217;re exactly the same. A <a href="http://en.wikipedia.org/wiki/Composite_video">composite RCA cable</a> has two audio cables, for left &#038; right stereo, and one for the entire video signal. This is a fairly low quality, but very ubiquitous analogue video cable.</p>
<p>A <a href="http://en.wikipedia.org/wiki/Component_video">component RCA cable</a> is a much higher quality analogue cable. Once again it has two audio cables, but it has three video cables, one for the red, green and blue signals respectively. Note that the colours here are only a guide, each plug is exactly the same as the other, so if you swap the red with blue on both the source and destination everything will be fine.</p>
<h4>TV Aerial, Radio Frequency (RF)</h4>
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RF.jpg" alt="RF" /><p class="wp-caption-text">RF</p></div>
<p>These used to be the only cable plugged into the back of a TV (besides power). It&#8217;s most commonly used to connect a TV receiver or tuner of some kind to an aerial that picks up a TV signal. This can be a digital or analogue TV signal and carries more than one channel of audio &#038; video all mixed together on different frequencies so you need a tuner to process it. Most TVs have a tuner built in.</p>
<h4>Digital Video/Audio</h4>
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/HDMI.jpg" alt="HDMI" /><p class="wp-caption-text">HDMI</p></div>
<p><a href="http://en.wikipedia.org/wiki/Hdmi">HDMI</a> is fast becoming the new standard for digital video &#038; audio to connect TVs to DVD players, game consoles, etc. It carries a very high quality signal.</p>
<h4>Computer Video</h4>
<p><div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/HDMI-DVI-300x200.jpg" alt="HDMI-DVI" /><p class="wp-caption-text">HDMI-DVI</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/VGA-300x225.jpg" alt="VGA" /><p class="wp-caption-text">VGA</p></div></p>
<p>These are used to connect computers to a monitor. <a href="http://en.wikipedia.org/wiki/VGA_connector">VGA</a> is an analogue signal, but still usually decent quality. <a href="http://en.wikipedia.org/wiki/DVI_connector">DVI</a> has two forms, DVI-A (analogue) and DVI-D (digital). DVI-A is the same signal as VGA, so you can get a simple cheap adaptor between the two. DVI-D is the same signal as HDMI, so the same thing applies. A DVI-HDMI cable is pictured above. There&#8217;s also DVI-I that carries both signals at once.</p>
<h4>Networking</h4>
<p><div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RJ12.jpg" alt="RJ12" /><p class="wp-caption-text">RJ12</p></div><br />
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/RJ45.jpg" alt="RJ45" /><p class="wp-caption-text">RJ45</p></div></p>
<p>RJ12 cables are usually phone cables. They&#8217;re used to connect a plain old analogue telephone to the wall, or an ADSL modem to the wall. RJ45 connectors usually appear on <a href="http://en.wikipedia.org/wiki/Ethernet">ethernet</a> cables, which are used for computer networking.</p>
<h4>eSATA</h4>
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/eSATA-300x244.jpg" alt="eSATA" /><p class="wp-caption-text">eSATA</p></div>
<p><a href="http://en.wikipedia.org/wiki/Serial_ATA#eSATA">eSATA</a> is a neat way to connect hard drives to your computer. It makes an external hard drive just as fast as an internal one, unlike USB hard drives which are much slower.</p>
<h4>Firewire</h4>
<div class="wp-caption alignnone" style="width: 310px"><img src="/blog/wp-content/uploads/2011/02/Firewire-300x225.jpg" alt="Firewire" /><p class="wp-caption-text">Firewire</p></div>
<p><a href="http://en.wikipedia.org/wiki/Firewire">Firewire</a>, more formally known as &#8216;IEEE 1394&#8242; is less common than USB, but serves many of the same purposes. File storage, video cameras, audio devices. It has higher data capacity, but is less common and so usually more expensive.</p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/02/tv-audio-video-computer-cable-pictures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing NotiPod</title>
		<link>http://delx.net.au/blog/2011/01/announcing-notipod/</link>
		<comments>http://delx.net.au/blog/2011/01/announcing-notipod/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 13:53:58 +0000</pubDate>
		<dc:creator>delx</dc:creator>
				<category><![CDATA[Technical]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[sync]]></category>

		<guid isPermaLink="false">http://delx.net.au/blog/?p=209</guid>
		<description><![CDATA[A very small (~25KiB compressed) Python Cocoa GUI app for synchronising iTunes playlists to any folder mounted on your Mac. I use this to sync my music and playlists from iTunes on my laptop to XBMC on my lounge media pc. See the NotiPod project page]]></description>
			<content:encoded><![CDATA[<p>A very small (~25KiB compressed) Python Cocoa GUI app for synchronising iTunes playlists to any folder mounted on your Mac. I use this to sync my music and playlists from iTunes on my laptop to XBMC on my lounge media pc.</p>
<p>See the <a href="/projects/notipod">NotiPod project page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://delx.net.au/blog/2011/01/announcing-notipod/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

