Stop emailing me about yahoo

Posted to old on 2003-06-25 18:48:00

So I posted weblog about being banned from yahoo and it was dormant for months. Now I seem to get a comment about every two weeks from people who think I can magically get their yahoo accounts back. Yup, I've got magic powers on a site I don't care about. Do you think that I'd be someone who can fix your stupid yahoo account? Did I even sound like I was sad I got banned? You people are probably the same type of people who fall for those fake PayPal emails asking you to enter your credit card numbers in an email.


Smart Mobs

Posted to old on 2003-06-17 12:06:00

This has to be one of the most intereseting social engineering efforts that I've ever seen. Apparently some people in New York are organizing themselves to all show up at a particular store for 10 minutes, the miracuously disperse. There is more information over at cheesebikini. I think this is an interesting concept, but the person organizing seems to be rather put off that someone called the cops last time. I'd be pissed off too. It's a perfectly safe gathering of people. It's probably going to be good business for the businesses involved because they see lots of people coming in and out. And best of all, it's meant to be safe. Don't cops have better things to do, like busting child molestors or thieves? Oh well, welcome to Ashcroft's America.


Goodbye pridkett [pridkett@dreams.wagstrom.org]

Posted to old on 2003-06-12 21:01:00

I'm a little sad. Hurricane Electric had to filter IRC traffic over their TunnelBroker IPv6 service. Apparently some people were doing dos attacks with it. That makes me sad, I enjoyed it because I could set my own reverse DNS. I still can for IPv6, but I just can't use IRC through IPv6 anymore.


Bruce Sterling Interview

Posted to old on 2003-06-04 12:08:00

There is a pretty good interview with Bruce Sterling at news.com.com. It varies from topic to topic, but spends some time talking about the dangers of data mining, mentions TIA, and other assorted stuff.


WinTV PVR 250 Under Linux

Posted to old on 2003-06-03 13:42:00

On Memorial Day, CompUSA had a really good sale on WinTV PVR 250 hardware MPEG encoder cards. I had been thinking about getting one for a while now, but they were too much on eBay. Well, after using a few tricks, the final price will be $75 after rebate. The card showed up on Thursday morning. What follows is how I got it working.

Major References

This guide will tell you how to get the card running with MythTV and LIRC. Here are some of the sites that will be very helpful to you on your quest.

Kernel Recompiling

If you're afraid of recompiling the kernel, abandon all hope and turn back now. I've heard that if you have RedHat 9, that you're in good shape as it already has Video4Linux2 installed. If you're using something else, like RedHat 7.3 (or gentoo, or debian....), then you're going to need to do this.

The first step is to go download the kernel sources from kernel.org. You'll need at least 2.4.20 for this to work. The next thing you'll need is the kernel patches for the new video for linux drivers. You can find these at http://bytesex.org/patches. I recommend getting the all in one patch because you don't need to worry about order then. Now it's time for some patching fun. Apply the patch the the kernel. This can be done by copying the patch to your /usr/src/linux after unpacking the new kernel. Then you can patch your kernel using the following procedure (the output is for kernel 2.4.20 with this patch):

# gzip -dc [patchfile.gz] | patch -p1
patching file arch/x86_64/config.in
patching file drivers/media/video/videodev.c
patching file Documentation/Configure.help
patching file Documentation/scsi-changer.txt
patching file arch/sparc64/config.in
patching file arch/sparc64/kernel/ioctl32.c
patching file drivers/scsi/Config.in
patching file drivers/scsi/Makefile
patching file drivers/scsi/ch.c
patching file include/linux/chio.h
patching file include/linux/major.h
patching file include/scsi/scsi.h
patching file drivers/media/video/Makefile
patching file drivers/media/video/v4l1-compat.c
patching file drivers/media/video/v4l2-common.c
patching file include/linux/videodev.h
patching file include/linux/videodev2.h
patching file drivers/media/video/bt832.c
patching file drivers/media/video/bt832.h
patching file drivers/media/video/bt848.h
patching file drivers/media/video/bttv-cards.c
patching file drivers/media/video/bttv-driver.c
patching file drivers/media/video/bttv-if.c
patching file drivers/media/video/bttv.h
patching file drivers/media/video/bttvp.h
patching file Documentation/video4linux/bttv/CARDLIST
patching file Documentation/video4linux/bttv/Cards
patching file Documentation/video4linux/bttv/Sound-FAQ
patching file drivers/media/video/audiochip.h
patching file drivers/media/video/msp3400.c
patching file drivers/media/video/tda7432.c
patching file drivers/media/video/tda9875.c
patching file drivers/media/video/tda9887.c
patching file drivers/media/video/tvaudio.c
patching file drivers/media/video/tvaudio.h
patching file drivers/media/video/tvmixer.c
patching file drivers/media/video/tuner.c
patching file drivers/media/video/tuner.h

Now comes the part of kernel compilation that everyone loves. Wading through pages and pages of options for devices that no one has used for 10 years to get to the stuff that you need. You'll need to make sure that CONFIG_I2C, CONFIG_I2C_ALGOBIT, CONFIG_VIDEO_DEV and CONFIG_VIDEO_PROC_FS are all set. If you can do it as a module, that would probably be helpful. I might have forgotten a few things here. So don't kill me. I hate kernel compiling.

Wash, rinse, repeat until your shiny new kernel works. There is plenty of stuff out there on how to install a kernel, so don't ask me. Go read the docs.

Driver Compiling

After you've managed to recompile your kernel you need to go and compile the drivers. You can fetch the CVS drivers off ivtv.sf.net. Follow the instructions posted in the FAQ about how to get it to work. It is very important that you not miss the section about ripping the firmware from the CDROM. Without the firmware the drivers will not work.

After you've made the drivers you need to add some lines to your /etc/modules.conf file to automatically load the appropriate modules.

# WinTV PVR 250
alias char-major-81 videodev
alias char-major-81-0 ivtv
options ivtv debug=1 mpg_buffers=32
options tuner type=2
options msp3400 once=1 simple=1
add below ivtv msp3400 saa7115 tuner

If you have another tuner card in your system that is /dev/video0, you will probably need to change the alias char-major-81-0 ivtv to the approriate reference to /dev/videoX (where X is the id of your ivtv card). You can find this by running ivtv/utils/ivtvfwextract.pl --use-encoder-image=2. You may need to change that value for encoder image, but that's what worked for me.

