<?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>Ryan Finnie</title>
	<atom:link href="http://www.finnie.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.finnie.org</link>
	<description></description>
	<lastBuildDate>Sun, 07 Mar 2010 23:37:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>External temperature monitoring with Linux</title>
		<link>http://www.finnie.org/2010/03/07/external-temperature-monitoring-with-linux/</link>
		<comments>http://www.finnie.org/2010/03/07/external-temperature-monitoring-with-linux/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 23:36:23 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1264</guid>
		<description><![CDATA[
At work, we moved into a new office last week.  Part of that move involved moving the office network infrastructure from a massive server and work room into a small server closet.  We're having some issues with cooling, so I decided to get some sort of ambient temperature monitoring going while we work [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.finnie.org/wp-content/uploads/2010/03/renooffice_servercloset_temp0-day3.png"><img src="http://www.finnie.org/wp-content/uploads/2010/03/renooffice_servercloset_temp0-day3.png" alt="MRTG Temperature" title="MRTG Temperature" width="500" height="135" style="border-style: none;" /></a></p>
<p><a href="http://www.finnie.org/wp-content/uploads/2010/03/t-sense_probe.jpg"><img src="http://www.finnie.org/wp-content/uploads/2010/03/t-sense_probe-225x300.jpg" alt="T-Sense Probe" title="T-Sense Probe" width="225" height="300" style="border-style: none; float: right;" /></a>At work, we moved into a new office last week.  Part of that move involved moving the office network infrastructure from a massive server and work room into a small server closet.  We're having some issues with cooling, so I decided to get some sort of ambient temperature monitoring going while we work on fixing the issue.</p>
<p>I found a few DIY articles (such as <a href="http://ssli.ee.washington.edu/people/nomad/thermalcube/">here</a> and <a href="http://www.hoppie.nl/tempsens/">here</a>) that use the Dallas Semiconductor 1-Wire bus.  <a href="http://en.wikipedia.org/wiki/1-Wire">1-Wire</a> is a low-speed parallel communications bus where the entire bus is powered and controlled by a single master interface.  The master is usually a serial device connected to a computer.  The rest of the devices can either be daisy-chained, or wired in a star topology, much the same as home phone wiring can be split from the telco demarc to multiple phones.  (Despite the name, two wires are needed for a 1-Wire bus, one carries data and power, the other is ground.)</p>
<p>They looked nice, but I didn't want to go the DIY route.  Eventually I found <a href="http://www.ibuttonlink.com/">iButtonLink</a>, who makes and sells 1-Wire products.  I bought the <a href="http://www.ibuttonlink.com/linkusbi.aspx">LinkUSBi</a> master and a few <a href="http://www.ibuttonlink.com/t-sense.aspx">T-Sense</a> temperature probes.  (The <a href="http://www.ibuttonlink.com/linkusb.aspx">LinkUSB</a> is a few dollars cheaper than the LinkUSBi, but the LinkUSBi also contains an ID chip, so you can verify operation of the bus even if no other devices are connected.)  The iButtonLink products use RJ45 ports, so you can use Cat5 network cable to connect them together.  The T-Sense probe has RJ45 ports on both ends, so you can daisy chain them if you like.  I haven't done so, but if you wanted to do star topology instead, you could buy a 4-port biscuit block with 4 RJ45 ports, and then wire all of their pin 4s together and all of their pin 5s together.  Then simply plug the master into one port (doesn't matter which, remember this is a parallel bus), and the sensors into the rest.</p>
<p>The products arrived Thursday, and I plugged the master into a server running Debian 5.0 Lenny.  The LinkUSBi is a serial device with an internal FTDI FT232R USB UART, which was recognized by the ftdi_sio usb-serial module and set up as <tt>/dev/ttyUSB0</tt>.  In case you have other ttyUSB devices on your machine, I devised this udev rule for more permanent device naming:</p>
<blockquote><pre>SUBSYSTEM=="tty", ATTRS{serial}=="?*", SYMLINK+="char/by-id/tty-$attr{serial}"</pre>
</blockquote>
<p>In this case it gives me <tt>/dev/char/by-id/tty-A800bZvc</tt>, but for the sake of simplicity I will continue to refer to the device as <tt>/dev/ttyUSB0</tt> for the rest of this guide.</p>
<h1>digitemp</h1>
<p>Now, to read the temperatures.  You'll want the <a href="http://www.digitemp.com/"><tt>digitemp</tt></a> package, which is pre-packaged in Debian and probably most other Linux distributions.  Once it's installed, you'll need to know what program to use.  Several are available for different DS masters, but in the LinkUSBi's case, you'll want <tt>digitemp_DS9097U</tt>.  To begin, verify the bus is working correctly by walking it:</p>
<pre># digitemp_DS9097U -w -s /dev/ttyUSB0
DigiTemp v3.5.0 Copyright 1996-2007 by Brian C. Lane
GNU Public License v2.0 - http://www.digitemp.com
Turning off all DS2409 Couplers
...
Devices on the Main LAN
28D1483C0200002F : DS18B20 Temperature Sensor
28E9393C020000C3 : DS18B20 Temperature Sensor
010EBED512000046 : DS2401/DS1990A Serial Number iButton</pre>
<p>This shows the two DS18B20 temperature sensors (T-Sense probes), as well as the DS2401 embedded in my LinkUSBi.  (The DS2401 literally does nothing but return a serial number.  Still, as mentioned before it's useful to have to verify the bus is working correctly even if no other devices are plugged into it.)</p>
<p>Next you'll want to create a config file.  I chose to store it in <tt>/etc/digitemp.conf</tt>.</p>
<blockquote><pre># digitemp_DS9097U -i -c /etc/digitemp.conf -s /dev/ttyUSB0
DigiTemp v3.5.0 Copyright 1996-2007 by Brian C. Lane
GNU Public License v2.0 - http://www.digitemp.com
Turning off all DS2409 Couplers
...
Searching the 1-Wire LAN
28D1483C0200002F : DS18B20 Temperature Sensor
28E9393C020000C3 : DS18B20 Temperature Sensor
ROM #0 : 28D1483C0200002F
ROM #1 : 28E9393C020000C3
Wrote /etc/digitemp.conf</pre>
</blockquote>
<p>You will be left with a file called <tt>/etc/digitemp.conf</tt> that looks something like this:</p>
<blockquote><pre>TTY /dev/ttyUSB0
READ_TIME 1000
LOG_TYPE 1
LOG_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F"
CNT_FORMAT "%b %d %H:%M:%S Sensor %s #%n %C"
HUM_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F H: %h%%"
SENSORS 2
ROM 0 0x28 0xD1 0x48 0x3C 0x02 0x00 0x00 0x2F
ROM 1 0x28 0xE9 0x39 0x3C 0x02 0x00 0x00 0xC3 </pre>
</blockquote>
<p>You can rearrange the ROM mappings as you'd like.  1-Wire refers to devices by their 64-bit IDs; the numeric mappings are for digitemp's benefit.  In my case, 28D1483C0200002F is the probe I'd like to use, so #0 is fine.</p>
<p>Now, let's see what's being returned:</p>
<blockquote><pre># digitemp_DS9097U -q -c /etc/digitemp.conf -a
Mar 04 22:22:43 Sensor 0 C: 25.38 F: 77.67
Mar 04 22:22:44 Sensor 1 C: 27.56 F: 81.61</pre>
</blockquote>
<p>Great, works fine.  We'll soon need the data in a machine-readable format, so here's how to do that:</p>
<blockquote><pre># digitemp_DS9097U -q -c /etc/digitemp.conf -o 3 -a
0	77.79	81.50</pre>
</blockquote>
<p>That output is tab-delimited, the first column being elapsed time (digitemp can pull data multiple times, but we won't be going into that so it will always be 0 here), and the rest of the columns are the probe values in order.  "-o 3" is Fahrenheit; use "-o 2" for Celsius.  In this case I only want the result of the first probe, so I can save some time by specifying a specific probe with "-t 0":</p>
<blockquote><pre># digitemp_DS9097U -q -c /etc/digitemp.conf -o 3 -t 0
0	77.90</pre>
</blockquote>
<p><span id="more-1264"></span></p>
<h1>SNMP</h1>
<p>I want to monitor temperature using Nagios and MRTG, but in my case the 1-Wire bus is attached to a different server than the Nagios/MRTG server, so we'll have to deal with cross-server probing. (My Nagios/MRTG server is a virtualized guest, so I placed the 1-Wire bus on the virtualization host server.)  SNMP should work well for this.</p>
<p>First, ensure your groups are correct.  The snmpd process (usually user "snmp") will have to access <tt>/dev/ttyUSB0</tt> (usually group "dialout").  Edit <tt>/etc/group</tt>, and add "snmp" to the "dialout" group.  Also, make sure snmpd is being called with both the user AND group.  In Debian, it just specifies the user and snmpd retains the effective group "root", which doesn't let you get at devices with group "dialout".  To fix this, edit <tt>/etc/default/snmpd</tt> and change "-u snmp" to "-u snmp -g nogroup").</p>
<p>Now, create a script.  I chose to create a Nagios-compatible Perl script that will also work as an snmpd "exec" process:</p>
<blockquote><pre>#!/usr/bin/perl

$warn = 82.0;
$crit = 87.0;

$output = `/usr/bin/digitemp_DS9097U -q -c /etc/digitemp.conf -t 0 -o 3`;
if($output =~ /^\d+\t([\d\.]+)/) {
  $temp0 = $1 + 0;
  if($temp0 &gt;= $crit) {
    print "CRIT Room temperature is ${temp0}F (&gt;= ${crit}F)\n";
    exit 1;
  } elsif($temp0 &gt;= $warn) {
    print "WARN Room temperature is ${temp0}F (&gt;= ${warn}F)\n";
    exit 2;
  } else {
    print "OK Room temperature is ${temp0}F|temp0=${temp0}\n";
    exit 0;
  }
} else {
  print "Cannot find probe!\n";
  exit 1;
}</pre>
</blockquote>
<p>And when run:</p>
<blockquote><pre># check_roomtemp; echo $?
OK Room temperature is 78.24F|temp0=78.24
0</pre>
</blockquote>
<p>Now add this to your working snmpd.conf and restart snmpd:</p>
<blockquote><pre>exec roomtemp /usr/local/bin/check_roomtemp</pre>
</blockquote>
<p>Now switch to another host and verify it is working:</p>
<blockquote><pre># snmpwalk -v 1 1wirehost.example.com -c community extTable
UCD-SNMP-MIB::extIndex.1 = INTEGER:
UCD-SNMP-MIB::extNames.1 = STRING: roomtemp
UCD-SNMP-MIB::extCommand.1 = STRING: /usr/local/bin/check_roomtemp
UCD-SNMP-MIB::extResult.1 = INTEGER: 0
UCD-SNMP-MIB::extOutput.1 = STRING: OK Room temperature is 78.35F|temp0=78.35
UCD-SNMP-MIB::extErrFix.1 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFixCmd.1 = STRING: </pre>
</blockquote>
<h1>Nagios</h1>
<p><a href="http://www.finnie.org/wp-content/uploads/2010/03/nagios-temp.png"><img src="http://www.finnie.org/wp-content/uploads/2010/03/nagios-temp.png" alt="Nagios Temperature" title="Nagios Temperature" width="451" height="305" style="border-style: none;" /></a></p>
<p>Now, on the Nagios host, we'll need to turn that into data Nagios can actually use.  I've got a little script called <tt>check_snmp_exec</tt>; feed it a named "exec" entry and it will return the result and text to Nagios:</p>
<blockquote><pre>#!/bin/sh

PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
USAGE="Usage: $0 [-h] -i host [-n community_string] (-x index | -e execname)"

# defaults
COMMUNITY=community

while getopts hn:i:x:e: option
        do
        case $option in
                n) COMMUNITY=$OPTARG;;
                i) HOST=$OPTARG;;
                x) INDEX=$OPTARG;;
                e) EXECNAME=$OPTARG;;
                \?|h)
                echo $USAGE
                exit 2;;
        esac