XMLTV Fun

One of the major components that is needed for MythTV to function properly is XMLTV. This is a perl module that you can pick up from http://membled.com/work/apps/xmltv/. There are nice pacakges for Redhat 9 on there, but we're not using RedHat 9, so we need to compile it from source. There is a good chance that this will require some extra packages, this is where perl -MCPAN -e shell quickly becomes your friend. As it complains about packages not being installed, install them. You should be in good shape after this.

Lucky for you, this is going to lead up to how to install MythTV. MythTV doesn't require you do any complex setup for XMLTV, so don't worry about setup for now.

LIRC

Now you'll probably want to get that cool remote control of yours working. This can be accomplished via the lirc_i2c module of lirc. Just compile the module using the standard methods. If for some reason the lirc_i2c module doesn't work correctly, you should try running the command: ./configure --with-driver=hauppauge to ensure it gets compiled. Then you'll want to install the drivers and make sure that everything is good in your /etc/modules.conf. Make sure to add these lines:

# lirc stuff
alias char-major-61 lirc_i2c

The next step is to copy the configuration file to the /etc/lircd.conf. You shouldn't have to worry about training your remote and making your own configuration file because the ivtv driver comes with a remote file for the remote. In my case I have the gray remote, so I copied ivtv/utils/lircd-g.conf to /etc/lircd.conf and everything seemed to work fine.

The final step is probably the most annoying. You still need to configure your remote control by creating your own ~/.lircrc file. I'm not going to list the entire contents of my file here. But, you can download it my .lircrc file. It is preconfigured for mplayer and irxevent, which is what MythTV uses.

MythTV

The last thing that you'll want to do is install MythTV. Installing this will make your friends wish they were as cool as you and feel shame because they still run windows. It really has the potential to be a "killer application" for Linux.

I'm not going into the details on how to get mythtv running. There is lots of documentation on the mythtv website that I would suggest you read. It's not an easy program to install as it requires MySQL in addition to the stuff above, but you should really enjoy it.

Random Helpful Tips

If you just want to watch some live TV without installing MythTV, you can use the ghetto mplayer trick. Using a command line like mplayer -vo xv /dev/video -cache 65536 will provide live TV with a short buffer for pausing the screen. In reality you need more than a 64 meg cache to really make it productive.

One thing that I've found really helpful is to have some aliases set up so I can do some easier manipulation of the card via the command line. I've pased them here (for Bash), in hopes that they might help you:

                alias test_ioctl='~patrick/ivtv/ivtv/utils/test_ioctl'
                alias tvsmall='test_ioctl -f width=400,height=300'
                alias tvmed='test_ioctl -f width=512,height=384'
                alias tvlarge='test_ioctl -f width=720,height=480'
                alias tvqmed='test_ioctl -c bitrate=4000000,bitrate_peak=10000000'
                alias tvqhigh='test_ioctl -c bitrate=8000000,bitrate_peak=16000000'
                alias tvqlow='test_ioctl -c bitrate=2500000,bitrate_peak=5000000'
                alias ptune='/home/patrick/ivtv/ivtv/utils/ptune.pl --channel'
                alias noghost='test_ioctl --set-codec-params=dnr_mode=0,dnr_temporal=0'

The first three (tvsmall, tvmed, tvlarge) set the resolution that the card captures video at. The next three (tvqhigh, tvqmed, tvqlow) set the quality taht the bit stream is recorded at. ptune is a simple alias so you can change the channel. Finally, noghost can be used if your card is getting weird ghosts that wouldn't be there on a normal TV.

As a side note, when I first started, I almost used freevo instead of MythTV because I could get it to work better and faster. I gave MythTV one last shot before I was to kill it, and was able to make it sing. There are a few tricks you should know. First of all, running the UI for MythTV at a resolution other than 800x600 will incur a performance penalty as everything has to be scaled. There are options in the program to force it to run at a certain resolution, use them. Secondly, if you have a slower computer, turn off deinterlacing. This is covered in the FAQ for mythtv, but reading the mailing list indicates that a lot of people miss this entirely. Lastly, if it is really slow on playback, lower the video quality to a lower resolution. The default is full frame maximum quality, which while fine for an Athlon XP 3200+, doesn't cut it on my Athlon 700.


A hefty dose of slashdotting...

Posted to old on 2003-05-27 18:12:00

It was a peaceful Saturday morning. The sun was out. The skies were blue. A few birds were singing. Overall it was one of those beautiful late May days here in Chicagoland. I was completely unaware that coming my way was attack which no mere mortal could stand in the way of, the slashdot effect was heading my way.

I began by thinking that my broadband connection was just a little slow. I was browsing CNN and Slashdot some and it seemed a little slow. I attributed this, at first, to some over aggresive filters that I had running. You see, I run a healthy dose of portsentry on my computer. This means that quite frequently sites get blocked if they try to open connections to my computer. In the past this has blocked CNN and OSDN's ad servers, IIT's webmail, and a host of other sites that I find generally useful.

Anyway, stuff was slow, so I reloaded slashdot for about the fifth time that morning, and that's when I saw the horror. My weblog had made front page news on slashdot. The fury was about to begin...

The Beginning

The original article was posted to my web page at 4:30pm CDT on May 23rd, 2003. Shortly afterwards I posted a comment on this thread at deadly.org which had inspired my work in the first place. The time of that comment was about 10 minutes later (deadly is in eastern time). It's unfortunate that deadly didn't automatically linkify it like it was supposed to because I can't track how many people came to visit it after that.

CowboyNeal posted the article on the slashdot homepage at 9:10AM CDT on May 24th, 2003. Previous to this point in time there was not a single person who followed a referrer to my page. Meaning that slashdot was the first link that was pointed to my site. The first reference to slashdot that appears in my log was from cache-1.atw.pa.webcache.rcn.net, it's hard to tell if this is the person who submitted the article, or a slashdot editor. My hunch is that the slashdot editor used the address 24.247.221.123.kzo.mi.chartermi.net as I'm pretty sure they all still live in the Holland/Grand Rapids/Kalamazoo area. These first hits started around 8:53AM CDT.

Previous to this point I had received 39 visits to the page with no referrer tag marked. This means that deadly has higher traffic than I thought as there were 39 people willing to paste the URL I posted into their location bars. Another interesting thing is the number of people who used the near future feature of slashdot was fairly low. Only 14 hits registered a referrer from slashdot before 9:10AM CDT on May 23rd.

The Initial Onslaught

At 9:10AM we saw the initial barrage begin. I figure that at this point it was the actual posting of the article on slashdot because the hits started to come fast and furiously. What we see below is a plot of the hits versus time for the first few hours. The red steps are the hits that I received for that minute and the green line is the smoothed version of those results using gnuplot's bezier option. It's not a true trend line, but it's good enough for my work here. This graph includes only requests for the actual document, and not the associate style sheets.

We can see that the server peaked around 1 request per second for the page. With associated requests for browsers that automatically request favicon.ico and the stylesheet this would be multiplied by a factor of two to three. It also should be noted that ideally only one of those requests would go out and try to fetch the hostname of the requesting host, although I can't be sure of that because I didn't collect that information.

Another issue of concern was the total bandwidth that was being consumed. While I don't have a 100% accurate way of measuring this, I can get a good estimate based off the number amount of data the apache says it sent each minute. This shows the bandwidth consumption for the initial slashdot effect and includes the css sheet, but it does not include the HTTP headers that were sent and the overhead if the data was chunked.

Surprisingly enough, it seems like the actual server processes held up pretty well. The computer that runs these servers is nothing spectacular, that's for sure. It's a little K6-200 with 4 gigs of hard disk and 96 megs of ram; network connectivity is done via 2 ISA ethernet cards. During the slashdotting I had no problem sshing into the computer on the second interface and looking around.

When I logged in I saw that the total system load was around 0.7. This was at the peak of the slashdotting. I also looked at the number of running httpd servers, it was around 30 or so. This is far less than the 150 max servers that I had set in the configuration file. I did notice things were a little slow and eventually traced this back to MySQL dieing a brutal death. Apparently it only recently became stable on current. This is the first time that I had problems with MySQL under OpenBSD, so I would have never known it was unstable. This is also why there are no comments from the peak of the slashdotting. People just couldn't connect to the mysql server.

The After Effects

After I realized that my broadband connection wasn't going to be of any use for the near future and observed that it was one of those very rare days in Chicago when the weather was actually nice, I decided to leave the system be and go outside. I returned later that night and found that my broadband connection was very usuable again, and almost to the point where it seemed like nothing happened.

The following graphs provide more information on how the slashdot effect slows down. It seems like it has an exponential decay in the number of requests.




It's pretty clear that by 6 hours after the initial posting to slashdot, my broadband connection was easily usuable again. By 12 hours after the initial slashdotting the stream had slowed to a point where it would be very hard to even tell that a slashdotting had occurred.

Collateral Damage

As mentioned in the article, this was all inspired by some images on Daniel Hartmeier's site. I also linked to those images. After the slashdotting I requested and received the logs from his site for the related images and found some interesting information. First of all, there were 6275 total requests made to his site because of this article. Of which 5528 came from my copy of the article, and 747 came from the mirror that slashdot posted at lmo.warcry.com.

These two graphs illustrate the bandwidth used only by references from the two links on slashdot. I didn't try to track visits and see how much total bandwidth was consumed if someone clicked to go to the index page and then browsed around for a long time. These are only cases where the referrer is one of the two sites on slashdot. The first one is for the first four hours of the slashdotting, the second one is for the 48 hours after the slashdotting. Once again, these represent the bandwidth only as his web server, thttpd, reported it.



This should be a concern for anyone that links to things on the web, especially if you know that page might be slashdotted. From reading Daniel's page, he states that he has a 128Kbps dsl line. This means that his upstream is capped around 100Kbps after you factor in PPOE overhead. Thus, at the initial onset, when it was averaging to over 5k/s, with spikes up to 10k/s, the links alone were consuming a substantial portion of his bandwidth.

Moving along, we see that the requests on the linked site follows almost the exact same pattern as the request to the slashdotted site. There is a nice exponential decrease, however it isn't quite as obvious because of the lower number of site visits.



For the sample period in question, there were 11624 unique hosts that accessed the original document and 1858 unique hosts that accessed the mirrored document. Of those hosts there were 3290 hosts that accessed clicked through the links to see the pictures that provided my motivation. This means that there was 23.7% overall clickthrough rate on the links (28.7% from the mirror at warcry and 23.4% from the original document). I'd like to see web advertises do that!

Now we're on to the stuff that just doesn't make any sense. Of the 3290 hosts that clicked through to benzedrine.cx, 239 of them clicked through from both the original document and the mirror. One has to wonder what these people were thinking. There were 637 hosts that visted both the original site and the mirror site. Meaning that in reality the mirror site only received about 1200 hits. By the time that the mirror was posted, the brunt had slowed down and it really didn't matter anymore.

Preventative Measures

This whole document would be fairly useless unless I had actually applied some changest to help avoid a slashdotting in the future. Whill, you can't really avoid it, unless you never post anything useful. So a better title might be dealing with slashdottings. I've listed a few pretty simple steps here that can help out in that respect.

The first is to turn off hostname lookups in your http log files. I had mine enabled because I happen to like looking at the log files and easily seeing where people came from, however, it means that most connections require an addition connection to the name server. Even though the nameserver was running locally, for an uncached address, this meant significant overhead. If you're running apache look in your configuration file and make sure the following line exists:

#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off

Another interesting point is that I was bandwidth limited in this slashdotting. As noted before, my server load never crept above 0.7 (and once I fixed MySQL, it stayed around 0.4). The solution is to install mod_gzip (there would be a link to the webpage here, but the webpage appears to have gone missing). Almost every modern web browser supports using gzip compression to on the fly compress web pages. Being as the slashdot effect linked to my weblog, which is nothing but html and css, it's not a problem to compress it. Mod_gzip takes advantage of this. You can find it in ports/www/mod_gzip.

Finally, I'm working on some additional tools. I'm writing my own mod_slashdotting module. I'm not sure if I'll ever release it or not, but I bought the apache module book a few years ago and have yet to create anything productive from it. The basic premise is this. If the server detects more then n hits in m minutes, it will use will either shut down or use some dynamic pf rules to forward all traffic to a more powerful server. Not quite sure how all the mechanics of it are going to work yet.