done

if [ -z "$HOST" ]; then
  echo $USAGE
  exit 2
fi

if [ -z "$INDEX" -a -z "$EXECNAME" ]; then
  echo $USAGE
  exit 2
fi
if [ -z "$INDEX" ]; then
  INDEX=$(snmpwalk -v 1 -t 5 -r 2 -Os -Oq ${HOST:?} -c ${COMMUNITY} extNames 2&gt;&amp;1 | while read FPART FNAME; do
    if [ "$FNAME" = "$EXECNAME" ]; then
      echo "$(echo $FPART | awk -F. '{print $2}')"
    fi
  done )
  if [ -z "$INDEX" ]; then
    echo "ERROR: Cannot find $EXECNAME on $HOST"
    exit 2
  fi
fi

snmpget -v 1 -t 5 -r 2 -Ov -Oq ${HOST:?} -c ${COMMUNITY} extOutput.${INDEX} extResult.${INDEX} 2&gt;&amp;1 | (read STATUSTEXT; read STATUSVAL; echo $STATUSTEXT; exit $STATUSVAL)
if [ $? -eq 0 ]; then
        exit 0
else
        exit 2
fi</pre>
</blockquote>
<p>Set up the check command in Nagios:</p>
<blockquote><pre>define command{
        command_name    check_snmp_exec
        command_line    /usr/lib/nagios/plugins/custom/check_snmp_exec -i $HOSTADDRESS$ -e $ARG1$ -n $ARG2$
        }</pre>