Also, I'm doing some work stuff with altq in OpenBSD 3.3. This lets me limit my upstream bandwidth used by HTTP servers to an arbitrary amount. Thus, if I get slashdotted again, while slashdot can complain about not being able to reach my web page, at least I'll still be able to access the rest of the network because I'll have a slice of bandwidth available for me.

Comments On My Site

After seeing some of the comments on my site, it's clear why slashdot has a moderation system. There were a lot of comments along that seemed to be made by 12 year olds (or people about the same level) that just were happy that they could make my website curse. That's pretty clever considering there already are curses on my website in various rants. Anyway, it shows that for a decent traffic site, human moderation is helpful.

This is very clear in reading the quality of the comments. Although things more easily swayed off topic on slashdot, the comments seemed longer and more robust. Most comments on my website were short and to the point. Perhaps this has something to do with karma-whoring nature of many slashdotters.

Conclusion

The first thing that can be seen is that if your site gets slashdotted, don't worry, it's only temporary. Take the rest of the day off and go outside and do something else. It will be better in a few hours anyway. This is largely because slashdot traffic roughly follows an exponential decay model.

Another observation is that a well written article can get click through rates that web advertises only dream of. A devious author could hide some links to pay-for-click sites in their HTML and make a tidy profit. I also wonder what the actual click through rate would have been for a site like Amazon where you can get a kickback if people buy the books that you reference.

One of the most interesting observations is how little a mirror site really helps in the case of a slashdotting. Either very few people choose to visit it, or by the time that it gets posted most people have already seen it. An interesting note is that the clickthrough on the mirror site was higher than the original. Perhaps future studies of the slashdot effect could help determine if this is a consistent thing, or just for this one article.

There were two rather disturbing results from this study. One is the power of slashdot to cause collateral damage. The documents I provided were very small static documents, while the documents that I linked to on benzedrine.cx were quite larger. This caused a significant amount of collateral damage to his site, based on my site being slashdotted. Secondly, the large amount of people who not only visited both the mirror and the original site, but the people who clicked through from both, seems quite high. I have to wonder why these people do such actions. Do they think that the article will be different at the different hosts?

Overall, I can say that the slashdot effect is no big deal. It saturated my broadband line for a short period, and I was a little worried that if it kept up Sprint might cancel my connection, but it slowed down quite quickly and in retrospect the bandwidth consumed is less than that of your average p2p user.

Acknowledgements

A substantial amount of this analysis would not have been possible without Daniel Hartmeier of benzedrine.cx and Lewt from lmo.warcry.com providing their httpd logs to me. Thank you very much for your help.


slashdot effect data analysis techniques

Posted to old on 2003-05-27 10:02:00

Addendum: How the Data Was Analyzed

This section of information is really part of the article. It's more just a reference for those of you who might want more information on how the data was analyzed. This section shows the tricks that I used so if you get slashdotted you can figure out what happened too.

The first piece of required information was to get just the views of the article in question. This was done via a series of grep commands that first found the references to the page in question, then eliminated references to css and icons. The next two greps eliminated any access that I might have made. I performed all the analysis on a remote computer that had access to the log via /mnt/scissors/www/logs/patrick.wagstrom.net-access_log. The following command was used to get all the references:

cat /mnt/scissors/www/logs/patrick.wagstrom.net-access_log | \
grep /weblog/archives/000128.html | grep -v css | grep -v ico | \
grep -v host106 | grep -v 192.168.1.2 > access_log

This created a file called access_log in my current directory. The next step was to do some analysis of the file. This was accomplished via the following PERL script, called webplot.pl:

#!/usr/bin/perl -w
$lastday = -1;
$lasthour = -1;
$currcount = 0;
while(<>){
   if(/\.html/){
        @results = split;
        $day = int(substr($results[3],1,2));
        $hour = int(substr($results[3],13,2));
                if ($day ne $lastday || $hour ne $lasthour) {
                        if ($lastday != -1) {
                                printf ("2003/05/%d %02d:00 %d\n", $lastday, $lasthour, $currcount);
                        }
                        $lastday = $day;
                        $lasthour = $hour;
                        $currcount = 0;
                }
                $currcount ++;
    }
}
printf ("2003/05/%d %02d:00 %d\n", $lastday, $lasthour, $currcount);

This initial version provided a listing by hour of all of the hits that the site had taken. However, I also wanted to get the hits by minute for some finer grain resolution. This required the creation of another script, webplot2.pl that read in the data and did a minute by minute analysis.

#!/usr/bin/perl -w
$lastday = -1;
$lasthour = -1;
$lastminute = -1;
$currcount = 0;
while(<>){
   if(/\.html/){
        @results = split;
        $day = int(substr($results[3],1,2));
        $hour = int(substr($results[3],13,2));
        $minute = int(substr($results[3],16,2));
                if ($day ne $lastday || $hour ne $lasthour || $minute ne $lastminute) {
                        if ($lastday != -1) {
                                printf ("2003/05/%d %02d:%02d %d\n", $lastday, $lasthour, $lastminute, $currcount);
                        }
                        $lastday = $day;
                        $lasthour = $hour;
                        $lastminute = $minute;
                        $currcount = 0;
                }
                $currcount ++;
    }
}
printf ("2003/05/%d %02d:%02d %d\n", $lastday, $lasthour, $lastminute, $currcount);

To process all of this data, I needed a way to visualize it. Luckily, gnuplot can plot just about everything you can throw at it. I used the following script to generate the graphs. It assumes that output from webplot.pl was in out.log and the output from webplot2.pl was in out2.log.

set output 'hits1.png'
set terminal png small
set ylabel "hits"
set title "hits per hour"
set grid
set timefmt "%Y/%m/%d %H:%M"
set xtics rotate
set xdata time
set xrange ["2003/05/24 00:00":"2003/05/27 00:00"]
set xtics "2003/05/24 00:00", 14400, "2003/05/27 00:00"
set format x "%b %d %H:%M"
set size 1.5,0.75
set key below title
plot 'out.log' using 1:3 title "Hits" with steps

set title "hits per minute"
set output 'hits2.png'
set xrange ["2003/05/24 15:00":"2003/05/24 19:00"]
set xtics "2003/05/24 00:00", 1800, "2003/05/27 00:00"
plot 'out2.log' using 1:3 title "Hits" with steps

Now that I had my nifty graphs, which of course you need to have people look at your page, I needed to ip addresses out of my access log, which still had the hostname in them. This was mainly because the other sites that I received access logs from all had hostnames turned off. This nifty command will parse an access log and print out all the ip addresses:

for x in `cat access_log | cut -d ' ' -f 1`; \
      do echo `host $x | sed -e "s/.* has address //"`; done

LPD for fun and MP3 playing

Posted to old on 2003-05-23 15:30:00

Background

Most true Unix geeks will recognize just how nice LPD is as a distributed queueing mechanism for managing all jobs sent to the printer. It has a beautiful simplicity to it, and some mean power to go along with it. It's a difficult beast to tame, but once you understand it, everything will start coming out exactly like you want it.

But, what most people don't realize is that LPD can be used for other things too. In fact, it can be viewed as a general queueing mechanism with a few added bells and whistles for printers. So let's examine a more interesting use of LPD, an engine for distributed spooling of MP3s.

Motivation

The main thing that got me started on this quest was seeing these two pictures (one, two) from the c2k3 openBSD hackathon I saw that obviously someone else had figured out how to do it. I sure as heck could also.

Initial Assessment

The first stop on my quest was examine the all-knowing seer of the Internet, google. That returned a wonderful page in Swedish about how to do this very task. Unfortunately, my swedish sucks, but thankfully the scripts were written in bash, and the other big thing was just a printcap file.

Creating a Printcap Entry

The first thing that you need to do is to create an entry in your printcap file for your shiny new mp3 printer. On most systems this file is /etc/printcap on my redhat 7.3 system (no sound card on the openBSD firewall) it is /etc/printcap.local. You'll want to paste the following snipped of code in there:

mp3:\
        :lp=/dev/null:\
        :sd=/var/spool/lpd/audio:\
        :if=/usr/local/bin/audiofilter:\
        :af=/var/log/audio-acct:\
        :lf=/var/log/audio-errs:\
        :sh

Now we'll walk through the entry line by line. I'll ignore the \ at the end of almost every line, that just tells lpd to keep reading because there is more to come. The last line doesn't need the \ obviously.

  • 1: mp3: - the name of your mp3 printer. In this case, just mp3
  • 2: :lp=/dev/null: - we're not hooking this up to a physical device in the normal sense
  • 3: :if=/usr/local/bin/audiofilter: - this is the input filter. I'll show how to create it later.
  • 4: :af=/var/log/audio-acct: - this is the accounting file. You could do some fun stuff with this to monitor who uses the queue the most and what not.
  • 5: :lf=/var/log/audio-errs: - this is the file that errors will be logged to. Well, some errors; not all errors will end up here.
  • 6: :sh - tells it to supress any header information that would normally be sent. This is important or you may get junk before every file which causes audiofilter to fail.

An Audio Input Filter

The key to the whole system is that all of the processing is done by input filter. On some platforms this may cause it say that the printing has stalled while a song is playing, but that's not a big deal. There is no output from the input filter, and thus nothing is done after this. You'll want to put the following piece of code on your system as /usr/local/bin/audiofilter:

#!/bin/bash
#
# This script was originally made by Teddy Hogeborn.
# Small alterations was made by:
#   Peter Lundqvist
#   Patrick Wagstrom
#
# This is a "printer filter" for playing audio files

for arg in "$@"; do
  case "$arg" in
    -d*) dir="${arg#-d}" ;;
    -e*) basefile="${arg#-e}" ;;
    -f*.*) ext="${arg##*.}" ;;
  esac
done

mp3player="mpg123 -q -o oss";
modplayer="mikmod --quiet --playmode 0 --noloops --norc"
oggplayer="ogg123 --device=oss --quiet"
file="${dir}/${basefile}"
type="$(file "${file}"| sed -e 's/^[^:]*: *//')"

case "$type" in
  MP3*)
    $mp3player -
    ;;
  Ogg*Vorbis*)
    $oggplayer -
    ;;
  RIFF*\ WAVE\ audio*)
    /usr/bin/play --type=wav --silent /dev/stdin
    ;;
  *Extended\ Module\ sound\ data*|*Protracker\ module\ sound\ data*)
    $modplayer $file
    ;;
  data|*audio*)
    if ogginfo "$file" 2>/dev/null | grep --quiet -e '^header_integrity=pass' >/dev/null; then
      $oggplayer -
    elif mp3info -x "$file" 2>/dev/null| grep --quiet -e '^File:' > /dev/null; then
      $mp3player -


    else
      play --type=auto --silent "$file" || play --type="$ext" --silent "$file"
    fi
    ;;
  *) echo "$type" >&2 ;;
esac

Here is the basic overview of what the system does. The beginning of the code parses the arguments that are passed to the print filter from the printer. It then stores them in a couple of variables. It then has some declarations for where you can find your mp3, ogg, and mod player. You should note, this system is also extensible with little difficulty.

After this the format of the file is obtained by running the program file on it. This nifty little tool that most people overlook will examine a file and usually can provide a pretty good guess about what sort of file it is. It's great at identifying files with incorrect extensions where you'd otherwise never be aware of it.

Finally, the options for the type of the file are parsed in a case statement and then the appropriate player is called. In all cases, the input stream is fed over standard input. The applications should be quiet, lpd usually assumes that if there is any output from a filter that something has gone wrong.

You may need to modify this script some. The main reason is that not all version of the file utility return the same strings. Some return "MPEG 2 layer 3 audio" for an MP3 file, while mine returns "MP3, 128 kBits, 44.1 kHz, Stereo" or something similar. Thus, you may need to modify the values for the case statement some to get the system to your liking.

Accessing the Sound Card

Up to this point we haven't done anything that could be considered a big security risk. This point is minor, but you need to give the account for your printer access to the sound card so it can play the music. This is done by giving it right to write the /dev/audio and /dev/dsp. If you're lazy you could just do a chmod a+rw /dev/audio /dev/dsp, but that allows all sorts of people to do things with your sound card. You're better off putting all people with rights to the sound card in a group and then also putting the lp account in the group too. For instance, creating a group called snduser with all the accounts that have access to the card in it, and also the lp account. The doing chgrp snduser /dev/audio /dev/dsp and chmod g+rw /dev/audio /dev/dsp should take care of it for you.

While you're creating files, you'll need to create those two accounting files that I mentioned in the /etc/printcap entry. You can do this by running the following commands:

touch /var/log/audio-acct
touch /var/log/audio-errs
chown lp /var/log/audio-acct
chown lp /var/log/audio-errs