</blockquote>
<p>And a service check:</p>
<blockquote><pre>define service{
        use                             generic-service
        host_name                       1wirehost.example.com
        service_description             ROOMTEMP
        check_command                   check_snmp_exec!roomtemp!community
        }</pre>
</blockquote>
<p>Now you're ready to monitor!  Of course, if the 1-Wire master is on the Nagios host directly, you can completely skip all the previous SNMP/<tt>check_snmp_exec</tt> steps and just point your service check directly at <tt>check_roomtemp</tt> (though you would then need to make sure "nagios" was in the "dialout" group).</p>
<h1>MRTG</h1>
<p><a href="http://www.finnie.org/wp-content/uploads/2010/03/renooffice_servercloset_temp0-day3.png"><img src="http://www.finnie.org/wp-content/uploads/2010/03/renooffice_servercloset_temp0-day3.png" alt="MRTG Temperature" title="MRTG Temperature" width="500" height="135" style="border-style: none;" /></a></p>
<p>I also wanted to graph the temperature, and MRTG can work for that purpose.  We can use the same "roomtemp" snmp exec on the backend, but we'll need a frontend script to extract the perfmon data to feed to MRTG.  Here's <tt>mrtg_roomtemp</tt>; it's similar to <tt>check_snmp_exec</tt> but rewritten in Perl for its splitting capability (yes, you could do it in bash, but I'm lazy and I'm decent with Perl), and is hardcoded to this purpose:</p>
<blockquote><pre>#!/usr/bin/perl

host = "1wirehost.example.com";
$community = "community";
$execname = "roomtemp";

$result = `snmpwalk -v 1 -t 5 -r 2 -Os -Oq $host -c $community extNames`;
while($result =~ /^extNames.(\d+)\s+(.*?)$/mg) {
  $testindex = $1;
  $testname = $2;
  if($testname eq $execname) {
    $index = $testindex;
    last;
  }
}

if(!$index) {
  exit 1;
}