Enjoying The Music

The final step is to enjoy the music. Provided that you've done everything right so far you should be able to execute lpr -Pmp3 [your music file] and shortly afterwards it should start playing for your speakers.

One of the really nice things about this is that you can use lpq to see what songs are on the queue and lprm to remove a song from the queue. Here is an example (yes, I own the albums):

[/u2/mp3]
[patrick@dreams] lpr -Pmp3 Wally\ Pleasant\ -\ Alternateen.mp3
[/u2/mp3]
[patrick@dreams] lpr -Pmp3 Wally\ Pleasant\ -\ Bigger\ Than\ Elvis\ -\ Wally\ World.mp3
[/u2/mp3]
[patrick@dreams] lpr -Pmp3 Wally\ Pleasant\ -\ In\ Love\ with\ a\ Geek.mp3
[/u2/mp3]
[patrick@dreams] lpr -Pmp3 Wally\ Pleasant\ -\ It\'s\ a\ Beautiful\ Day.mp3
[/u2/mp3]
[patrick@dreams] lpq -Pmp3
Printer: mp3@dreams
 Queue: 4 printable jobs
 Server: pid 7043 active
 Unspooler: pid 7044 active
 Status: waiting for subserver to exit at 16:22:55.342
 Rank   Owner/ID                  Class Job Files                 Size Time
active patrick@dreams+42            A    42 Wally Pleasant - A 2727348 16:22:38
2      patrick@dreams+50            A    50 Wally Pleasant - B 2679246 16:22:42
3      patrick@dreams+52            A    52 Wally Pleasant - I 3266864 16:22:49
4      patrick@dreams+54            A    54 Wally Pleasant - I 3469897 16:22:55

It's not working!

Contrary to what you may be thinking, the first step if this is not working is not to e-mail me about your system configuration. I probably won't be much help. The first step is to go into the spooling directory, in this case /var/spool/lpd/audio and see what's lying in there. The file that you'll want to look at is status.pr. This provides the status of your printer. If there was any output from the script, it will be saved in there. Look around in there and use that for a debugging point.

Questions/Follow-up Ideas

If you've got a question about this article and think it's something that should be addressed more, let me know. Also, if you've got an idea for a followup, I'd like to hear those also. I'm always looking for interesting new hacks to try out and experiment with.


IPv6 Applications

Posted to old on 2003-05-22 23:04:00

In yesterday's article I wrote about how to get OpenBSD and IPv6 to play nicely together, so you could get some basic applications running. Today, I'm going to go into some more depth and tell about how to get some applications going.

Finding Hostnames

One of the most basic things that you'll want to do is look up hostnames on the Internet. For IPv4 an address record is an A record, for IPv6 it is an AAAA record. Thus, to get the IPv6 address for a host run the command dig [hostname] AAAA to get the record.

Web Browsing

The first that you'll probably want to get going is web browsing. If for nothing else than allowing you see the wonderful dancing kame. The great thing is that for newer versions of Mozilla, Konqueror, and Galeon you don't need to do anything. By default if a host also has an IPv6 address, it will try to access it over IPv6. The problem comes when you try to enter IPv6 addresses into your address bar, usually they'll get mangled. To fix this, for an address you can put the address in brackets. Thus, you should see that http://www.wagstrom.org/ and http://[2001:470:1f00:572::1]/ will take you to the same location, which is my little IPv6 test web server.

Web Servers

I've read some stuff that Apache apparently has IPv6 support built in natively as of version 2. Unfortunately, the chroot version of it in OpenBSD is still based on version 1.3, so there is no IPv6 support, at least not that I could tell. Because I'm lazy, I didn't want to go and install a whole new version of Apache, after all, my current setup works fine and there is no reason to think people will currently get added benefit from accessing it under IPv6.

Looking for a simple solution I settled on thttpd 2.23. This was pretty straight forward to compile, in fact no additional options were needed to get IPv6 support. Then I wanted to start serving web pages from a special IPv6 directory under my normal html directory. To do this, I added the following commands to /etc/rc.local to start up thttpd:

# thttpd startup
echo -n ' thttpd ipv6 webserver startup'
y=`pwd`
cd /home/patrick/public_html/ipv6
thttpd -p 80 -h 2001:470:1f00:572::1 -r
cd $y

This very simply echoes that it is starting up the web service. Stores the current directory in a variable. Changes into the director where the web pages are being served from, and then starts up an instance of thttpd. The -p 80 tells it to listen on port 80, while the -h 2001:470:1f00:572::1 gives the IP address that the daemon should bind to. A quick restart later (or just running the commands as root) and you should be able to access you brand spanking new IPv6 web server.

SSH

Probably one of the best reasons to use IPv6 is to avoid manual tunneling to get to a machine that resides behind a NAT device. OpenSSH supports IPv6 natively. Once you have IPv6 running, you'll need to give the server a restart (so it will know to start listening on the IPv6) interfaces. Then you can connect to it by referencing an IPv6 only hostname or IP address. If the machine has entries for both IPv4 and IPv6 you can specify the -6 flag to force IPv6. For instance:

$ ssh -6 yourhost.ipv6.yourdomain.com

should connect to your designated host via IPv6. You'll get a good idea based on where the system says you're coming from when you first log in.

IRC

Although most of the unix IRC clients claim to have support for IPv6, the only one I've been able to get to work successfully is BitchX. You'll probably need to recompile it to enable IPv6 as the default compiled package for OpenBSD does not support IPv6. You can do this by setting WITH_IPV6=yes if compiling from ports, or doing ./configure --enable-ipv6 if compiling from source.

After this point you'll probably want to connect to an IPv6 irc server. Two that I've had good luck with are irc.ipv6.homelien.no and irc.efnet.nl. The problem, is that because both of these have IPv4 addresses you'll need to manually give it the IP address of the server to connect to. You then connect by doing the usual server command, but appending a comma to the hostname. Thus /server 2001:840::1000, and /server 2001:7b8:3:3f:201:2ff:fef6:574e, will connect you to irc.ipv6.homelien.no and irc.efnet.nl respectively. Once you have everything set up, you should see something like this when you do a whois:

+----------------------------------------- --  -
| pridkett (patrick@dreams.ipv6.wagstrom.org) (Internic Non-Profit Organization)
| ircname  : patrick wagstrom
| channels : #openbsd
| server   : irc.ipv6.homelien.no (Who Cares -- IPv6!)
| away     : pridkett - is away: (Auto-Away after 10 mins) [BX-MsgLog On]
: idle     : 0 hours 22 mins 5 secs (signon: Thu May 22 16:25:40 2003)

However, you should be prepared to know that DCC will stop working unless that other person is using an IPv6 host. So if you use IRC to talk, this is fine. If you use IRC to download MP3s or warez, continue using IPv4.

DNS

Unfortunately, most DNS service providers do not support the AAAA record type, this includes dyndns.org whom I use to administer wagstrom.net. However, as I had wagstrom.org sitting around and not being used, I figured that I would get that set up. The first thing that you need is a host with a static IPv4 address because nameservers still require IPv4 to work. Then go and update your records to point your domain at your DNS, in my case this is at 66.1.1.250.

The version of BIND that ships with OpenBSD is IPv6 enabled, so once you get it going, you shouldn't have any problems. The first thing you need to do is edit /etc/rc.conf and change this line:

named_flags=""          # for normal use: ""

This tells OpenBSD to start up the name server on the next boot. Now you need to go to /var/named/etc and add your domain to your named.conf as you would an IPv4 domain. In my case I did the following:

zone "wagstrom.org" {
        type master;
        file "master/wagstrom.org";
        allow-transfer {
        };
};

You'll want to change it for whatever your domain is. The next step is to create the domain file. This should reside in /var/named/master/wagstrom.org. Here is what mine looks like:

; File: wagstrom.org
; wagstrom.org network file
; support of IPv6 hostnames
;
@       IN      SOA     ns.wagstrom.org.        root.wagstrom.org.      (
        2003052101      ; serial number YYYYMMDDrr
        3H              ; refresh
        15M             ; retry
        1W              ; expiry
        1D )            ; minimum

        IN      NS      ns.wagstrom.org.
        IN      MX      10 scissors.wagstrom.net.
;
; Local Hosts
;
ns                      IN      AAAA    2001:470:1f00:572::1
                        IN      A       66.1.1.250
scissors.ipv6           IN      AAAA    2001:470:1f00:572::1
scissors.ipv4           IN      A       66.1.1.250
scissors                IN      CNAME   scissors.ipv4
www.ipv6                IN      CNAME   scissors.ipv6

Most of that should be pretty straight forward. I have different host names for my host for IPv4 (scissors.ipv4.wagstrom.org -> 66.1.1.250) and IPv6 (scissors.ipv6.wagstrom.org -> 2001:470:1f00:572::1). In addition, I have ns.wagstrom.org mapping to both an IPv4 and an IPv6 address. It's important that this be in place and running for a while before trying to get reverse DNS to work.

Reverse DNS

One of the really nice features of Tunnelbroker is that it also allows you do your own reverse DNS. Combined with the massive amounts of address space that IPv6 provides, this means a limitless number of virtual hosts with cool names like i.am.a.37337.hax0r.from.wagstrom.org for your use on IRC. Or, more realistically, it makes it nicer for when you SSH to your other IPv6 boxes so you don't have to guess what host it was from by the really long IP address.

To get all of this going you'll want to log in to Tunnelbroker. Then select your /64 allocation. From your /64 allocation there is a spot to put the hostname of your name server. I'm not sure, but I think it needs to resolve in both IPv4 and IPv6 address space. If it doesn't odds are that Tunnelbroker will come back and yell at you. I can't be sure because the docs are pretty sparse for it.

Anyway, so this assumes that Tunnelbroker has accepted your DNS. Now comes the fun part, reverse DNS names for ipv6 are in the ipv6.arpa domain (older versions had them in the ipv6.int domain, you'll probably want to use both for now as ipv6.arpa doesn't work on freenet6 allocations). The easiest way to do this is to use the IPv6 reverse DNS zone builder. This handles the headache of converting your domain. Follow their instructions and you should be good.

Otherwise, you can be a masochist and it by hand. The first thing is to figure out what domains you're going to be doing revese DNS for. You do this by reversing the subnet (don't forget to add your zeroes back in) and putting periods between them and finally smacking on a ip6.arpa at the end. This 2001:470:1f00:572::/64 becomes 2.7.5.0.0.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa. That's a mouthful. Here's the code that I put in my /var/named/etc/named.conf file:

/* 2001:470:1f00:572::/64
 */
zone "2.7.5.0.0.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa" {
        type master;
        file "master/ipv6.arpa";
        allow-transfer {
        };
};

That was fun. Now you get to do it for each of your hosts! Remember, those zeroes that disapper with the :: in the address, well ,they're back. So this is the contents of my /var/named/master/ipv6.arpa file:

$TTL 3d ; Default TTL (bind 8 needs this, bind 9 ignores it)
@       IN SOA 2.7.5.0.0.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa. wagspat.iit.edu. (
                2003052100        ; Serial number YYYYMMDDrr
                24h             ; Refresh time
                30m             ; Retry time
                2d              ; Expire time
                3d              ; Default TTL (bind 8 ignores this, bind 9 needs it)
)

; Name server entries
                                        IN     NS     scissors.wagstrom.org
; IPv6 PTR entries

; Subnet #1
$ORIGIN 2.7.5.0.0.0.f.1.0.7.4.0.1.0.0.2.ip6.arpa.

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0         IN      PTR     scissors.ipv6.wagstrom.org.

If all goes well, in another few hours you should be able to log into IRC over IPv6 from your host and you'll see your brand new IPv6 domain name coming up as the reverse DNS.


OpenBSD and IPv6 Mini How-To

Posted to old on 2003-05-22 01:01:00

After some mucking around, I've gotten IPv6 and OpenBSD to play nicely together. Furthermore, I've got my OpenBSD box acting as a router for my other computers behind it, as such they all have globally addressable ipv6 addresses now too. I got a lot of help from Carl Brewer's page on making a 6bone router using OpenBSD, but needed to do some small modifications to account for the changes between OpenBSD 2.8 and OpenBSD 3.3.

Here is the basic overview of what I needed to for this to happen. Step 1 is to set up an IPv6 tunnel. There are a variety of services that can do this for you, I'm using TunnelBroker from Hurricane Electric (good people, they've been long time supporters of PHP).