@result = split(/\n/, `snmpget -v 1 -t 5 -r 2 -Ov -Oq $host -c $community extOutput.$index extResult.$index`);
if($result[1] =~ /^\d+$/) {
  @result2 = split(/|/, $result[0], 2);
  if($result2[1] =~ /temp0=([\d\.]+)/) {
    print int($1 * 100) . "\n";
    print int($1 * 100) . "\n";
    print `uptime | awk '{ gsub(/,/, ""); print \$3, \$4, \$5; }'`;
    print `hostname`;
  } else {
    exit 1;
  }
} else {
  exit 1;
}</pre>
</blockquote>
<p>Which will return:</p>
<blockquote><pre># mrtg_roomtemp
7845
7845
6 days 12:08
mrtghost.example.com</pre>
</blockquote>
<p>The temperature is multiplied by 100 because MRTG cannot handle decimal input (it was originally designed for handling SNMP interface integer counters), but we do want the extra precision so it will be converted back in the MRTG config.</p>
<p>Here's the <tt>mrtg.cfg</tt> entry to handle this data:</p>
<blockquote><pre>Target[roomtemp]: `/usr/local/bin/mrtg_roomtemp`
Options[roomtemp]: growright, gauge, noo, nopercent, noinfo, expscale
Factor[roomtemp]: 0.01
YTics[roomtemp]: 7
YTicsFactor[roomtemp]: 0.01
MaxBytes[roomtemp]: 20000
Title[roomtemp]: Server Closet Ambient Temperature
PageTop[roomtemp]: &lt;h1&gt;Server Closet Ambient Temperature&lt;/h1&gt;
YLegend[roomtemp]: Degrees F
ShortLegend[roomtemp]: &amp;deg;F
Legend1[roomtemp]: Ambient Fahrenheit Temperature
LegendI[roomtemp]: &amp;nbsp;Ambient</pre>
</blockquote>
<p>This will produce a graph that converts the temperature back into decimal, and makes an exponentially-scaled graph (easier to see minor changes as in our case).  Note that MRTG cannot handle values below zero, so if you'll be monitoring an area that will get below 0&deg;F (or 0&deg;C if you decided on Celsius earlier), you'll have to do something like convert to Kelvin:</p>
<ul>
<li>Change "-o 3" to "-o 2" in <tt>check_roomtemp</tt> on the 1-Wire host to change it to Celsius</li>
<li>Change "int($1 * 100)" to "int($1 * 100 + 27315)" in <tt>mrtg_roomtemp</tt> on the MRTG host to convert from Celsius to Kelvin</li>
<li>Change "MaxBytes[roomtemp]: 20000" to "MaxBytes[roomtemp]: 400000" in the MRTG config to account for the raised scale. (That's from "twenty thousand" to "four hundred thousand", there's an extra 0 in there.)</li>
<li>Change any labels in the MRTG config to reflect Kelvin.</li>
</ul>
<p>If you need to monitor temperatures below 0K, you've got some rather large thermodynamic problems on your hands, though you're probably saving a lot in cooling costs during the summer.</p>
<p>But seriously, here's what the documentation says about its temperature range:</p>
<blockquote><p><em>[The DS18B20] has an operating temperature range of -55&deg;C to +125&deg;C and is accurate to &plusmn;0.5&deg;C over the range of -10&deg;C to +85&deg;C</em></p>
<p><em>The temperature range of the T-Sense is equal to the range of the DS18B20. The temperature range of the connecting cables will likely be far less. Standard cat5 cable sheathing will begin to melt at temperatures &gt;60&deg;C (140&deg;F). High temp cables are available by special order if needed.</em></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/03/07/external-temperature-monitoring-with-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cisco PIX DNS fixup in Linux?</title>
		<link>http://www.finnie.org/2010/02/18/cisco-pix-dns-fixup-in-linux/</link>
		<comments>http://www.finnie.org/2010/02/18/cisco-pix-dns-fixup-in-linux/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 03:12:42 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1259</guid>
		<description><![CDATA[At work we have a Cisco PIX firewall for the office.  It's decent (if a bit eccentric; that is, hard to configure), but occasionally I go through a thought exercise to see how this firewall could be replaced with a Linux firewall.  Most of the functionality is easy in Linux (NAT, ACLs, VPNs, [...]]]></description>
			<content:encoded><![CDATA[<p>At work we have a Cisco PIX firewall for the office.  It's decent (if a bit eccentric; that is, hard to configure), but occasionally I go through a thought exercise to see how this firewall could be replaced with a Linux firewall.  Most of the functionality is easy in Linux (NAT, ACLs, VPNs, etc), but one thing I get hung up on is DNS fixup.  Fixup is a monitoring service much like nf_conntrack/nf_nat in Linux, and in DNS fixup's case can rewrite responses depending on the context.  Here's an explanation:</p>
<p>The players:<br />
- Mallory is the PIX firewall, with the 10.0.0.0 network inside and the 9.9.9.0 network outside. (Despite conventional naming examples, Mallory is not malicious here, but otherwise has the same attributes.)<br />
- Alice is the DNS server, 10.0.0.2 inside, 9.9.9.2 outside.  Alice knows only about internal IPs in her DNS database.<br />
- Bob is some server, 10.0.0.3 inside, 9.9.9.3 outside.  Bob is listed with Alice as bob.corp.example.com, 10.0.0.3.<br />
- Charlie is a client on the outside network.<br />
- Dave is a client on the inside network.</p>
<p>Now, say Charlie (outside) queries bob.corp.example.com via Alice's external IP.  Alice will respond with 10.0.0.3.  Mallory intercepts the response, knows that Bob is 10.0.0.3 on the inside and 9.9.9.3 on the outside, so she rewrites the response as 9.9.9.3 and gives it to Charlie.</p>
<p>It also works in the opposite direction.  Say www.example.com is a web server served by Bob, and DNS is hosted by an outside DNS provider which obviously returns 9.9.9.3 for www.example.com.  Now say Dave (inside) queries www.example.com via Alice.  Alice doesn't know about www.example.com, so she goes out to the Internet (through Mallory) to find it.  The outside DNS responds with 9.9.9.3.  Again, Mallory knows about Bob's mapping and will rewrite the response to 10.0.0.3 to Alice, which then gives the final answer to Dave.</p>
<p>As far as I know, there is nothing in Linux to facilitate this.  Yes, I know about split-horizon DNS, but it's a pain to maintain multiple zone copies, and Alice's DNS service would have to be moved to Mallory directly.  The PIX does this all automatically for you (if you want; of course it can be disabled).</p>
<p>(Please, prove me wrong.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/02/18/cisco-pix-dns-fixup-in-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>in.tcpmuxd: A secure, RFC compliant TCPMUX server</title>
		<link>http://www.finnie.org/2010/02/13/in-tcpmuxd-a-secure-rfc-compliant-tcpmux-server/</link>
		<comments>http://www.finnie.org/2010/02/13/in-tcpmuxd-a-secure-rfc-compliant-tcpmux-server/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 11:41:49 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1254</guid>
		<description><![CDATA[Yesterday, on IRC, neale asked if it was wise to run a TCP service on port 1.  sneakums replied it was not, since it was a registered service, "tcpmux".  However, nobody immediately knew what "tcpmux" was; Wikipedia provided the answer.
TCPMUX is an ancient, horrible protocol.  You connect to a TCPMUX server on [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, on IRC, <a href="http://woozle.org/~neale/">neale</a> asked if it was wise to run a TCP service on port 1.  <a href="http://zork.net/~sneakums/">sneakums</a> replied it was not, since it was a registered service, "tcpmux".  However, nobody immediately knew what "tcpmux" was; <a href="http://en.wikipedia.org/wiki/TCPMUX">Wikipedia provided the answer</a>.</p>
<p>TCPMUX is an ancient, horrible protocol.  You connect to a TCPMUX server on port 1, then tell it which TCP service you actually wanted, and it forwards locally for you.  Obviously fraught with security problems on the modern Internet.  Nonetheless, I immediately wanted to write a TCPMUX server.</p>
<p>I started out by coding to the description in the Wikipedia entry, not knowing there was an RFC.  We did find it (<a href="http://www.faqs.org/rfcs/rfc1078.html">RFC 1078</a>), and Neale and I went back and forth tweaking the code.  Eventually I stopped with this:</p>
<blockquote><pre>#!/usr/bin/perl

while(<>) {
  if($_ eq "HELP\r\n") {
    print "tcpmux\r\n";
    exit 0;
  } elsif(lc($_) eq "tcpmux\r\n") {
    print "+OK FINE\r\n";
  } else {
    print "-BLOW ME\r\n";
    exit 0;
  }
}</pre>
</blockquote>
<p>My friends, that is a fully functional, RFC 1078-compliant, completely secure TCPMUX server, in 11 lines of Perl.  Neale has a bash version that he prefers, but I argue mine is better because it's strictly RFC-compliant (only accepts CRLF, etc).  To use it, add this to <tt>/etc/inetd.conf</tt>:</p>
<blockquote><pre>tcpmux stream tcp nowait nobody /path/to/in.tcpmuxd</pre>
</blockquote>
<p>To use, telnet to port 1. (You can use <tt>nc</tt>, but you will have to do something like "<tt>echo -ne 'tcpmux\r\n' | nc localhost 1</tt>" because it will only recognize CRLF-terminated lines per the RFC.)  in.tcpmuxd will accept and forward exactly one service, tcpmux.  All others will be rejected with a kind explanation.  "HELP" will also conveniently list all services it will forward.</p>
<p>You can also test this by telnetting to <tt>colobox.com</tt> port 1, which is running a fully functional TCPMUX server.</p>
<p>This service has been painstakingly checked for security flaws.  A highly skilled team has gone through the entire codebase, line by line, and has determined that there are no known implementation or security flaws in the service.  You're welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/02/13/in-tcpmuxd-a-secure-rfc-compliant-tcpmux-server/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>oui, an IEEE OUI database search utility</title>
		<link>http://www.finnie.org/2010/01/16/oui-an-ieee-oui-database-search-utility/</link>
		<comments>http://www.finnie.org/2010/01/16/oui-an-ieee-oui-database-search-utility/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 00:17:54 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1240</guid>
		<description><![CDATA[On Friday, I was grepping through DHCP logs, looking for a certain machine, and got sick of going to the IEEE web site to plug in the OUI to figure out the manufacturer of MAC addresses.  This involved manually converting a "standard" format MAC address (00:04:f2:e6:93:16, for example) into an OUI format that would [...]]]></description>
			<content:encoded><![CDATA[<p>On Friday, I was grepping through DHCP logs, looking for a certain machine, and got sick of going to the IEEE web site to plug in the OUI to figure out the manufacturer of MAC addresses.  This involved manually converting a "standard" format MAC address (00:04:f2:e6:93:16, for example) into an OUI format that would be accepted by the IEEE site (00-04-F2).</p>
<p>I found that my workstation already had several OUI databases installed locally (most notably one provided by the nmap package), and hacked together a 5 line Perl script to take a MAC address and use it to search one of the OUI databases.  I later fleshed it out into a complete, releasable product.  You can download the program from <a href="http://www.finnie.org/software/oui/">http://www.finnie.org/software/oui/</a>.</p>
<p>At its simplest, give it a MAC address, and it will return a vendor.</p>
<blockquote><pre>$ oui 00:22:19:df:a8:2b
002219 Dell</pre>
</blockquote>
<p>You can give it multiple items to look up.  These can be either a full MAC address or just an OUI, uppercase or lowercase, and can be in a variety of popular formats.</p>
<blockquote><pre>$ oui 00:30:48:88:1B:AF 0004f2e69316 000a.4137.c40a 00:26:99:8d:38:ea 00-50-8D
0004F2 Polycom
000A41 Cisco Systems
003048 Supermicro Computer
00508D Abit Computer</pre>
</blockquote>
<p>Note that oui was given 5 items, but only returned 4 results.  oui searches for several common OUI databases that may be installed locally on your system (the most common would be nmap's database), and they can be quite out of date.  Let's rectify that by downloading a current database from the IEEE.</p>
<blockquote><pre>$ oui 00:26:99:8d:38:ea
$ wget -O /tmp/oui-20100116.txt http://standards.ieee.org/regauth/oui/oui.txt
--2010-01-16 15:04:12--  http://standards.ieee.org/regauth/oui/oui.txt
Resolving standards.ieee.org... 140.98.193.16
Connecting to standards.ieee.org|140.98.193.16|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2118408 (2.0M) [text/plain]
Saving to: `/tmp/oui-20100116.txt'

100%[=====================================&gt;] 2,118,408   1019K/s   in 2.0s    

2010-01-16 15:04:17 (1019 KB/s) - `/tmp/oui-20100116.txt' saved [2118408/2118408]

$ oui -d /tmp/oui-20100116.txt 00:26:99:8d:38:ea
002699 Cisco Systems</pre>
</blockquote>
<p>Much better.  If you want to permanently store that database, put it in <code>/usr/share/oui/oui.txt</code>; oui will look there first for a database.</p>
<p>You can also use oui to search one or more organization names.</p>
<blockquote><pre>$ oui -s avaya "university of california"
00040D Avaya
00126D University of California, Berkeley
001B4F Avaya
00E007 Avaya ECS</pre>
</blockquote>
<p>Let's take a look at how many registrations some companies have.</p>
<blockquote><pre>$ oui -s dell | wc -l
29</pre>
</blockquote>
<p>That's about 500 million possible MAC addresses, which sounds right for the world's largest PC manufacturer.  Let's try my favorite server manufacturer, Supermicro.</p>
<blockquote><pre>oui -s supermicro "super micro" | wc -l
2</pre>
</blockquote>
<p>Ahh, not so much.  What about Cisco?  They seem to have a lot of devices out there on the ol' Internets.</p>
<blockquote><pre>$ oui -s cisco | wc -l
448</pre>
</blockquote>
<p>Wow.  That's 7.5 billion possible MAC addresses.</p>
<p>We can also see how many registrations are currently marked "private".  These are registrations where the IEEE keeps the manufacturer's identity private for a time, in exchange for a yearly fee.</p>
<blockquote><pre>$ oui -s -c '^PRIVATE$' | wc -l
43</pre>
</blockquote>
<p>A few notes: First, you will get no results if you just have the nmap database installed, as it uses a condensed format and filters out private registrations.  Second, you can use regular expressions to match an organization (PCRE).  Third, the -c flag forces the search to be case sensitive.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/01/16/oui-an-ieee-oui-database-search-utility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hampr Mobile compatible with iPhone, Android, Pre</title>
		<link>http://www.finnie.org/2010/01/07/hampr-mobile-compatible-with-iphone-android-pre/</link>
		<comments>http://www.finnie.org/2010/01/07/hampr-mobile-compatible-with-iphone-android-pre/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 08:42:51 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Hampr]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1230</guid>
		<description><![CDATA[Two years ago, an "iPhone" version of the Hampr web interface was released, optimized for the iPhone web browser.  Well, here we are in The Future, and the same interface works equally well on many WebKit-based mobile browsers.  The Hampr Mobile interface has been tested on:

iPhone (all versions)
Android 1.6 &#038; 2.0 (including T-Mobile [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.hampr.com/images/hampr-ss-mobile-webkit.png"><img src="http://www.hampr.com/images/hampr-ss-mobile-webkit-sm.png" alt="Hampr Mobile screenshot" style="float: right; margin: 1em;" /></a>Two years ago, an "iPhone" version of the Hampr web interface was released, optimized for the iPhone web browser.  Well, here we are in The Future, and the same interface works equally well on many WebKit-based mobile browsers.  The Hampr Mobile interface has been tested on:</p>
<ul>
<li>iPhone (all versions)</li>
<li>Android 1.6 &#038; 2.0 (including T-Mobile G1, Droid, and the upcoming Google Nexus One)</li>
<li>Palm Pre/Pixi (and presumably future WebOS-based mobile phones)</li>
</ul>
<p>In light of this, the interface is now available a <a href="https://www.hampr.com/mobile/webkit">https://www.hampr.com/mobile/webkit</a> (the old URL, <a href="https://www.hampr.com/iphone">https://www.hampr.com/iphone</a>, will continue to work).  When you log into <a href="https://www.hampr.com/">https://www.hampr.com/</a>, the mobile link at the bottom-right corner of the page will be customized according to what mobile device it detects ("iPhone Version", "Android Version", etc), but the interface itself is the same for all WebKit-based mobile devices.</p>
<p>All phones listed above allow you to bookmark the Hampr Mobile interface and save the bookmark on your home screen.  No "App" needed!  And of course, while on the desktop, be sure to download the <a href="https://www.hampr.com/firefoxextension">Hampr Firefox extension</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/01/07/hampr-mobile-compatible-with-iphone-android-pre/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hampr Firefox extension 2.2 released</title>
		<link>http://www.finnie.org/2010/01/01/hampr-firefox-extension-2-2-released/</link>
		<comments>http://www.finnie.org/2010/01/01/hampr-firefox-extension-2-2-released/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 22:39:38 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Hampr]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1227</guid>
		<description><![CDATA[Hampr is a free, centralized, personal bookmark manager. Hampr is designed for users who want access to their bookmarks from several locations, such as home, work and school. Hampr is similar in concept to del.icio.us, but is not public in nature.
Changes in version 2.2 of the Hampr Firefox extension include:

Extension is now aware of Firefox's [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://www.hampr.com/">Hampr</a> is a free, centralized, personal bookmark manager. Hampr is designed for users who want access to their bookmarks from several locations, such as home, work and school. Hampr is similar in concept to del.icio.us, but is not public in nature.</p>
<p><a href="https://www.hampr.com/firefoxextension"><img src="https://www.hampr.com/images/hampr-2.0.0-screenshot.png" style="float: right; border-style: none;"/></a>Changes in version 2.2 of the Hampr Firefox extension include:</p>
<ul>
<li>Extension is now aware of Firefox's Offline mode, and will not try network operations when Offline.</li>
<li>A copy of a recent server refresh will be stored locally periodically, and will be used when a new window is opened and the extension is accessed, before the extension has had a chance to get updates from the server.</li>
<li>Extension has been tested against Firefox 3.6 beta.</li>
</ul>
<p>Please visit <a href="https://www.hampr.com/firefoxextension">the extension home page</a> and give it a try!  Hampr is fully OpenID-enabled; for information about creating an account, please visit <a href="https://www.hampr.com/login">the login page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2010/01/01/hampr-firefox-extension-2-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I forgot about Christmas.</title>
		<link>http://www.finnie.org/2009/12/23/i-forgot-about-christmas/</link>
		<comments>http://www.finnie.org/2009/12/23/i-forgot-about-christmas/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 02:14:56 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1222</guid>
		<description><![CDATA[Literally.
Ever since a week before Thanksgiving, I've been working on a massive project for work.  I'd like to talk about it in detail sometime later because even though it was an exhausting project, it was still very fun and interesting, but that's another post.  It all culminated with an 8 day trip to [...]]]></description>
			<content:encoded><![CDATA[<p>Literally.</p>
<p>Ever since a week before Thanksgiving, I've been working on a massive project for work.  I'd like to talk about it in detail sometime later because even though it was an exhausting project, it was still very fun and interesting, but that's another post.  It all culminated with an 8 day trip to Boston, which I got back from Monday night.</p>
<p>Friday night I was at my hotel, watching TV, when I thought to myself, "Man, they're advertising Christmas shopping earlier and earlier this year."  Then I looked at a calendar: it was one week from Christmas.</p>
<p>I was aware of the dates as they passed, but frankly my mind wasn't processing them as they related to holidays, just various deadlines for work.  I got home Monday, was still exhausted Tuesday (and the roads were very slick), and now it's 2 days from Christmas.</p>
<p>So yeah, I didn't get anybody anything.  Sorry.  To make penance, I whipped out the plastic and decided to donate to charity.  I had planned on spending about $250, and was deciding between the <a href="http://www.aclu.org/">American Civil Liberties Union</a> and the <a href="http://www.eff.org/">Electronic Frontier Foundation</a>, but at the last moment I said "what the hell" and donated $250 to each.  They both do good work, and I am glad they are there when we need them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2009/12/23/i-forgot-about-christmas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Outside dial tones on SPA500 series phones</title>
		<link>http://www.finnie.org/2009/11/27/outside-dial-tones-on-spa500-series-phones/</link>
		<comments>http://www.finnie.org/2009/11/27/outside-dial-tones-on-spa500-series-phones/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 07:36:06 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1214</guid>
		<description><![CDATA[I'm currently in the process of upgrading our phone systems at work.  In the Reno and Salt Lake City offices, we had a Cisco Unified Communications VoIP system going back to 2001, with Cisco 7900 series phones.  The 7900s used SCCP, a proprietary but decently understood protocol to talk with the call managers. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.finnie.org/wp-content/uploads/2009/11/photo.jpg"><img src="http://www.finnie.org/wp-content/uploads/2009/11/photo-225x300.jpg" alt="Cisco SPA504G" title="Cisco SPA504G" width="225" height="300" style="float: right; margin: 1em;" /></a>I'm currently in the process of upgrading our phone systems at work.  In the Reno and Salt Lake City offices, we had a <a href="http://www.cisco.com/en/US/netsol/ns151/networking_solutions_unified_communications_home.html">Cisco Unified Communications</a> VoIP system going back to 2001, with <a href="http://www.cisco.com/en/US/products/hw/phones/ps379/index.html">Cisco 7900 series</a> phones.  The 7900s used SCCP, a proprietary but decently understood protocol to talk with the call managers.  Earlier this year, the call managers died.  We had been preparing for this possibility, and had an <a href="http://www.asterisk.org/">Asterisk</a> system ready that was able to talk SCCP to the 7900 phones.  Unfortunately, the SCCP driver is graciously described as "beta" (remember, it's a proprietary protocol).  Everything mostly worked, but we lost the ability to do 3-way conferencing via the phones.  So now we're replacing them with <a href="http://blog.voipsupply.com/first-look-cisco-spa504g-ip-phone">Cisco SPA504G phones</a>, which use the industry standard SIP protocol.</p>
<p>In the last few weeks/months, I've been preparing to make this process as smooth as possible from a user perspective, since this is the most visible aspect to the employees.  One of the features of the 7900 phones is a separate tone when reaching an outside line.  When you pick up the phone, you hear a standard North American dial tone (350 + 440 Hz).  When you press 9, however, that changes to a different dial tone, to signal that you are "outside" and can dial as if you were at a regular POTS phone.  <a href="http://www.finnie.org/wp-content/uploads/2009/11/outside-line.wav">Here is a sample audio file of that process.</a>  I always found the order to be backwards; I figured the "inside" dial tone should be non-standard, and once you hit 9, you'd be presented with a standard North American dial tone.  Oh well.</p>
<p>The SPA504G can be programmed to generate an outside dial tone, but it defaulted to a single 440 Hz tone, which just did not sound right.  It's customizable, so I started looking for what DTMF combination the 7900's outside dial tone is.  I didn't find anything online, and while many of the tones on the 7900s are sent to the phone by the call manager, the outside dial tone is hard-coded in the phone's firmware.  I could have probably figured it out if I had an oscilloscope, but I didn't have access to one.  Random fiddling came close, but it still sounded off.</p>
<p>Through some reading, I eventually figured out that "special tone frequencies" are always in multiples of 40, 50 and 90 Hz.  This apparently makes it easier to determine what two tones are being sent in a DTMF sequence.  A dial tone is 350 + 440 Hz (90 Hz difference), a ringing tone is 440 + 480 Hz (40 Hz difference), and a busy signal is 480 + 620 Hz (90 + 50 Hz difference).  With that, I was able to narrow down the possibilities, and came up with 440 + 530 Hz for Cisco's outside dial tone.  The low tone is 90 Hz higher than the 350 Hz low tone of the dial tone, and the high tone is 90 Hz higher than the low tone.</p>
<p>If you happen to be in my same situation (or if you just want to use an outside dial tone that sounds better than that stupid single 440 Hz outside dial tone that the SPA504G defaults to), go to Admin, Advanced, Regional, Call Progress Tones, Outside Dial Tone, and use this:</p>
<pre>440@-19,530@-19;10(*/0/1+2)</pre>
<p>Note that to actually get the phone to play an outside dial tone, you must configure your dial plan to support it.  That means that after every 9, enter a comma.  Here's my current dial plan:</p>
<pre>(3xxx|*22xx|*23xx[0-9*#].|*2x|*3xxx|9,11|9,911|[346]11|0|9,[2-9]xxxxxx|9,1[2-9]xx[2-9]xxxxxx|9,011xx[0-9*#].)</pre>
<p>Note that <strong>all</strong> leading 9s need to have a comma after for this to work.  See, for example, <code>9,11|9,911</code>.  The user can still either dial 911 or 9911 in an emergency, it's just the outside dial tone will play after the first 9.</p>
<p>By the way, for that example wav file I showed above, I had considered recording the actual sound coming from the phones with a microphone, but I decided to do it all in <a href="http://audacity.sourceforge.net/">Audacity</a> instead.  That's right, it was completely computer-generated.  All I had to do was use Audacity's tone generator on separate channels (for example, one channel with a 350 Hz tone and one channel with a 440Hz tone for the regular dial tone), and then combine everything down into a single mono channel.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2009/11/27/outside-dial-tones-on-spa500-series-phones/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.finnie.org/wp-content/uploads/2009/11/outside-line.wav" length="51898" type="audio/x-wav" />
		</item>
		<item>
		<title>Fear and Loathing in Second Life</title>
		<link>http://www.finnie.org/2009/11/16/fear-and-loathing-in-second-life/</link>
		<comments>http://www.finnie.org/2009/11/16/fear-and-loathing-in-second-life/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 05:40:11 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1201</guid>
		<description><![CDATA[I signed up for a Second Life account a few years ago, but I rarely used it.  It really wasn't that fun for me.  Later, I learned that simply being in Second Life wasn't the fun part; it was creating and building that was interesting.  However, building anything lasting required a premium [...]]]></description>
			<content:encoded><![CDATA[<p>I signed up for a Second Life account a few years ago, but I rarely used it.  It really wasn't that fun for me.  Later, I learned that simply being in Second Life wasn't the fun part; it was creating and building that was interesting.  However, building anything lasting required a premium account ($9.95 per month), which "entitles" you to buy 512m<sup>2</sup> of land via the in-world economy.  So last December, I bought some land.</p>
<p><a href="http://www.flickr.com/photos/fo0bar/3196215896/" title="010 by Ryan Finnie, on Flickr"><img src="http://farm4.static.flickr.com/3512/3196215896_a1a493bf9e_m.jpg" width="240" height="143" alt="010" style="float: right; margin: 1em;" /></a>It was quite a steal, as far as in-world land goes.  I paid L$8500 (approx. $34) for a 1536m<sup>2</sup> plot at the edge of a sloping green hill region, overlooking a "protected" beach region.  (Protected means nobody can actually buy the land, it simply remains empty.)  The view was excellent.  The seller had literally just put the land up for sale, and I had just happened to find it via the land sale search when he did.  This is the sort of land that could easily go for double that.</p>
<p>I started working away, building objects and sometimes buying others.  At first I just was doing random things with the land, but I later decided to build the Finnix Information Center.  (More information about that is available in <a href="http://blog.finnix.org/2009/01/13/finnix-in-second-life/">this Finnix blog post</a>.)</p>
<p>At one point, the land immediately south of my land went up for sale, at L$10000 ($40) for 1024m<sup>2</sup>.  I bought it, not knowing what I'd do with it, but it was still a good deal.  I set it for sale at L$30000 ($120) in case anyone really, really wanted it, but in the meantime, I just used the area for various projects.  But about 2 months later, someone bought it!  I made a quick buck.</p>
<p><a href="http://www.flickr.com/photos/fo0bar/3195374383/" title="090 by Ryan Finnie, on Flickr"><img src="http://farm4.static.flickr.com/3484/3195374383_2b0680a95a_m.jpg" width="240" height="143" alt="090" style="float: right; margin: 1em;" /></a>Keep those numbers in mind: L$30000 for 1024m<sup>2</sup>.  That was fairly typical of the area.  Just like in real life, in-world land is driven by mostly aesthetic factors.  Is the area cluttered?  Do the neighbors have big fences butting up against your property?  Good neighborhood?  What's the terrain like?  Grass or rocky?  This area was one of the best areas you could get.  It was on a small slope, and had an unobstructed easterly view of a protected region on the beach.  The only way you could do better was to find land directly on the beach.</p>
<p>Well, one day, Linden Labs decided to un-protect that region and sell it off to developers.  Literally overnight, a strip mall moved in next door and blocked my view of the beach.  At this point, I had started losing interest in Second Life again, so having "just another plot of land" wasn't worth me maintaining.  As a great leader once said, "It's been swell, but the swelling's gone down."</p>
<p>Eventually, I dismantled the Finnix Information Center.  I wanted to sell the land, so I started looking at other land for sale in the area, and it was pretty dismal.  I ended up selling 1024m<sup>2</sup> of the 1536m<sup>2</sup> directly to a neighbor (it filled in the square of her land, making it 4096m<sup>2</sup>) for L$4000 ($16).  For the other 512m<sup>2</sup>, I put it up for L$2500.</p>
<p>It sat there for months.</p>
<p>I logged in tonight, saw that it had not been sold, and then thought, "Wait a minute.  I'm paying $10 per month to try to sell this land for $10!"  I went on land sale search, saw that the cheapest 512m<sup>2</sup> plot was L$800, and set mine to L$786 ($3.14).  It was sold within 3 minutes.  By a guy who immediately put it up for sale for L$940 ($3.76).</p>
<p>So that's it.  I bought 1536m<sup>2</sup> for L$8500 and sold it for L$4786.  That's pretty dismal, considering at its height, I sold the equivalent of 1536m<sup>2</sup> for L$45000.  Now, part of it is the economy, both real-life and in-world.  I've noticed that items like clothing seem to sell for about the same types of prices they sold for a year ago, but the in-world land market seems to have collapsed.  Here's my working guess: That 1536m<sup>2</sup> plot of land may only cost L$5000, which is $20 of your real-world money, but it then costs $18 per month in the form of land use fees.  ($10 per month is basic premium access with 512m<sup>2</sup> of land use rights, but everything above that amount of land costs extra monthly fees.  An extra 1024m<sup>2</sup> is an extra $8 per month.)</p>
<p>So it costs a decent chunk of change just to continue owning land.  $18 may not have been much a year ago, but you may be tighter for money now.  However, items like clothing don't have to live anywhere.  They're either on you, or stored in your inventory.  So you don't need to own land to buy and use clothing, so you don't need a premium membership.  Therefore, the price of in-world clothing has remained pretty stable, while the price of land has crashed.</p>
<p>It's funny how closely the in-world land market is mimicking the real-world housing market.  Fly around Second Life and you'll see a LOT of land available, most of it very cheap.  But just like how I can't buy a house in the real world now -- even though I'd love to and it's a buyer's market -- there's not a lot of interest in in-world land ownership because of how much it cost to keep that land.  And just like how there are many foreclosed homes in the real world, there is a lot of abandoned land in-world.  Land is usually abandoned when a user stops paying for their account without first selling off their land.  Eventually Linden Labs will take this land and sell it at auction, much like a real-world bank.</p>
<p>That's Second Life economics on a macro scale.  As for my personal situation, I blame the strip mall.</p>
<p>Anyway, I went into my account and set it back to the Free account type.  I'm still playing with building in-world, but these days I'm on <a href="http://www.osgrid.org/">OSGrid</a>.  It's a Second-Life compatible grid that uses <a href="http://www.opensimulator.org/">OpenSimulator</a>, and the land is free, since you're running your own OpenSim server.  Come on by!  The region name is "Undef Lagoon" on OSGrid.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2009/11/16/fear-and-loathing-in-second-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Chef Fo0bar presents: Sausage Roll Prerelease</title>
		<link>http://www.finnie.org/2009/11/08/chef-fo0bar-presents-sausage-roll-prerelease/</link>
		<comments>http://www.finnie.org/2009/11/08/chef-fo0bar-presents-sausage-roll-prerelease/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 04:29:52 +0000</pubDate>
		<dc:creator>Ryan Finnie</dc:creator>
				<category><![CDATA[Chef Fo0bar Presents]]></category>

		<guid isPermaLink="false">http://www.finnie.org/?p=1196</guid>
		<description><![CDATA[
Most of the dishes I've presented here have turned out well.  However, I thought I'd document a dish that didn't work out the best, but still has potential for improvement.  A culinary beta, as it were.
A discussion about "sausage rolls" started in IRC this evening.  Sausage rolls are pretty simple, just sausage [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/fo0bar/4087845507/" title="Sausage roll by Ryan Finnie, on Flickr"><img src="http://farm3.static.flickr.com/2506/4087845507_84d04e74d7.jpg" width="500" height="375" alt="Sausage roll" /></a></p>
<p>Most of the dishes I've presented here have turned out well.  However, I thought I'd document a dish that didn't work out the best, but still has potential for improvement.  A culinary beta, as it were.</p>
<p>A discussion about "sausage rolls" started in IRC this evening.  Sausage rolls are pretty simple, just sausage and seasonings inside a dough wrapper, and are popular in the UK, Ireland and Australia.  I decided to try my hand at a variation, as a single sausage loaf, designed to be cut into slices and served.</p>
<p><a href="http://www.flickr.com/photos/fo0bar/4087844013/" title="Sausage roll by Ryan Finnie, on Flickr"><img src="http://farm3.static.flickr.com/2476/4087844013_3e65f7e03f_m.jpg" width="240" height="180" alt="Sausage roll" /></a> <a href="http://www.flickr.com/photos/fo0bar/4087844817/" title="Sausage roll by Ryan Finnie, on Flickr"><img src="http://farm3.static.flickr.com/2579/4087844817_12b9bcb0d9_m.jpg" width="240" height="180" alt="Sausage roll" /></a></p>
<p>I took a tube of crescent rolls, but instead of pulling them apart into triangles, I left the sheet of dough intact.  I then spread a pound of Jimmy Dean "sage sausage" (you can use regular sausage, with some sage rubbed into it) over the dough, leaving some room on the sides and top.  I then rolled the dough and sausage into itself, much like a cinnamon roll.  Crimp the top and ends, patch up any exposed areas of dough, and put into a 350 degree oven for 30 minutes.  I always leave a baking stone inside my oven, and put the mega-roll directly on the stone.</p>
<p><a href="http://www.flickr.com/photos/fo0bar/4087846161/" title="Sausage roll by Ryan Finnie, on Flickr"><img src="http://farm3.static.flickr.com/2488/4087846161_7366bf2636_m.jpg" width="240" height="180" alt="Sausage roll" /></a></p>
<p>This was the result.  I pulled the loaf after 25 minutes, and you can tell it was still a little pink in the middle.  But another 5 minutes in the oven cooked it all the way through.  I really liked the flaky outer crust, but the inner dough pooled in the middle, and was... well, doughy.  It wasn't the consistency I was expecting.</p>
<p>It was certainly edible, but next time I'll make a few changes.  Namely, instead of one rolled loaf using the entire sheet of crescent roll dough, I'll split into 4 quarters, still leaving the diagonal perforations connected.  That way there is no inner dough, and the result will be a more consistent baking experience.  But again, overall I liked the idea of using crescent roll dough, and baking directly on a baking stone turned out well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.finnie.org/2009/11/08/chef-fo0bar-presents-sausage-roll-prerelease/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