When you register on TunnelBroker, they'll need information about your IPv4 endpoint. Fortunately, I have a static IP address. I'm not real sure how well this would work if I didn't. So let's just hope that you have a static IP address (I may have to work around that when I move in a few months). After registering your endpoint, it will take up to 24 hours for the tunnel to be set up (this is in contrast to places like freenet6 where you can get instant set ups, but my pings here seem to be lower, and you get more options here).

After your tunnel is initialized, log back into TunnelBroker and look at the example configuration. Select OpenBSD from the list. This should give a configuration something like this:

ifconfig gif0 giftunnel 66.1.1.250 64.71.128.82 
ifconfig gif0 inet6 alias 2001:470:1F00:FFFF::3B1 2001:470:1F00:FFFF::3B0 prefixlen 128
route -n add -inet6 default 2001:470:1F00:FFFF::3B0 

You can feel free to run those commands right away. Also make sure you paste those at the end of your /etc/rc.local configuration file. You'll also want to make sure that you've got a line to start rout6d in there too. I have this hunk of code in mine:

# IPv6 Information
echo -n ' setting up IPv6 to he.net'
ifconfig gif0 giftunnel 66.1.1.250 64.71.128.82
ifconfig gif0 inet6 alias 2001:470:1F00:FFFF::3B1 2001:470:1F00:FFFF::3B0 prefixlen 128
route -n add -inet6 default 2001:470:1F00:FFFF::3B0
route6d

At this point you can try a ping6 to the other endpoint, which is the second set of numbers up there.

ping6 2001:470:1F00:FFFF::3B0

If your ping6 went through, you're in really good shape to get your own /64 subnet. This is a MAMMOTH amount of address space, but hey, it's IPv6. Go to the page on TunnelBroker and select /64 Allocation. Then just click submit, you can leave the fields blank for now until you set up ipv6 dns (which will be covered in another writeup).

The page will reload and it will contain text similar to this:

Assigned Prefix: 2001:470:1F00:572::/64

This is your /64 address space allocation from Hurricane Electric. Requests for nodes on that subnet (which has a number of nodes equal to the square of the TOTAL number of IPv4 nodes) will be routed to your OpenBSD box. The next step is to set up an ethernet interface to have an IPv6 address. In this case I chose to give device ne1, which is my internal network interface, an IPv6 address. This is what my /etc/hostname.ne1 now looks like:

inet 192.168.1.1 255.255.255.0 NONE
inet6 alias 2001:470:1F00:572::1 64

The first line is the normal IPv4 address that I use for routing everything and talking to all my nodes that are natted. The second line sets up an alias for IPv6. While IPv6 does have this really cool concept of stateless autoconfiguration, we're not going to use it here because this will be a router. So I've chosen to give this interface the first address in my IPv6 address space. The 64 indicates how many bits in my subnet, in this case, 64. A reboot or a quick running of /etc/netstart ne1 will bring the device up. If you run a ifconfig ne1 you should see something like this:

ne1: flags=8863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        address: 00:80:ad:1b:cd:b7
        media: Ethernet manual
        inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
        inet6 fe80::280:adff:fe1b:cdb7%ne1 prefixlen 64 scopeid 0x1
        inet6 2001:470:1f00:572::1 prefixlen 64

If you see the last line with your address, you should be good to go. The second to the last line is the link identifier, but we're not going to worry about that right now. Unfortunately, we're not quite ready to test our connection yet. We need to set up the system so it does routing of IPv6 packets. To do this you need to set the following lines in /etc/sysctl.conf:

net.inet6.ip6.forwarding=1      # 1=Permit forwarding (routing) of packets
net.inet6.ip6.accept_rtadv=0    # 1=Permit IPv6 autoconf (forwarding must be 0)

These two options are mutually exclusive. You can't do auto configuration and also do routing, which makes sense, routers are supposed to have static addresses.

Now we get to muck around in /etc/rc.conf and set some more options. Here are the ones that are important:

rtadvd_flags=ne1        # for normal use: list of interfaces
                        # be sure to set net.inet6.ip6.forwarding=1
route6d_flags=""        # for normal use: ""
                        # be sure to set net.inet6.ip6.forwarding=1
rtsold_flags=NO         # for normal use: interface
                        # be sure to set net.inet6.ip6.forwarding=0
                        # be sure to set net.inet6.ip6.accept_rtadv=1

These options should make the route advertisement daemon start at boot time. The last step you should have to do is to configure rtadvd. You can do this by editing /etc/rtadvd.conf and inserting text similar to this:

ne1:\
        :addrs#1:addr="2001:470:1F00:572::":prefixlen#64:tc=ether:

Where you'll want to change ne1 to the proper device that you gave an ip to earlier and add to whatever your /64 allocation from TunnelBroker is.

Now, all you need to do is reboot and you should be good to go (you could start up everything manually, but rebooting is just as easy). Now go back to TunnelBroker and select connectivity and try to ping the IP address you just created. If all goes well, it should work.

If for some reason it doesn't work, you might have very tight rules for pf. Placing these rules in should help out some (see yesterday's article for more on building a proper firewall):

pass in quick proto 41 from any to any
pass out quick proto 41 from any to any

Now comes the true test. I've got a linux box (running a heavily modified version of RedHat 7.3) behind my OpenBSD router. If you have an IPv6 module ready for your kernel you should be able to run modprobe ipv6 and then your devices connected to your OpenBSD router will immediately get IP addresses. Here's what the output of ifconfig eth0 looks like for me:

eth0      Link encap:Ethernet  HWaddr 00:01:02:39:A5:67
          inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 2001:470:1f00:572:201:2ff:fe39:a567/64 Scope:Global
          inet6 addr: fe80::201:2ff:fe39:a567/10 Scope:Link
          UP BROADCAST NOTRAILERS RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9259 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14256 errors:0 dropped:0 overruns:0 carrier:0
          collisions:21 txqueuelen:100
          RX bytes:2440576 (2.3 Mb)  TX bytes:2228114 (2.1 Mb)
          Interrupt:10 Base address:0xe800

The second inet6 line should be an IPv6 address. If everything went as planned you should be able to go back to TunnelBroker and do a ping6 to that address and it should work. Furthermore, browsing the web will now use IPv6 if possible. This will get you the coveted dancing kame.

Later on I'll post a more in depth article on getting applications running under OpenBSD and Linux with IPv6.

Update: I've completed my overview of IPv6 applications.