`npm run build` now builds both the site.json file and the React app. Two new run scripts are available: * build_site - just build the site.json file * build_code - build the React app
1 line
No EOL
93 KiB
JSON
1 line
No EOL
93 KiB
JSON
{"pages":[{"title":"About me","url":"/about/","slug":"about","parent":null,"body":"This about page was incredibly out-of-date, so I removed it. If you want to know who I am or what I'm up to, check out these links:\n\n* [Twitter](https://twitter.com/nickpegg)\n* [GitHub](https://github.com/nickpegg)"},{"title":"CPU Usage Meter","url":"/projects/cpu-usage-meter/","parent":"Projects","body":"Back in the day, there was a little obscure operating system called BeOS. The\ncompany which made the OS was brave enough to put it on their own hardware, too.\nThis was dubbed the [BeBox](https://en.wikipedia.org/wiki/Bebox). Among all the\nneat doohickies on the computer were two CPU load meters (one for each processor).\nNow, how cool would it be to have a computer with those?\n\n__Very.__\n\n### Download\nNote: Linux code makes use of libserial and libstatgrab. Both must be installed for\nprogram to work/compile. The UM245R device uses the ftdi_sio driver. It's in the\n2.6 kernel tree, so it should (hopefully) be detected when you plug the device in.\n\nUSB controller program:\n\n* [Linux code and executable](/media/projects/cpu_meter.tar.gz)\n* Windows code removed due to buginess\n\n### Updates\n\n#### Status Update - Nov 27 2007\n\nWow, it's been almost a year since I've put work on this. I decided to finally write\ncode to make it work under Linux. I ended up throwing out the notion of trying to\nuse libusb. After 4 hours of research and code hacking, it worked!\n\n#### Status Update - Dec 08 2006\n\nThe hardware works and the software works (kinda). Once I get around to cleaning up\nsome of the code and adding some documentation, I'll start uploading stuff. Stay tuned!\n\n#### Status Update - Dec 02 2006\n\nGot the hardware working on a breadboard. Using DLP's test program, various patterns\nwere able to be sent. Video coming soon!\n\n### Statistics:\n* Cost: $27.69\n* Lines of code (Linux): 83\n* Lines of code (Windows): 1503\n* Sleep lost: Unknown\n\n### Hardware Design\nThe hardware is pretty simple. Using an UM245R, most of the work is done for you. The\n[UM245R](https://www.ftdichip.com/Products/EvaluationKits/UM245R.htm) takes in USB data\nand outputs it on the 8 data pins, and those 8 pins directly drive the LEDs. It's not\nquite as simple as that, since there's all sorts of protocol with Ready-to-Read and\nReady-to-Write and Read and Write pins that go high and low. I just cheated and used\nat 555 timer to generate a clock signal on the RD pin to give me the data. I just\nlucked out and the UM245R outputs the last data if there's no new data available.\n\n[Circuit Design](/media/img/cpu_meter/circuit.png)\n\n[Testing the circuit](/media/img/cpu_meter/testing.jpg)\n\n### Software\nAs with any hardware, there needs to be software which controls it. For the Windows\ncode, I decided to use [LibUSB](https://libusb.sf.net/) to help me with this project. Programming with LibUSB\nis fairly straightforward, which helps since the documentation is rather spotty. Along\nwith LibUSB, I also took the Queue class from [nicklib](/projects/) and wrote a UsbDevice class to\nhelp handle failures better. This stuff can be found in the source package above.\n\nAfter wrangling with libusb on the Windows side of things, I decided to throw out\nthat idea on the Linux client. It turns out that FTDI makes a driver for the UM245R\ncalled ftdi_sio which creates a virtual serial interface. I used this along with\nlibserial and libstatgrab to get it working.\n\nThe Linux code is rather simple and only does CPU usage. I'm planning on extending\nit to do things such as music visualization. This of course means writing some sort\nof user interface and probably using threads.\n\n### Pictures\nSome pictures of the final product:\n\n \n\n \n\n"},{"title":"Kegerator","url":"/projects/kegerator/","parent":"Projects","body":"I've been homebrewing for a couple of years now, and my least favorite part of\nthe whole process is definitely the bottling. Each 5 gallon batch has\napproximately 55 bottles that you have to clean, santize, fill, cap, clean\nagain, and put in boxes. I've gotten sick and tired of doing that for every\nbatch of beer, so I decided to make the jump and build myself a kegerator.\n\n![Kegerator mostly finished][0]\n\nBuilding a kegerator is fairly simple, only requiring some plumbing and\nwoodworking. The only hard part is the cost. Below is the cost for a\nthree-keg setup similar to my current two-keg setup.\n\n### Updates\n\n#### Feb 20, 2011\nGot the kegerator built yesterday minus a temperature controller. I got a\nlittle drill-happy and accidentally made three faucet holes instead of two.\nOops, I guess I'll have to put in that third faucet.\n\n### Links\n* [Flickr set](https://www.flickr.com/photos/nickpegg/sets/72157625971333921/)\n\n### Bill of Materials\n\n<table border=\"1\">\n\t<tr>\n\t\t<th>Qty</th>\n\t\t<th>Cost Each</th>\n\t\t<th>Item</th>\n\t</tr>\n\t<tr>\n\t\t<td>1</th>\n\t\t<td>$198</td>\n\t\t<td>GE 7.0 cubic ft freezer</td>\n\t</tr>\n\t<tr>\n\t\t<td>1</td>\n\t\t<td>$90</td>\n\t\t<td>5 pound CO2 tank</td>\n\t</tr>\n\t<tr>\n\t\t<td>1</td>\n\t\t<td>$75</td>\n\t\t<td>Dual gauge CO2 regulator</td>\n\t</tr>\n\t<tr>\n\t\t<td>1</td>\n\t\t<td>$47</td>\n\t\t<td>3-way CO2 distributor</td>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$40</td>\n\t\t<td>Used 5 gallon soda keg</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$6.50</td>\n\t\t<td>Ball lock gas disconnect - MFL</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$6.50</td>\n\t\t<td>Ball lock liquid disconnect - MFL</td>\n\t</tr>\n\t<tr>\n\t\t<td>7</td>\n\t\t<td>$1.30</td>\n\t\t<td>1/4\" barb-to-MFL connector</td>\n\t</tr>\n\t<tr>\n\t\t<td>7</td>\n\t\t<td>$0.25</td>\n\t\t<td>Flared nylon washers for MFL connections</td>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$20</td>\n\t\t<td>Stainless steel faucet shank</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$2.25</td>\n\t\t<td>1/4\" barbed shank tail piece and hex nut</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$0.10</td>\n\t\t<td>Rubber shank washer</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$31.50</td>\n\t\t<td>Perlick beer faucet</td>\n\t</tr>\n\t<tr>\n\t\t<td>3</td>\n\t\t<td>$2</td>\n\t\t<td>Economy tap handle</td>\n\t</tr>\n\t<tr>\n\t\t<td>1</td>\n\t\t<td>$6.42</td>\n\t\t<td>12' 2x8</td>\n\t</tr>\n\t<tr>\n\t\t<td>1</td>\n\t\t<td>$3.37</td>\n\t\t<td>Roll of weather stripping</td>\n\t</tr>\n\t<tr>\n\t\t<td>2</td>\n\t\t<td>$5.65</td>\n\t\t<td>25' roll of poly ice maker tubing</td>\n\t</tr>\n\t<tr>\n\t\t<td>14</td>\n\t\t<td>$0.65</td>\n\t\t<td>1/4\" to 1/2\" hose clamp</td>\n\t</tr>\n\t<tr>\n\t\t<th align=\"left\">Total</th>\n\t\t<th align=\"left\">$758.09</th>\n\t\t<td></td>\n\t</tr>\n</table>\n\n### Construction\n\nBy far the most popular way to build a kegerator outside of complete\nfabrication is to take an existing chest freezer and add a collar between the\nfreezer and the original lid. This is what I did as seen below.\n\n![Hinges][1]\n\nAn added bonus to the collar method is that you now have a wooden platform to\nadd your faucets and other items without harming the original freezer, in case\nyou decide to sell it later or actually use it for storing food. When building\nthe collar, you'll want to use something like a 2x8 to have enough clearance\nfor the old hinges to attach to the wood.\n\nTo help keep the cold air in the kegerator, it's a good idea to seal the\ncollar. I just put some weather stripping down where the collar rests on the\nfreezer and filled the collar joints with some extra oil pan sealant I had\nlaying around. The weather stripping is nice because if you're not quite a\nmaster woodworker and can't be bothered to get the collar exactly square, it\nhelps fill in your gaps.\n\nOnce the collar's on and the faucets are installed, it's just a matter of\nconnecting everything. Don't forget to use your washers to get a good seal! You\ncan hand-tighten the MFL connections, but it might be a better idea to tighten\nthem with a pair of pliers.\n\n### Pressure Testing\n\nOnce everything's together, you'll want to pressure test the entire dispensing\nsystem. What I did was fill the kegs with water and pressurize the whole system,\nand do some test pours. If you have any leaks, you'll either hear air hissing\nor see water leaking out.\n\n![Pressure testing][2]\n\nIn the case that it is an air leak and you're not\nsure where it's coming from, disconnect things one by one until the\nhissing stops. The part that you last disconnected is the faulty one, so make\nsure that everything's tight on there, especially if it's a hose clamp on a\nbarbed connection.\n\n[0]: https://farm6.static.flickr.com/5135/5462665976_d11faea2aa.jpg \"Mostly finished\"\n[1]: https://farm6.static.flickr.com/5132/5462060669_436dbe852f.jpg\n[2]: https://farm6.static.flickr.com/5053/5462065415_efefbb9675.jpg \"Pressure testing\""},{"title":"LIRC IR Receiver","slug":"ir-receiver","url":"/projects/ir-receiver/","parent":"Projects","body":"Since my computer was used as a media hub for my two roommates and I my Sophmore\nyear at UMR, I figured being able to use my A/V receiver's remote control to\ncontrol the computer would be nice. After doing some quick research, (Win)LIRC\nseemed to be the best solution. Many people either buy a pre-made receiver, or\nbuild their own receiver that fits on the end of a serial cable.\n\n### Parts List\n\n* [A suitable IR receiver module](http://lirc.org/receivers.html) (Vishay 1738 is popular)\n* 1N4148 diode\n* 4.7 uF capacitor\n* 4.7 kOhm resistor\n* 7805 5V voltage regulator\n\n### Construction\n\nConstruction is fairly easy. I personally used a Vishay TSOP2238 IR receiver\nmodule and a [instructions](http://lnx.manoweb.com/lirc/) found freely on the web. Below is the circuit diagram\nthat I used. In the schematic, the - pin (GND) on the IR receiver goes to the serial\nGND, the +/Vs pin receives the +5V from the voltage regulator, and the Data pin is\nconnected to the DCD on the serial port. Beware that many IR receivers have different\npinouts! More details on what does what can be found at the [LIRC guide](http://lirc.org/receivers.html). Once the\nreceiver is complete, the easiest way to position it is to connect it to a serial\nextension cable and mount it somewhere.\nSchematic:\n\n### Usage\n\nSince I primarily used Windows for day-to-day tasks back then, I used [WinLIRC](http://winlirc.sf.net/) to\nhandle the receiver. It's configuration files are identical to LIRC. Pre-made\nconfiguration files are available for a [wide range of remotes](http://lirc.org/receivers.html), but your remote can be\nprogrammed manually if it needs to be.\n\nMy two main media players were [Winamp](http://winamp.com/) and [Media Player Classic](http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=84358), which both have some\nsort of support for LIRC. Media Player Classic has it built-in (configuration in the\nKeys options), but Winamp requires a plugin. Luckily, there is one available on the\n[WinLIRC website](http://winlirc.sf.net/).\n\n### Links\n\n* [LIRC](http://lirc.org/)\n* [WinLIRC - A Windows port of LIRC](http://winlirc.sf.net/)\n* [List of known working IR modules](http://lirc.org/receivers.html)\n* [Nice construction instructions](http://lnx.manoweb.com/lirc/)"},{"title":"Projects","url":"/projects/","parent":null,"body":"Here's a decent number of the projects I've worked on in the past.\n**This is mostly ancient and you should probably check out my [GitHub](https://github.com/nickpegg) profile instead**\n\n### Posty (2010)\nLinks: [GitHub](https://github.com/nickpegg/posty)\n\nJust a little static page generator I wrote when I got sick of using\nWordpress. It's quick, it's dirty, but it does what I need it to.\n\nI guess I'm just never satisfied with using pre-made software packages\nto run my personal website.\n\n### Beertraq (2009)\nLinks: [Website](https://beertraq.com/)\n\nA website to keep track of which beers you've tried, compare with others,\nread their reviews, and discover new beer. Started in the summer of 2009,\ninspired by The Flying Saucer's UFO Club.\n\n### Intelligent Drink Dispenser (2009)\n(No code available, sorry)\n\nThis is my Computer Engineering Senior Design project at the University of\nMissouri-Rolla. It's basically a robotic bartender which keeps track of\ncustomers (via RFID) and their purchases. This was an idea that Richard Allen\nand I have been kicking around for a few years, but it's finally come to life.\n\n### Nick Tracker (Python, Java) (2008)\n(No code available, sorry)\n\nKeeps track of where my phone's at, which is usually where I am. Server side\nscript written in Python, client written in Java for the Android phone platform.\nSince I've written this, two better applications have hit the Android Market,\nincluding Google Latitude. I've stopped work on this because I don't feel like\nre-inventing the wheel.\n\n### CPU Usage Meter (2006)\nLinks: [Project page](/cpu-usage-meter/), [Linux source](/media/projects/cpu_meter.tar.gz)\n\nLEDs on the front of my computer case displaying the CPU load.\n\n### Serial IR Receiver (2006)\nLinks: [Project page](/ir-receiver/)\n\nA simple serial-based LIRC-compatible IR reciever.\n\n### ServCheck (PHP)\nLinks: [servCheck.tar.gz](/media/projects/servCheck.tar.gz)\n\nA simple service checker written in PHP. Attempts to open a socket with the\nconfigured hosts and ports, and outputs an HTML file showing which services\nare up and down. I originally wrote this for the TerminalUnix site to show what's\nworking and what isn't.\n\n### TerminalUnix (PHP)\nA PHP and MySQL driven site, functioning as a web front-end and community site for\nthe TerminalUnix server. I started it because I was sick of all of these Content\nManagement Systems having features that I didn't want. I sat down during Spring Break\nof 2006 and coded a PHP login system, not knowing about the wonders of some of the PHP\nfeatures. Eventually I coded nice things in such as MySQL access (instead of a flat\ntext file), a user adminstration system, and even a news sytem.\n\nUnfortunately I don't plan on releasing the source code since it's a big hard-coded mess.\n\n### N-Queens solver (C++)\nLinks: [nqueens.tar.gz](/media/projects/nqueens.tar.gz)\n\nAnother Data Structures homework assignment. This solves (brute-forces) the\n[N-Queens Problem](https://www.google.com/search?q=n-queens+problem) using recursion and backtracking."}],"posts":[{"date":"2017-09-05T00:00:00.000Z","tags":["linux","git"],"title":"Visualizing Web Design Evolution Using Git","blurb":"\nMy website here, as of the time of writing this, is still based on a design I made back in 2010, and is rendered using my [static site generator](http://github.com/nickpegg/posty) that I haven't touched in nearly as long. The site's served its purpose pretty well, but it's kind of a mess; It's unreadable on mobile devices, the CSS causes some weird inconsistencies, and the static site generator is no where near my current standards. So since this is a personal project I have the liberty of throwing it all in the trash and starting over (and learning new things along the way!).\n","body":"\nMy website here, as of the time of writing this, is still based on a design I made back in 2010, and is rendered using my [static site generator](http://github.com/nickpegg/posty) that I haven't touched in nearly as long. The site's served its purpose pretty well, but it's kind of a mess; It's unreadable on mobile devices, the CSS causes some weird inconsistencies, and the static site generator is no where near my current standards. So since this is a personal project I have the liberty of throwing it all in the trash and starting over (and learning new things along the way!).\n\nSince my weakest area is front-end (design, Javascript, CSS that doesn't look like it was written by a crazy person, etc.), I decided to jump in there, doing a couple of experiments. I ended up spending the better part of a weekend fiddling with HTML, playing with a couple of CSS frameworks to see what I liked, and incessantly bugging my friend [Brian](https://bokstuff.com) for help. Eventually I got something that I thought looked pretty good and got the 'final' version checked into git.\n\nSo you want to know the cool part about git? If you use it right, you have a bunch of commits containing the full history of what you're building! And with a bit of magic you can come up with something like this:\n\n[](/media/img/design_vis/progress.gif)\n\n(click on image to see the full size version)\n\nNeat, huh? So how the heck did I manage to pull this off? With some shell scripting wizardry!\n\nSince all of my design is in a single HTML file, `index.html`, it's easy to comb through the history with the `git log` command. And to get the commit hashes to iterate over them, just add in some `grep`, `awk`, and `tac` to reverse-sort them (from oldest to newest).\n\n```\ngit log -- index.html | grep commit | grep -v initial | awk '{print $2}' | tac\n```\n\nOkay, cool, so now we can flip through the history of our `index.html`, now how do we make an animated GIF of it? Well, an animation is just a set of images, so we need to figure out how to turn our HTML into an image a bunch of times. This is where [wkhtmltopdf](https://wkhtmltopdf.org/) comes in handy! The name's kind of a mouthful, but it's a tool that uses WebKit to render HTML and output that to a PDF (or an image). It's super simple to use! Just give it a URL or file name, and then a file to output to, and it does the rest.\n\n```\nwkhtmltoimage --width 1920 --height 1080 index.html index${NUM}.png\n```\n\nAlright, now we've got a bunch of images, how do we string those together into a GIF? For things like this, I always turn to ImageMagick's `convert` tool, which is the swiss-army-knife of image manipulation. It turns out that if you pass it a bunch of still images and a filename that ends in `.gif`, it just knows to make a GIF! Incredible! Since we want it to slowly go through the changes so you can play spot-the-difference, we add in a `-delay 100` to the command to tell it to wait 100 tens of milliseconds between each frame.\n\n```\nconvert -delay 100 index*.png progress.gif\n```\n\nAdd in some hackery to remove duplicates (because the rendered page may not change if you change the HTML) and to add a pause of the last frame, and this is what I came up with:\n\n```\n#!/bin/bash\n\n# requires that imagemagick and wkhtmltopdf are installed\n\nmkdir -p progress\ngit checkout master\n\nmkhtmltoimage --crop-w 1920 --crop-h 1080 https://nickpegg.com progress/0000.png\n\ncount=0\ncommits=$(git log | grep commit | grep -v initial | awk '{print $2}' | tac)\n\nfor commit in $(echo $commits | xargs); do\n git checkout \"$commit\"\n i=$((++count))\n wkhtmltoimage --crop-w 1920 --crop-h 1080 index.html \"progress/$(printf \"%04d\" \"$count\").png\"\ndone\n\n# Magical one-liner to remove duplicates\nmd5sum progress/* | \\\n sort | \\\n awk 'BEGIN{lasthash = \"\"} $1 == lasthash {print $2} {lasthash = $1}' | \\\n xargs rm\n\n# Add an artificial pause by copying the last file a few times\nfor i in $(seq $((count+1)) $((count+5))); do\n cp progress/$(printf \"%04d\" \"$count\").png progress/$(printf \"%04d\" \"$i\").png\ndone\n\nconvert -delay 100 progress/*png progress.gif\ngit checkout master\n```\n"},{"date":"2017-06-25T00:00:00.000Z","tags":["bike","touring"],"title":"North Bay Area Bike Tour Log","blurb":"In April of this year, I attempted to bike the [Katy Trail](https://mostateparks.com/park/katy-trail-state-park), but I forgot how unpredictable weather could be in Missouri that time of year and got rained out. While visiting with my parents waiting for my flight back to California, I decided to do a short bike tour in the San Francisco Bay Area where at the very least I wouldn't have to deal with rain.\n","body":"In April of this year, I attempted to bike the [Katy Trail](https://mostateparks.com/park/katy-trail-state-park), but I forgot how unpredictable weather could be in Missouri that time of year and got rained out. While visiting with my parents waiting for my flight back to California, I decided to do a short bike tour in the San Francisco Bay Area where at the very least I wouldn't have to deal with rain.\n\nSet out on this trip on July 21 and returned to my home in Berkeley on July 24. This is the log I kept while on the road, transcribed with minimal editing from the notebook I kept with me.\n\nIn addition to my notes, I also took a bunch of pictures which you can find on [Flickr][9].\n\n# The Plan\n* Day 1 ([Google maps][2])\n * Start in Berkeley, ride to Oakland\n * Take the ferry from Oakland to SF\n * Ride up to Samuel P Taylor State Park and camp\n* Day 2 ([Google maps][3])\n * Ride over to CA Highway 1 (the Pacific Coast Highway)\n * Follow Highway 1 to Bodega Dunes State Park and camp\n* Day 3 ([Google maps][4])\n * Ride east to Santa Rosa, get lunch\n * Make the climb over the mountains to Calistoga\n * Camp at Bothe-Napa State Park\n* Day 4 ([Google maps][5])\n * Ride south to Napa, get lunch there\n * Ride all the way back home\n\n# Day 1\nThis is abridged since I'm writing this after the fact\n\nRolled out @ 08:00, hit up Suzette Crepe Cafe and then Safeway for food. Got some tortillas, bananas, and Nutella. That combo makes for a killer snack!\n\nCaught the 10:15 ferry from Oakland to SF. More crowded than expected, probably because it's summer and kids are out of school. Was on the Gemini which was a fast ride (faster that weekends).\n\nSF was uneventful, normal tourists on their way to the bridge. The west path was closed, so it was more of a shitshow than usual getting across (with not only biking tourists, but pedestrians too). Plus it was foggy and freezing. It felt like a 20 degrees warmer after the bridge. The east path meant I came down Alexander Drive which saved the climb up the hill before Sausilito.\n\nGot lunch at Sausilito Gourmet Deli. Had a _really_ nice backyard seating area. Ended up [taking El Camino Alto][6] up as a challenge, wasn't too bad and dumped me right into Corte Madera.\n\nTook (bicycle) Route 20 along the creek to Fairfax, was really nice.\n\nStopped on a park bench at Fairfax to rest in the mid-afternoon.\n\nFucking hot.\n\nAnd that fucking climb out of Fairfax! Holy crap!! It was tough in the heat. While I was stopped just before the crest, a mountain biker stopped to make sure I was good. Really lifted my spirits. He mentioned a shady way parallel to Sir Francis Drake Blvd. I should have followed his advice!\n\nGot to Sam P. Taylor alright after that.\n\nAt camp, I met:\n\n* __Quinn__ - He hitched a ride via Craiglist from North Carolina to Portland, bought a bike and was riding down the Pacific Coast Highway to SF\n* __Don__ - Last lived in St. Louis (Richmond Heights) but used to live in the Bay Area. 70 years old! Chill dude, was drinking Old English when I showed up. Used to work in the fish business.\n* __French guy__ - was with his two sons, from Mill Valley, works as a software engineer for Salesforce.\n\n# Day 2\nDeparted Sam P Taylor, got the anxious feeling of venturing somehwere new (since I had been to Sam P Taylor before and knew my way there). Took the bike path to the end, then a serious climb up Sir Francis Drake with _zero_ shoulder and a 55 mph speed limit. Yikes! The descent into Olema was gorgeous though!\n\nHighway 1 was smooth going, shady, and cool. Nice change. Scenery of Tomales Bay was nice, got breakfast at Bovine Bakery in Pt. Reyes Station. Giant scone!\n\nBiking right along the coast was really nice. Found a place on the side of the road that was shady. Took a quick rest there, almost fell asleep!\n\nGot to Tomales, got some early lunch (lamb sandwich with feta, onions, pepperocini, and horseradish sauce, yum!). As usual, had a giant climb after the town. Bunch of ups and downs that I'll probably have to re-visit tomorrow.\n\nHeadwind from Tomales. :( I'd rather have a headwind than that oppressive heat! No shoulder on Highway 1 in many places, even on tough climbs.\n\nGentle coast down toward the coast, which gave me a second wind! Grass got greener, could smell the ocean breeze, it was lovely.\n\nDecent climbs into Bodega Bay, again no shoulder, but at least the speed limit was 25 mph.\n\nThe guys I met at Sam P Taylor warned me about the sand at Bodega Dunes State Park, they weren't kidding. Nice big hiker/biker site. Lots of people wrote stuff on the food locker there, mostly names, dates, and their route (and some words of wisdom, like \"count the smiles, not the miles\"). Got dinner at Spud Point Crab Co. Crab roll and clam chowder. Good stuff.\n\nBeach was a short ride away. Nice but kinda hot. Water was feezing as expected. Chilled there for about an hour before coming back to camp.\n\nNo other cyclists. At least I still have Caliban's War to finish reading.\n\nLate, like 8 pm or so a couple showed up who were from Quebec City. They were going from Portland to SF, doing about 70 miles a day! They're getting married in the fall. That's about the extent of the conversation I was able to get out of them, they just hung out in their tent as soon as they got that set up.\n\n# Day 3\nWriting this at Bothe-Napa State Park. Hot but fun day. About 2500 feet of climbing, but nothing demoralizing. Maybe it gets easier past day 2!\n\nWoke up to it raining on my tent! It was misting and droplets were falling from the trees. Cold morning, but after about a mile had to take my jacket off.\n\nTook Highway 1 (back the way I came) to Bodega Highway. While on Bodega Highway a truck passed me kicking up all kinds of crud and I got something stuck in my eye. Had to stop and flush it out with water, I'm sure I looked like a goofball. Tip: wear sunglasses, even when it's foggy.\n\nGot second breakfast at a bakery (Wild Flour Bread) in Freehold. Popular place. Met some poeple on a supported bike tour coming from Tahoe.\n\nAs usual, had a big climb out of the town I stopped in. Nothing stressful though, despite the 6-8% grade according to the map. Took windy back roads after the climb. Much less traffic and amazing views. Lots of vineyards and giant homes up there.\n\nRode down into Sebastopol and jumped on the Joe Rodota Trail into Santa Rosa. That was super-chill, but turned into a hobo highway in Santa Rosa city limits.\n\nAte at Franchettis' which Jason Wilson from Dropbox recommended. Was great, but I was out of place as the smelly cyclist, hah!\n\nWent north out of town and took the Mark West Springs, Porter Creek, Petrified Forest route. I didn't pay to see the petrified forest but made a water stop.\n\nHonestly, the climbing wasn't all that bad. The descent was _crazy_ though. Gorgeous and fast. I should have turned Strava on, I must have exceeded my record speed and hit 40 mph. On a touring bike no less! I had a stupid grin on my face the entire way down.\n\nOnce in Calistoga, I went to go see Old Faithful. Not _that_ Old Faithful, just the California knock-off. Still neat, but I wouldn't go again.\n\nGot a carnitas super burrito and a six pack of 21st Amendment's Hell or High Watermelon from a taqueria/bodega combo. Dug into that right before writing this. Life is good.\n\n# Day 4\nI slept like a baby. Either I'm getting used to camping, or it was the beer.\n\nAccording to Google Maps:\n\n * 65 miles\n * 1100 feet climbing\n * 1500 feet descending\n\n__OH YEAH__\n\nThe elevation profile shows a nice gentle descent through the Napa Valley. Gonna be a fun day albiet maybe long.\n\nCamp breakfast was oatmeal with peanut butter mixed in. How did I not think of this earlier?\n\nJumped north to catch Silverado Trail Road. It's a cyclist's paradise: little traffic, rolling hills, shade, decent \"bike lane\" (shoulder).\n\nGot a pastry and cup of coffee at Napa Valley Coffee Roasting Company in St. Helena. Damn good coffee.\n\nDecent headwind, but still downhill. Awesome view of vineyeards. So many cyclists that I'm getting tired of waving at all of them.\n\nGot into Napa at 11:00 on the dot. Nice and cool compared to Marin County! Hung out for a bit and got a couple of slices at Velo Pizzeria, which has the most legit NY style I've had in California.\n\nRiding south of Napa is all along California Highway 29, with some side roads. The shoulder is nice and wide, but it's still stressful having cars fly by at 55 mph.\n\nAmerican Canyon feels like American Dream-land. Reminds me of pictures of neighborhoods from the 1950s.\n\nVallejo has some decent riding on trails or bike lanes near Napa River. But then it's back on CA-29. Took some side roads before the bridge, but with some annoying hills.\n\nThe Carquinez Bridge Trail is a nice, chill ride. San Pablo Ave up from Crockett is the opposite, but no traffic.\n\nThis part of the Bay Area is so weird, vastly different towns right next to each other.\n\n* Crockett - feels like a small fishing village\n* Rodeo - feels like a dead midwestern town. Seemed like 50% of downtown was empty storefronts.\n* Hercules - affluent, new, shiny. Good biking\n* Pinole - suburban, standard\n\nStarts getting sketchier the closer you get to Richmond.\n\nStarting to get angry at hills.\n\nGoogle Maps is an asshole. Why does it think that [Sarah Drive in Pinole][7] is an acceptible bike route? It's like a 10+% grande. Should have followed the Krebs map through Richmond.\n\nSan Pablo Dam Road sucks. Horrible, narrow shoulder, I think they consider it a bike lane. I almost flipped catching a wheel in a grate.\n\nStupid hills.\n\nI could hear the BART trains as I approached the Ohlone Greenway. Oddly soothing after travelling 200 miles. Once I hit the greenway, I played [some punk][8] from my phone and pounded out the last few miles home.\n\n[1]: https://mostateparks.com/park/katy-trail-state-park\n[2]: https://goo.gl/maps/yNz9rwYTapm\n[3]: https://goo.gl/maps/CvzrM19eSns\n[4]: https://goo.gl/maps/AxF8DUd7yMQ2\n[5]: https://goo.gl/maps/EP2WcASHwos\n[6]: https://www.strava.com/activities/1047975978\n[7]: https://goo.gl/maps/dweuGANk6D72\n[8]: https://www.youtube.com/watch?v=sxLEuoK0xFs\n[9]: https://www.flickr.com/photos/nickpegg/sets/72157682416796352/\n"},{"date":"2015-08-16T00:00:00.000Z","tags":["linux","networking","ipv6"],"title":"Building My Own Home Router - IPv6 Tunnel","blurb":"Continuing on my adventure of running my own self-built router at home, I decided to get IPv6 running on my home network. As of writing this blog post, my ISP doesn't do native IPv6 yet so I decided to go with Hurricane Electric's [IPv6 Tunnel Broker](https://tunnelbroker.net) service, which provides you with an IPv6-in-IPv4 tunnel.\n","body":"Continuing on my adventure of running my own self-built router at home, I decided to get IPv6 running on my home network. As of writing this blog post, my ISP doesn't do native IPv6 yet so I decided to go with Hurricane Electric's [IPv6 Tunnel Broker](https://tunnelbroker.net) service, which provides you with an IPv6-in-IPv4 tunnel.\n\n# Creating the tunnel\n\nThe first step is going to [HE's Tunnel Broker website][1] and creating a regular tunnel. Set your IPv4 endpoint to your router's public IP address and be sure to pick a tunnel server close to you.\n\nOnce the tunnel's been created, you'll want to grab the following information:\n\n* Server IPv4 address\n* Server IPv6 Address (this will be your route to the outside world)\n* Client IPv6 Address (this will be your router's address)\n* Routed /64 (this is the block of IPv6 addresses for your network)\n\nIf you run multiple subnets, you can create a /48 block, but for my uses I just need a single subnet (/64 block), so that's what I'll be covering.\n\n\n# Updating the firewall\n\nBefore we even fire up the tunnel, we want to make sure it'll be secure when it comes up. This is a little different from my [first post][2] which covered IPv4 since we won't be using a NAT, but instead directly routing packets.\n\nThe goals of these firewall rules will be to:\n\n* Allow traffic related to already-established outbound connections\n* Allow ICMPv6 Destination Unreachable\n* Allow ICMPv6 Echo Request\n* Allow ICMPv6 Neighbor Soliciation and Advertisement on the local network (interface br0)\n* Allow all traffic coming from the local network (interface br0) out the world (interface he-ipv6)\n* Drop everything else\n\nSince we are doing regular routing, all rules on the INPUT chain will manage traffic directed to the router itself and all rules on the FORWARD chain will manage routed traffic (between the local network and the internet).\n\nHere's what my `/etc/iptables/rules.v6` file looks like with all these rules applied. Note that the default policy on `INPUT` and `FORWARD` are `DROP`.\n\n```\n*filter\n:INPUT DROP [0:0]\n:FORWARD DROP [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -i lo -j ACCEPT\n-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT\n-A INPUT -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT\n-A INPUT -i br0 -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-solicitation -j ACCEPT\n-A INPUT -i br0 -p ipv6-icmp -m icmp6 --icmpv6-type neighbour-advertisement -j ACCEPT\n-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type echo-request -j ACCEPT\n-A FORWARD -p ipv6-icmp -m icmp6 --icmpv6-type destination-unreachable -j ACCEPT\n-A FORWARD -i br0 -o he-ipv6 -j ACCEPT\nCOMMIT\n```\n\n\n# Updating the `interfaces` file\n\nOnce you have the firewall rules in place, it's time to update the `/etc/network/interfaces` file for the tunnel. There are two additions that we need to make: An IPv6 address for your internal network's interface and a virtual interface for the tunnel.\n\nThis is where you'll use the details you got from the Tunnel Broker website. Everything will mostly be directly used, however you need to choose an address from the Routed /64 block for your router's internal interface. The first one in the block is convenient, so if your block is `2001:470:6661:7274::/64` then your router's address will be `2001:470:6661:7274::1` (`2001:470:6661:7274::0` is technically the first address, but using 1 is less confusing since it's similar to IPv4 addressing).\n\nHere's what my `/etc/network/interfaces` files looks like after those changes, the IPv6 additions at the end. Be sure to replace the variables in the file with the values you got from the Tunnel Broker website.\n\n```\n# The loopback network interface\nauto lo\niface lo inet loopback\n\n# outside\nallow-hotplug eth0\niface eth0 inet dhcp\n hwaddress ether AA:BB:CC:DD:EE:FF\n\tdns-search home.nickpegg.com nickpegg.com\n\tdns-nameservers 8.8.8.8 8.8.4.4\n\niface eth0 inet6 auto\n\niface eth1 inet manual\niface wlan0 inet manual\n\nauto br0\niface br0 inet static\n\taddress 10.0.0.1\n\tnetmask 255.255.255.0\n\tbridge_ports eth1\n\niface br0 inet6 static\n\taddress 2001:470:6661:7274::1\n\tnetmask 64\n\nauto he-ipv6\niface he-ipv6 inet6 v4tunnel\n\taddress $CLIENT_IPV6_ADDRESS\n\tnetmask 64\n\tendpoint $SERVER_IPV4_ADDRESS\n\tgateway $SERVER_IPV6_ADDRESS\n```\n\nOnce you make these changes you'll be able to run these commands to start/restart your interfaces to fire up the tunnel:\n\n* `sudo ifdown br0; sudo ifup br0`\n* `sudo ifup he-ipv6`\n\nNote that if you're SSH'd into your server, you should run the first command in screen because you're going to lose connectivity for a few seconds. Once your tunnel's up, you should be able to `ping6 ipv6.google.com` and get a response.\n\n\n# Setting up Router Advertisements\nGetting the router talking IPv6 is only the first half. Now we need to have the devices on our local network pick up IPv6 addresses using a mechanism called [Router Advertisement][3]. Fortunately there's a Linux package called `radvd` which is incredibly easy to set up.\n\nHere's what a basic `/etc/radvd.conf` will look like. Again, be sure to replace `$ROUTED_64` with the block you were assigned via the Tunnel Broker website.\n\n```\ninterface br0\n{\n AdvSendAdvert on;\n\n prefix $ROUTED_64\n {\n };\n};\n```\n\nYeah, that's it. Start the `radvd` service and everything should get an IPv6 address. From a machine that's not your router, you can `ping ipv6.google.com` to verify that connectivity's working.\n\n\nNow that's all done, you have a router that talks IPv6 with the world and you can feel a little bit better about the whole [IPv4 exhaustion][4] issue.\n\n\n[1]: https://tunnelbroker.net/\n[2]: https://nickpegg.com/2014/8/building_my_own_home_router,_part_1.html\n[3]: https://tools.ietf.org/html/rfc4861#section-6\n[4]: https://en.wikipedia.org/wiki/IPv4_address_exhaustion\n"},{"date":"2014-08-22T00:00:00.000Z","tags":["linux","networking"],"title":"Building My Own Home Router, Part 2 - 802.11","blurb":"In my [last post](http://nickpegg.com/2014/8/building_my_own_home_router,_part_1.html) I talked about getting my home router up and forwarding packets from nothing and getting my computers connected via Ethernet. The next step is to get 802.11 (WiFi) working.\n","body":"In my [last post](http://nickpegg.com/2014/8/building_my_own_home_router,_part_1.html) I talked about getting my home router up and forwarding packets from nothing and getting my computers connected via Ethernet. The next step is to get 802.11 (WiFi) working.\n\n\n# Hardware Caveats\n\nIn my last post, I mentioned that I got the Intel 7260-ac card, which I've had some problems with. Intel decided to code into the EEPROM that the card can only use channels that make it compliant with *every* country's laws, and the firmware and Linux driver dutifully read this information and comply. This means that the card can only work in AP mode on channels 1-11, and will NOT in the 5GHz band. This means that you're stuck to the noisy 2.4 GHz band and can't even use 802.11ac (since it requires 5GHz).\n\nI've seen some various blog and forum posts where the OpenWRT people have gotten around this on cards with atheros chipsets since it's just a check in the driver. However, in the small amount of kernel driver hacking I've done, I've been unsuccessful.\n\n**Long story short**, watch which card you pick up and make sure people have had luck making it do what you want to, preferrably without having to patch kernel drivers.\n\n\n# Network Changes\n\nSince you're turning your router into a wireless access point, you have two options to connect clients to your network: split them off into their own network segment in a different subnet, or bridge the wireless interface in with your inside network and let wireless users mingle with your wired users. I chose the latter, since it was simpler.\n\nThe basic idea is that you create a bridge device (`br0`) and bridge in your `eth1` and `wlan0` interfaces. My updated config shows the changes you need to make to `/etc/network/interfaces`:\n\n```\nauto lo\niface lo inet loopback\n\n# outside\nallow-hotplug eth0\niface eth0 inet dhcp\n hwaddress ether AA:BB:CC:DD:EE:FF\n dns-search home.nickpegg.com nickpegg.com\n dns-nameservers 8.8.8.8 8.8.4.4\n\n# inside\niface eth1 inet manual\niface wlan0 inet manual\n\nauto br0\niface br0 inet static\n address 10.0.0.1\n netmask 255.255.255.0\n bridge_ports eth1\n```\n\nNote that `br0` has pretty much taken the place of `eth1` in the config. Also, we don't bridge in `wlan0` since our access point daemon will take care of that.\n\nAlong with this change in `/etc/network/interfaces`, don't forget to also change your dnsmasq settings so that it listens on `br0` instead of `eth1`.\n\nInstall the `bridge-utils` package if you haven't already and restart networking. Congrats, your router is now a one port network switch!\n\n\n# Firewall Changes\n\nSince our inside interface is now `br0`, we have to tweak our firewall rules a bit.\n\n#### rules.v4\n```\n*nat\n:PREROUTING ACCEPT [0:0]\n:INPUT ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -o eth0 -j MASQUERADE\nCOMMIT\n*filter\n:INPUT DROP [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -i lo -j ACCEPT\n-A INPUT -i eth1 -j ACCEPT\n-A INPUT -i br0 -j ACCEPT\n-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT\n-A FORWARD -i eth0 -o br0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A FORWARD -i br0 -o eth0 -j ACCEPT\nCOMMIT\n```\n\n#### rules.v6\n```\n*filter\n:INPUT DROP [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -i lo -j ACCEPT\n-A INPUT -i eth1 -j ACCEPT\n-A INPUT -i br0 -j ACCEPT\nCOMMIT\n```\n\n\n# HostAPd Config\n\nThanks to [`hostapd`][2], getting your wireless card running in AP mode is a cinch! It's just a package install away in most cases, and the configuration isn't *too* terrible. Below is my config, annotated to make it easier to understand.\n\n```\n# Set up some logging. VERY useful to see why things aren't working.\nlogger_syslog=-1\nlogger_syslog_level=2\nlogger_stdout=-1\nlogger_stdout_level=2\n\n# Which interface to use and which bridge to join\ninterface=wlan0\nbridge=br0\n\n# Use this driver for AP stuff. This corresponds to the mac80211 driver\n# which most newer cards support.\ndriver=nl80211\n\n# 802.11 mode and channel, pretty self-explanatory\nhw_mode=g\ncountry_code=US\nchannel=11\n\n\n# Set and broadcast the SSID. Stupid double-negatives...\nssid=test_net\nignore_broadcast_ssid=0\n\n# 802.11N stuff - Try 40 MHz channels, fall back to 20 MHz\nieee80211n=1\nht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40]\n\n# WPA Authentication\nauth_algs=1 # Open authentication, no WEP\nwpa=2 # WPA2 only, set to 3 for WPA+WPA2\nwpa_passphrase=xxxxxxxxxxx # Hah! Like I'd put this in a gist.\nwpa_key_mgmt=WPA-PSK\nrsn_pairwise=CCMP # Cipher for WPA2 (AES in this case)\n\n# Don't use a MAC ACL\nmacaddr_acl=0\n```\n\nThe things to watch out for are the settings that are ORs of bits, like `auth_algs` and `wpa`. When setting up your own AP, it's a good idea to check out the [example config][3] to see what each setting does and what the defaults are.\n\nMy config doesn't include any 5 GHz settings, so you'll have to figure those out on your own if you're lucky enough to have a card that supports it. If I get mine working, I'll make another post with those settings.\n\nOnce you're done with configuration, fire up `hostapd` with `service hostpad start`. If everything was successful, you should see `wlan0` bridged in (use the `brctl show` command to check) and the network should be joinable by one of your wireless devices. If you don't see that, you'll want to check `/var/log/syslog` to see what hostapd is complaining about.\n\n\nAnd there you have it, a router with wireless! Next up is IPv6 support, so stay tuned for part 3.\n\n\n\n[1]: http://nickpegg.com/2014/8/building_my_own_home_router,_part_1.html\n[2]: http://wireless.kernel.org/en/users/Documentation/hostapd\n[3]: http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=blob_plain;f=hostapd/hostapd.conf\n"},{"date":"2014-08-19T00:00:00.000Z","tags":["linux","networking"],"title":"Building My Own Home Router, Part 1","blurb":"This is the first of a series of blog posts on building my own home router from scratch using Debian. My hopes are that by sharing my experiences, it can help others in this endeavor.\n","body":"This is the first of a series of blog posts on building my own home router from scratch using Debian. My hopes are that by sharing my experiences, it can help others in this endeavor.\n\nI've been kicking around the idea of building my own router for a while now, mostly due to the fact that my trusty [WRT54GL][1] is grealy limted by what it can do with its measly 4 MB of flash and weak CPU. After months of casually searching and trying (unsuccessfully) to re-purpose some old hardware, I finally found what I've been looking for: a cheap-ish, low-power, rackmount server with more than one NIC.\n\n# The Hardware\n\n* [Intel D2500CCE Mini-ITX motherboard in a rackmount case][2]\n* [Intel 7260-ac Mini-PCIe card with antenna][3] - there are some issues with this, which I'll cover in a later post\n\nI can't believe that I didn't think to check the various Mini-ITX resellers for something like this, because this is almost exactly what I've always been looking for. I got a 2-NIC board since I'm cheap and already have a gigabit switch, but you can easily find boards with more ports if you don't mind shelling out the extra cash.\n\nOnce the equipment got to my apartment, I slapped in some old laptop RAM and a spare 2.5\" drive and got Debian installed.\n\n\n# 802.3 and IPv4\n\nThe first order of business was to replicate the core functionality of my old router: IPv4 routing and Ethernet connectivity. The plan was to use eth0 as my public interface (plugged into my cable modem) and eth1 as my internal interface. Before I even plugged in anything, I wrote a basic `/etc/network/interfaces` file.\n\n```\nauto lo\niface lo inet loopback\n\n# outside\nallow-hotplug eth0\niface eth0 inet dhcp\n hwaddress ether AA:BB:CC:DD:EE:FF\n dns-search home.nickpegg.com nickpegg.com\n dns-nameservers 8.8.8.8 8.8.4.4\n\n# inside\nauto eth1\niface eth1 inet static\n address 10.0.0.1\n netmask 255.255.255.0\n```\n\nNote the `hwaddress ether` line there. Since my ISP (whose name shall not be spoken (not Voldemort, but [just as evil][4])) locks me to a single MAC address, my new router had to spoof my old router's MAC address, which was spoofed from my laptop that I originally set the connection up with. If you seemingly can't get a DHCP lease on your public interface, this is likely the problem.\n\n\nNow that I had my interfaces configured and rarin' to go, I had to make sure that my ip{,6}tables rules were in order before plugging in.\n\n#### rules.v4\n```\n*nat\n:PREROUTING ACCEPT [2:125]\n:INPUT ACCEPT [1:65]\n:OUTPUT ACCEPT [4:260]\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -o eth0 -j MASQUERADE\nCOMMIT\n*filter\n:INPUT DROP [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -i lo -j ACCEPT\n-A INPUT -i eth1 -j ACCEPT\n-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT\n-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT\n-A FORWARD -i eth1 -o eth0 -j ACCEPT\nCOMMIT\n```\n\n#### rules.v6\n```\n*filter\n:INPUT DROP [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n-A INPUT -i lo -j ACCEPT\n-A INPUT -i eth1 -j ACCEPT\nCOMMIT\n```\n\nThe above rules are my output from `iptables-save` and `ip6tables-save`, and are fully compatible with the respective restore programs. Debian even has a nice package called `iptables-persistent` which will load these rules on boot if you stash them as `rules.v4` and `rules.v6` in `/etc/iptables`!\n\nTo better understand these rules, it helps to have the [Netfilter packet flow diagram][5] in front of you. There are some simple goals with these:\n\n## IPv4 Filters\n\n* Allow traffic coming from loopback or the inside interface\n* Only allow traffic outside->inside if it pertains to an existing in->out connection\n* **Secret sauce** - that MASQURADE line enables NAT, so my private addresses can hide behind the one public address that my ISP gives me\n\n\n## IPv6 Filters\n\n* Just drop everything for now unless it comes from the inside and is destined for the router itself\n\n\nOf course, before I could have a fully-functional internet connection, I had to get DNS set up. And I guess a DHCP server would be nice to have before my leases all expire and everything drops its IP.\n\nLuckily, there's a software package which is geared towards these very tasks: `dnsmasq`! Getting it running was as easy as running `apt-get install dnsmasq` and `service dnsmasq start`, which was enough to get DNS working. To get DHCP working, I created two config files in `/etc/dnsmasq.d/`:\n\n#### dhcp.conf\n```\n# My DHCP configs\ndhcp-range=10.0.0.110,10.0.0.250,12h\n\n# options for DNS\ndhcp-option=option:domain-search,home.nickpegg.com,nickpegg.com\n\n# Static DHCP entries\ndhcp-host=00:24:1D:7D:5F:C3,10.0.0.10,host1\ndhcp-host=88:30:8A:22:2E:74,10.0.0.11,host2\ndhcp-host=00:23:54:1A:16:2D,10.0.0.12,host3\n```\n\n#### interface.conf\n```\n# Only allow DNS/DHCP requests from the inside interface\ninterface=eth1\n```\n\nWith all of that, I had a functioning IPv4 router and could do important things again, like idle on IRC and browse Reddit.\n\nThis is just the beginning though! You should go check out [part 2][6] of this series where I get 802.11 working.\n\n\n\n[1]: http://en.wikipedia.org/wiki/Wrt54gl\n[2]: http://mitxpc.com/proddetail.asp?prod=ER1UD2500DLM02\n[3]: http://mitxpc.com/proddetail.asp?prod=INTWIFI7260AC\n[4]: http://www.comcast.com/\n[5]: http://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg\n[6]: http://nickpegg.com/2014/8/building_my_own_home_router,_part_2_-_802.11.html\n"},{"date":"2011-11-25T00:00:00.000Z","tags":["git","games"],"title":"Syncing Minecraft Saves with Git","blurb":"I've been playing Minecraft for a while and after doing some travelling, I've\nran into the issue where I'd like to syncronize my Minecraft saves across\ncomputers.\n","body":"I've been playing Minecraft for a while and after doing some travelling, I've\nran into the issue where I'd like to syncronize my Minecraft saves across\ncomputers.\n\nI already use git for software version control, so why not shoehorn Minecraft\ninto it? Not only would I get easy syncronization, I would also get version\ncontrol so if I seriously mung something up, I can revert back to a previous\nsave! Here's how I did it.\n\nFirst, I had to make sure git was installed on all of my machines. Luckily\non Linux git is usually provided in the package repository (git-core), but\nsince my desktop also runs Windows (for gaming), I use\n[msysgit](http://code.google.com/p/msysgit/). For example,\non Debian/Ubuntu all you need to do is:\n\n```\nsudo apt-get install git-core\n```\n\nOnce git was installed, I decided to go with a centralized approach since I\nwant one 'official' spot where I can push and pull my Mincraft saves to.\nI already have a server\nfrom the wonderful folks at [Linode](http://linode.com), so I just\ninitialized a bare (centralized) repository on there:\n\n```\ncd /path/to/repos/minecraft\ngit init --bare\n```\n\nThen, since I already have Minecraft installed on my desktop with quite a few\nsaves, I had to clone the central repository, add my saves, commit, and then\npush back to the central repository.\n\n```\ncd /home/nick/.minecraft/\ngit clone nick@nickpegg.com:/path/to/repos/minecraft temp\nmv temp/.git ./\n```\n\nSince you can't clone a repository into a non-empty folder, I had to clone it\nto a temporary folder and then copy the .git folder from there into my\n.minecraft folder. Now that my local repository was setup, I added the files\nI wanted to syncronize.\n\n```\ngit add saves screenshots stats texturepacks options.txt servers.dat\ngit commit -m 'Initial commit'\n```\n\nOnce I had the files commited, all I needed to do was push them up to the\ncentral repository on my server.\n\n```\ngit push\n```\n\nAnd now I have my Minecraft files in a central spot! Now every time I'm done\nplaying a bit, all I have to do to sync my files up is:\n\n```\ngit commit -a -m 'Played a bit'\ngit push\n```\n\nNow, on other machines, all I need to do is clone once, ``git pull``\nbefore playing,\nand then commit and push when I'm done playing!\n\nEasy peasy. Of course, you can do more fancy things with git since it's a\nfull-blown version control system. If you feel inlined to play with those\nfeatures, go read some [documentation](http://gitref.org/).\n"},{"date":"2011-02-20T00:00:00.000Z","tags":["beer"],"title":"Kegerator","blurb":"After getting my tax refund and being sick and tired of bottling my homebrew\nbeer, I've built myself a kegerator!\n\n[](http://www.flickr.com/photos/nickpegg/sets/72157625971333921/)\n\nDetails are over at my [project page](/projects/kegerator/), or if you'd\nrather just gawk at some pictures, check out the [Flickr set](http://www.flickr.com/photos/nickpegg/sets/72157625971333921/)!\n","body":"After getting my tax refund and being sick and tired of bottling my homebrew\nbeer, I've built myself a kegerator!\n\n[](http://www.flickr.com/photos/nickpegg/sets/72157625971333921/)\n\nDetails are over at my [project page](/projects/kegerator/), or if you'd\nrather just gawk at some pictures, check out the [Flickr set](http://www.flickr.com/photos/nickpegg/sets/72157625971333921/)!\n"},{"date":"2010-10-22T00:00:00.000Z","tags":["programming"],"title":"New Website (Again!)","blurb":"Yes, it's that time of year. Time to change my website design\n _yet again_!\n\nI got tired of dealing with Wordpress and wrote my own static page generator\nin Python, dubbed [Posty](http://github.com/nickpegg/posty). I know, I'm\nkind of [re-inventing the wheel](http://ringce.com/hyde) here and there\nare some [really nice solutions](http://github.com/mojombo/jekyll/wiki) to\nthis problem, but why not just make something for making's sake?\n\nPlus, I just feel _cool_ using Markdown and YAML to update my website.\n","body":"Yes, it's that time of year. Time to change my website design\n _yet again_!\n\nI got tired of dealing with Wordpress and wrote my own static page generator\nin Python, dubbed [Posty](http://github.com/nickpegg/posty). I know, I'm\nkind of [re-inventing the wheel](http://ringce.com/hyde) here and there\nare some [really nice solutions](http://github.com/mojombo/jekyll/wiki) to\nthis problem, but why not just make something for making's sake?\n\nPlus, I just feel _cool_ using Markdown and YAML to update my website.\n"},{"date":"2010-06-23T00:00:00.000Z","tags":[],"title":"Verifying Google Voice","blurb":"I've been struggling getting my work phone number verified with Google Voice. The way that number verification works is that Google Voice calls you and asks\nyou to enter the two-digit code that's displayed on the website. But for some reason when I get a call on my outside line and I press a number button, it\ndoesn't send that DTMF tone. Instead it tries to place another call.\n\nMy solution? I found a DTMF tone generator online and I played the code DTMF tones through my computer speakers.\n\nIt's nice to see that these old phone tricks still work.\n","body":"I've been struggling getting my work phone number verified with Google Voice. The way that number verification works is that Google Voice calls you and asks\nyou to enter the two-digit code that's displayed on the website. But for some reason when I get a call on my outside line and I press a number button, it\ndoesn't send that DTMF tone. Instead it tries to place another call.\n\nMy solution? I found a DTMF tone generator online and I played the code DTMF tones through my computer speakers.\n\nIt's nice to see that these old phone tricks still work.\n"},{"date":"2010-06-19T00:00:00.000Z","tags":["linux","htpc"],"title":"LIRC and XBMC","blurb":"Those of you who know me fairly well know that I'm a total HTPC\ngeek. It's to the point where I outright refuse to subscribe to cable television\nor even hook up an antenna to my TV. This geekery combined with my affinity\nfor Linux leads me to running XBMC on Linux on my little home theater machine.\nIt's been a pretty smooth experience with the exception of getting my remote\nwork with it. If you're struggling with it too, hopefully my tales will help you\nget it going.\n","body":"Those of you who know me fairly well know that I'm a total HTPC\ngeek. It's to the point where I outright refuse to subscribe to cable television\nor even hook up an antenna to my TV. This geekery combined with my affinity\nfor Linux leads me to running XBMC on Linux on my little home theater machine.\nIt's been a pretty smooth experience with the exception of getting my remote\nwork with it. If you're struggling with it too, hopefully my tales will help you\nget it going.\n\nSo, here's my setup. I've got an Antec Fusion 430 (a silver one\nwith the VFD), a Logitech Harmony remote, and Ubuntu 10.04. The Antec case is\npretty cool since it looks like it belongs \nin my home theater setup, and it\neven includes an IR receiver built right into the case! Cool! It should accept\nsignals from any IR remote, right?\n\n*Wrong*\n\nIn the hardware developer's infinite\nwisdom, they made it only work with Windows Media Center remotes instead of just\nmaking it a dumb device that passes data along. They actually put \n**more** effort\ninto designing the thing just to make my life harder. Augh! Luckily, when I got\nthis case my [then-roommate](http://benmurrell.com/) had an Xbox 360 remote which\nmagically \nworked! So I eventually got a Logitech Harmony remote and told it\nthat my HTPC was actually an Xbox 360. Step one complete.\n\nThe next step was\nto get LIRC to accept the remote. This is a bit tricky, but luckily I had backed\nup my configs. If you're starting out from scratch, here's how to do it in an\nUbuntu system.\n\nFirst of all, you need to install LIRC:\n\n sudo aptitude\n install lirc\n\nDuring the configuration phase of the install, it'll ask you for\nwhat kind of device you have. I selected *Soundgraph iMON PAD IR/VFD*, which uses\nthe lirc_imon driver. Unfortunately, since I have the silver Antec Fusion\n430 I have the VFD and not the LCD display, which has a slightly different IR\nreceiver. You have to specify the display_type=1 when the module is loaded.\nYou can do this by adding a file called lirc-imon.conf to /etc/modprobe.d/ with\n[these contents](http://nickpegg.com/stuff/lirc/modprobe.d-lirc-imon.conf). \n\nIf you don't want to restart, you'll have to throw commands at the system to reload\nthe module with the correct options.\n\n sudo service lirc stop\n sudo rmmod lirc_imon\n sudo modprobe lirc_imon display_type=1\n\nWhile you have LIRC stopped, you might as well double-check that the IR receiver is\nactually receiving data with the following command (hit Ctrl-C to stop):\n\n sudo cat /dev/lirc0\n\nYou should see a bunch of garbage get printed to\nthe terminal when you press buttons on your remote. If you don't, then either\nyou have the wrong type of remote or you don't need the \ndisplay_type argument to modprobe.\n\nNext, you need to setup the button config for your remote. Since\nI'm using a Logitech Harmony remote to emulate an Xbox 360 remote, I used the\nirrecord command to generate [my config](http://nickpegg.com/stuff/lirc/xbox360.conf).\nLuckily there's [plenty of people out there](http://www.google.com/search?&q=lirc++microsoft+remote+config)\nwho have already done this for you for a large amount of remotes \n([here's a good list](http://lirc.sourceforge.net/remotes/), for example). \nOnce you have the remote config file downloaded or created, \nadd an include to your [lircd.conf](http://nickpegg.com/stuff/lirc/lircd.conf)\nfor it, fire up LIRC, and test it out with the irw command.\n\n sudo service\n lirc start\n irw\n\nWhen you press buttons, you should see the button commands\nscroll by in the terminal.\n\n*\\*whew\\** Almost there. Still with me? Good, because\nwe only have one thing left, the XBMC Lircmap.xml file! I'll spare you the nitty-girtty\nof it and just give you \n[mine](http://nickpegg.com/stuff/lirc/Lircmap.xml) (right-click\nand save it). If you feel like making your own or need to tweak mine a bit, the\nXBMC wiki has some \n[good information](http://wiki.xbmc.org/index.php?title=Lirc_and_Lircmap.xml)\non how to do it.\n\n### For the impatient, here's all of my files associated with getting this to work:\n[lircd.conf](http://nickpegg.com/stuff/lirc/lircd.conf) (LIRC) \n[hardware.conf](http://nickpegg.com/stuff/lirc/hardware.conf) (LIRC) \n[xbox360.conf](http://nickpegg.com/stuff/lirc/xbox360.conf) (remote) \n[Lircmap.xml](http://nickpegg.com/stuff/lirc/Lircmap.xml)(XBMC)\n"},{"date":"2010-04-07T00:00:00.000Z","tags":["car"],"title":"New Car","blurb":"It was the Friday before my Spring Break and quite possibly the worst thing in the world happened to me: I got rear-ended while at a stop.\nWell, okay, it's not the worst thing in the world but to a college student who loves his car, it was pretty bad. The lady who hit me did quite a\nnumber on my back end, and then pushed me into the car in front of me. Despite my airbags not going off, my car was totaled. The damage to the bumper,\nright rear quarter panel, and unibody frame were just too much.\n","body":"It was the Friday before my Spring Break and quite possibly the worst thing in the world happened to me: I got rear-ended while at a stop.\nWell, okay, it's not the worst thing in the world but to a college student who loves his car, it was pretty bad. The lady who hit me did quite a\nnumber on my back end, and then pushed me into the car in front of me. Despite my airbags not going off, my car was totaled. The damage to the bumper,\nright rear quarter panel, and unibody frame were just too much.\n\n[![Damage to the Jetta][4]][3]\n\nWith the Jetta totaled I had three options: Buy it back and spend the $1000 left over on repairs/hookers, give it away to the insurance company and\nspend <$2400 on a beater from Craigslist, or do the financially irresponsible thing and buy the new car I've been dreaming of, going into debt even\nfurther than I already was.\n\nGuess which option I chose:\n\n[![2010 VW GTI][2]][1]\n\n\nYes, that's right. I bought myself a new MkVI GTI. Since I had some money saved up from my recent internship, will be starting work in a couple of months,\nand was planning on buying one within a year I decided to go for it. I ended up paying $22,500 for it, which is a few hundred below dealer invoice for the\noptions that I wanted on it. I won't go into any car buying tips here, I'll save that for another post.\n\nOverall, I'm very pleased with my purchase. Here's why:\n\n**Performance:** It's got the VW 2.0L TSI turbocharged engine in it which puts out 200 hp. That's only a little more than my old VR6 Jetta, but the lighter\nengine makes a difference. I'm still breaking the engine in, but from what I can tell from accidentally giving too much gas, it can put down some power.\n\n**Handling:** With the sport-tuned suspension, this thing handles like a beast. With simply taking corners quickly and turning smoothly, I have yet to break\nthe tires loose from the road. There's also a roundabout here in Rolla which I took at speeds that I'm not at liberty to discuss publicly since I'm sure that\nthe city police would frown upon that.\n\nThe car also has a pseudo-locking differential called XDS. This is part of the electronic stability control system. What XDS does is when it senses that one\nwheel is getting too much power compared to the other, it applies the brakes to that first wheel to slow it down, giving more power to the second wheel. I\nhaven't noticed this kick in yet, but probably because I'm not giving it full throttle due to the break-in period\n\n**Electronics:** Included standard on the car is a touchscreen radio with Volkswagen's MDI interface. The MDI interface provides a port in the arm rest where\ndifferent devices can be plugged in, such as an iPod or USB drive. With the addition of an SD card slot right in the radio, with support up to 32 GB, I no\nlonger need a car computer. The software can be a little flaky at times and could use certain features (like creating an on-the-go playlist), but it suits my needs fine.\n\nAlso included is the MFI, which is essentially a trip computer. It tells you trip time, distance, fuel consumption, range left on the tank of gas, etc. The cool\npart about this is that in the settings menu, you can adjust some convenience settings which normally could only be done using a VAG-COM, such as which doors\nunlock when you use the keyfob, rolling windows down with the key, etc.\n\n**Practicality:** The folks on Top Gear always talk about the practicality of a car whenever they review something the average person could buy. Since I'm not\ngoing through a mid-life crisis, something practical is what I need. The GTI fits this bill nicely.\n\nThere's plenty of room for passengers in the back (a change VW made starting with the MkV) along with all of the creature comforts you would expect from sitting\nin the front. There's also a good amount of space in the hatch area, and the back seats fold down in case I need to haul anything big. I was able to fit a whole\nrecliner in the back with room to spare, for example.\n\nAll in all, I really love this car. It's quick, fun to drive, can get good gas mileage, and it's still useful for when I need it.\n\n\n[1]:/media/img/GTI.jpg\n[2]:/media/img/GTI-thumb.jpg\n[3]:/media/img/jetta.jpg\n[4]:/media/img/jetta-thumb.jpg\n"},{"date":"2010-02-09T00:00:00.000Z","tags":[],"title":"Whiteboard","blurb":"If you know me personally, you know that I can be pretty scatterbrained from\ntime to time. I've desperately needed a whiteboard to keep my thoughts\norganized, and I've finally gotten one. I know, it's not the\nmost exciting thing in the world to talk about, but it should be a change\nin the right direction for me.\n","body":"If you know me personally, you know that I can be pretty scatterbrained from\ntime to time. I've desperately needed a whiteboard to keep my thoughts\norganized, and I've finally gotten one. I know, it's not the\nmost exciting thing in the world to talk about, but it should be a change\nin the right direction for me.\n\n[](/media/img/whiteboard1.jpg)\n\nBut, wait. What's this? \"Beertraq Road to Stable\"?\n\n[](/media/img/whiteboard2.jpg)\n\nPart of why I want to get my thoughts organized is because I want a good\nview of what all is left before I fully release Beertraq to the public.\nWith this list looming over my head (literally) it will hopefully get my\nbutt in gear to reach a stable release.\n"},{"date":"2009-12-25T00:00:00.000Z","tags":["cooking"],"title":"Holiday Ham Recipe","blurb":"I don't cook/bake all that often, but when I do I like to have some fun\nwith it. I came up with a ham recipe that turned out well, so I figured\nI'd share it with everyone.\n","body":"I don't cook/bake all that often, but when I do I like to have some fun\nwith it. I came up with a ham recipe that turned out well, so I figured\nI'd share it with everyone.\n\nFirst, put your ham in a baking pan and cut the diamond pattern into it. Trust\nAlton Brown when he says that utility knives work well for this. Then, mix the\nfollowing in a bowl\n\n* 1 cup brown sugar\n* 1/2 teaspoon ground mustard\n* 4 ounces of fine bourbon. My preference is Maker's Mark.\n\nOnce you have that all mixed up, pack it gently onto the ham. Uniformity is nice,\nbut not required. Then cook the ham at 325 degrees Fahrenheit until the inside\nmeat temperature reaches 150 degrees (about 3 hours with a 20 pound ham). I\nguarantee that it'll be tasty when it's done.\n"},{"date":"2009-12-18T00:00:00.000Z","tags":["programming","networking"],"title":"More Fun With Graphs","blurb":"I figured I'd post the latest graph magic from my work at Nucor-Yamato Steel.\nThis is a graph of the entire network, switches AND hosts!\n","body":"I figured I'd post the latest graph magic from my work at Nucor-Yamato Steel.\nThis is a graph of the entire network, switches AND hosts!\n\n[](/media/img/more_fun_with_graphs/nys-super-sanitized.png)\n<p class=\"centered\">(click for full-sized version, warning: LARGE image)</p>\n\nHere, the yellow boxes are center switches/routers, the green boxes are switches,\nand the peach-colored nodes are hosts. Also, red lines are switch-to-switch\nconnections and blue lines are switch-to-host connections.\n\nAnother somewhat off-topic thing about these graphs is that the manager of IT at\nNucor-Yamato is interested in open-sourcing the code that manages all of the data\nand generates these graphs, AND let me use company time to work on and manage the\nproject. If anyone knows of any open-source project (or software that doesn't cost\nan arm and a leg) that already does network discovery, data collection, and automated\nmapping then please let me know! If I'm not going to be re-inventing the wheel, then\nI'll probably be kicking the project off shortly after I start working full-time in\nJune 2010.\n"},{"date":"2009-12-05T00:00:00.000Z","tags":["programming","beertraq"],"title":"Beertraq Beta!","blurb":"I'm glad to announce that my recent pet project, Beertraq, is now in a\n(somewhat closed) beta stage! The basic idea is there and functioning,\nbut the extra functionality isn't done and it's far from polished.\nNonetheless, it's time to take her for a test drive!\n","body":"I'm glad to announce that my recent pet project, Beertraq, is now in a\n(somewhat closed) beta stage! The basic idea is there and functioning,\nbut the extra functionality isn't done and it's far from polished.\nNonetheless, it's time to take her for a test drive!\n\n\n> Note from future-Nick\n>\n> I got lazy and never finished Beertraq, and Untappd ended up releasing not long after. Though it took them _years_ to implement a barcode scanner in the app, which was going to be a core thing in Beertraq.\n\n\nSo what is Beertraq, you ask? It's a way for you to keep track of which\nbeers you've tasted, compare those with others, read beer reviews, and\nmost importantly discover new beers to try. I originally got the idea\nfrom The Flying Saucer's UFO Club, where members work toward a goal of\ndrinking 200 different beers. Once they complete the task, they get their\nname on a plate which gets put on the wall of the bar. The cool part about\nthe UFO Club is that it's all computerized, using a magstripe card to login\nat a kiosk in the bar. You can also log in to their website to check your\nprogress and read reviews on there. I figured that if The Flying Saucer can\nhave that system for their bar, I could do the same for the world.\n\nIf you're interested in becoming a BeerTraq beta user, send an email to\nbeertraq (at) beertraq (dot) com with the email address you want to use for\nyour account. All I ask is that you give feedback by filling out issue requests\nwith bugs you find or suggestions you might have.\n"},{"date":"2009-11-30T00:00:00.000Z","tags":["programming","networking"],"title":"Fun With Graphs","blurb":"I've always been utterly fascinated with graph theory, mostly with its\napplications to networks. As an added bonus, they can be represented with\npretty pictures!\n","body":"I've always been utterly fascinated with graph theory, mostly with its\napplications to networks. As an added bonus, they can be represented with\npretty pictures!\n\n[](/media/img/fun_with_graphs/nys-network.png)\n(click on image for full-sized version)\n\nThat graph represents the network behind Nucor-Yamato Steel and Nucor Castrip\nArkansas, sanitized of sensitive information of course. All of the nodes are\nCisco switches, the yellow boxes representing backbone switches (6500 series\nto be exact). This graph is part of the network information system that I've\nbeen working on during the majority of my internship at NYS and gets auto-generated\nevery day, along with more centralized graphs on a per-switch basis.\nThe way the system works is that a periodic Python script goes out to a list of\nknown switches and gathers CDP neighbor information as well as the MAC address\ntables. Then Nmap scans are ran every 6 hours to scan for hosts, gathering IP\naddresses, hostnames, and MAC addresses. These MAC addresses are correlated with\nthe MAC tables from the switches to determine which hosts are connected to which\nports on what switches. The CDP neighbor information also gives which switches\nare connected to each other, giving a full scope of how the network's connected.\nThe script which generates the graphs grabs all of that information out of the\ndatabase, uses NetworkX and pydot to create the graph, and then graphviz to render\nit into a PNG image. The graph is pretty plain, though. The real version shows\nswitch names and IP addresses. Since the time between graph generation is so long,\nany more useful information that I could throw onto the graph would quickly become\noutdated. My grand scheme is to make a quickly-updated graph showing live stats like\nswitch load, link load, link types (fiber, twisted pair, wireless), downed switches,\netc. That way, I (or the network supervisor, I guess...) could have a big-screen TV\ndisplaying the live health of the network.\n\nI've been asked what parameters I set to get that graph to look that way. I didn't set anything special in code, it's all in the command line:\n\n twopi -q -Ksfdp -Tpng -Goverlap=\"prism\" -Eoverlap=\"prism\" -Gsplines=\"true\" -Gratio=\"compress\" -oclean.png clean.dot\n\nReally, I'm just a data visualization nerd looking to get a fix.\n"},{"date":"2009-11-26T00:00:00.000Z","tags":["servers","linux"],"title":"Moving Servers and Doing It Right","blurb":"Well, I finally bit the bullet and got a Linode account. So far I'm pretty\nhappy with it. I figured that with the costs of power and bandwidth, I was\nalmost spending $20/month to run my old server on my own hardware.\nIncidentally, the lowest-grade Linode VM costs that much and is enough to\nsuit my needs.\n","body":"Well, I finally bit the bullet and got a Linode account. So far I'm pretty\nhappy with it. I figured that with the costs of power and bandwidth, I was\nalmost spending $20/month to run my old server on my own hardware.\nIncidentally, the lowest-grade Linode VM costs that much and is enough to\nsuit my needs.\n\nSo now that I've been setting up a webserver from scratch again, I'm doing\nit right this time. I'm setting up some monitoring software to notify me when\nthings go down, I'm no longer relying on myself for DNS (no more dynamic IPs!),\nand I'm also branching out and trying an alternative webserver.\n\nThe webserver in question is [Cherokee](http://cherokee-project.com/) which claims\nto use less memory and\nperform better than Apache. It sure does use less memory, but as a down side\nit doesn't have a native PHP module, so I'm required to use FastCGI for that\npurpose. Right now, there's five php-cgi processes running each using about\n25-30 MB. This wouldn't be a problem except that I've only got 360 MB of memory\nto play with. On the plus side its got a pretty sweet admin interface with wizards\nto help you set up things like WordPress, Drupal, Ruby on Rails, Django, etc. and\nyou can setup some pretty complex rules for what and how files should be hosted.\n\nOn the monitoring side of things, I'm using [Munin](http://munin.projects.linpro.no/) to monitor the various\n[stats on the server](http://terminalunix.com/munin/), [Piwik](http://piwik.org/) for website visit statistics, and I plan on getting [Monit](http://mmonit.com/monit/) going\nfor service monitoring. It's a bit more important now that I keep and eye on memory\nand data transfer now that I'm limited on that. Also, if some process goes wild and\nstarts using crazy amounts of CPU power and memory, I'll be able to catch it.\n\nUnfortunately when you move servers, you have to move everything that was running\non them. I'm still in that process, but it's been going pretty smoothly.\n"},{"date":"2009-08-18T00:00:00.000Z","tags":["linux"],"title":"Stupid Linux Trick #5245","blurb":"Want to share what you're doing with another person logged into the same system? All you need is a FIFO, cat, and script.\n\nOn your session:\n mkfifo foo\n script -f foo\n\nOn the viewer's session:\n\n cat foo\n\nThe viewer can then see everything that you're doing as if they're looking over your shoulder!\n\n","body":"Want to share what you're doing with another person logged into the same system? All you need is a FIFO, cat, and script.\n\nOn your session:\n mkfifo foo\n script -f foo\n\nOn the viewer's session:\n\n cat foo\n\nThe viewer can then see everything that you're doing as if they're looking over your shoulder!\n\n"},{"date":"2009-06-21T00:00:00.000Z","title":"Intelligent Drink Dispenser - Software Design","blurb":"The other major half of the Intelligent Drink Dispenser project was the software side\nof things. As with the hardware, there were some things we had to consider when\nbeginning the design of things.\n\n","body":"The other major half of the Intelligent Drink Dispenser project was the software side\nof things. As with the hardware, there were some things we had to consider when\nbeginning the design of things.\n\n\nWhat language should we use? Should this be a GUI\napplication or web application? If we go with a GUI application, what operating system\nshould we target?\n\nWe decided that since we only had a semester to get everything done, we needed a\nframework to take care of the more nitty-gritty stuff. We eventually decided to go\nwith the Django web framework, which uses the Python programming language. Python is\na language we all knew and Jon and I had used Django in the past. Also, since our\n'final product' would be highly based on a client-server model, it makes sense to\ngo with a web app since the server can be in a central location with many clients\nconnecting to it.\n\nThe most important thing to us was the fact that Django abstracts the database into models\nfor us. No having to mess around with raw SQL, we just run some queries and get our data\nfrom the models as if they're just plain ol' objects. After some thought, we came up with\nour models and their relationships:\n\n\n\nThe development of the application was fairly straight-forward. It was just a standard\nDjango app after all. The interesting part was interfacing with the hardware.\n\nIf you remember from my post talking about the hardware side, we used an FTDI UM232\nUSB-to-serial converter. Lucky for us, there's a Linux kernel module which represents this\ndevice as a virtual serial port, which made our jobs a whole lot easier since there's\nexisting serial libraries for Python (like pyserial). We ended up just writing a couple of\nfunctions, one to read the RFID tag from the serial port, and one that takes in a Drink id\nand then communicates to the microcontroller to pour it. The microcontroller's fairly dumb,\njust taking a number and turning that pin on, or turning all of the pins off if a non-valid\ncharacter is sent, as you can see in the pourDrink function:\n\n def pourDrink(id, serialPort=DEVICE):\n \"\"\"Pours the drink given by the specified ID\"\"\"\n\n # Seconds per mL of the motors, found experimentally\n # These should be in the database or a config file instead of hardcoded...\n secondsPerML = []\n secondsPerML.append(9.858/350.0) # Pump 0\n secondsPerML.append(9.858/350.0) # Pump 1\n secondsPerML.append(6.385/210.0) # Pump 2\n\n components = DrinkComponent.objects.filter(drink=id)\n\n for c in components:\n stock = IngredientStock.objects.filter(ingredient=c.ingredient)\n total = 0\n\n for s in stock:\n total += s.amount\n\n if total < c.amount:\n raise UnableToPour(\"Not enough \" + c.ingredient.name + \" to pour drink!\")\n\n port = serial.Serial(serialPort, 2400)\n if not port.isOpen():\n raise UnableToPour(\"Unable to open serial port!\")\n\n for c in components:\n stock = IngredientStock.objects.filter(ingredient=c.ingredient)\n leftToPour = c.amount\n\n startTime = time.time()\n\n for s in stock:\n port.write(str(s.slot))\n if leftToPour < s.amount:\n time.sleep(secondsPerML[s.slot]*leftToPour)\n s.amount = s.amount - leftToPour\n s.save()\n\n break\n else:\n time.sleep(secondsPerML[s.slot]*(s.amount - ))\n leftToPour = leftToPour - s.amount - 30\n\n s.amount = 0\n s.save()\n\n print \"Time to pour:\" + str(time.time() - startTime)\n port.write(\"\\n\")\n port.close()\n\nNot exactly the most precise in terms of pouring accuracy, but it gets the job\ndone as a prototype. As for the rest of the code, there's not too much else that's\nvery interesting. I may release the code at some point in the future.\n","tags":[]},{"date":"2009-06-21T00:00:00.000Z","title":"Intelligent Drink Dispenser Details","blurb":"I said that I'd post details on my Intelligent Drink Dispenser project \"soon\". That\nwas over a month ago. Whoops. I blame my [new internship](http://nucoryamato.com/) for that.\n\nFor those of you not in the know, the Intelligent Drink Dispenser was my senior design\nproject at Missouri University of Science and Technology (which will forever in my heart\nbe University of Missouri-Rolla). It's basically a smart drink dispenser that's capable\nof mixing, charging customers, telling the bar/restaurant owner when they need to refill\nthe machine, etc.\n","body":"I said that I'd post details on my Intelligent Drink Dispenser project \"soon\". That\nwas over a month ago. Whoops. I blame my [new internship](http://nucoryamato.com/) for that.\n\nFor those of you not in the know, the Intelligent Drink Dispenser was my senior design\nproject at Missouri University of Science and Technology (which will forever in my heart\nbe University of Missouri-Rolla). It's basically a smart drink dispenser that's capable\nof mixing, charging customers, telling the bar/restaurant owner when they need to refill\nthe machine, etc.\n\nIf you don't feel like reading the details and just want to look at the pretty pictures,\nyou can check out my [Picasa album](http://picasaweb.google.com/nick.pegg/IntelligentDrinkDispenser)\nor watch the [Youtube video](http://www.youtube.com/watch?v=79H5oAS_Y6k).\n\nThe theoretical process is that the customer would go to order a drink, and since they're\na new customer, they'd have to be entered into the system by the person running the machine\n(bartender, or waiting staff). They would have their name and credit card information taken,\nand would then be assigned a drinking vessel based on the first drink they were wanting to\norder. Multiple vessels could also be assigned to the same person. Once the customer is\nsetup and is ready to purchase their drink, they set the fluid vessel on the marked reader\narea on the dispenser. The system then recognizes the vessel, who it belongs to, asks the\ncustomer for the last four digits of their credit card, and then asks the customer which\ndrink they'd like to order. The customer then chooses what drink they'd like to have, the\nsystem double-checks that the vessel is the right size, and pours it.\n\nSecurity and privacy was one of the major goals of the project. The only information stored\nabout the user is their name, a secure hash of their credit card number, the last four digits\nof ther card, and their drink order history.\n\nThe project itself can pretty much be split into two major components: hardware and software.\nI would probably say the hardware is more interesting and posed more challenges for us. The\nfirst thing is how the heck do you pour the fluid? If you take into consideration that we only\nhad a $300 budget for the whole shebang, it's not an easy task. The way that the professionals\ndo it is with Carbon Dioxide-powered pumps, which are controlled by electronic valves and supplied\nby a tank and pressure regulator. Three pumps, valves, and the feed system would cost us well\nover $300. Our original idea was to use 24 VDC sprinkler valves, but that idea failed because the\nsprinkler valves by their nature require back-pressure to operate. We came up with the idea of using\nwindshield washer pumps made for cars. Since this was supposed to be a prototype, we didn't have to\nworry about our components being food-grade. That, coupled with the fact that the pumps operate on\n12V DC and are relatively inexpensive ($15-25 a pop), that's what we went with for our design.\n\nThe rest of the hardware design was fairly straightfoward. We used an 8051 microcontroller to control\neverything, an FTDI UM232 to handle the PC communications and a Parallax RFID reader to read the\ntags that are on the bottom of the drinking vessels. The serial communication is pretty interesting\nsince the USB-to-serial device has only one serial port but two devices to talk to (the RFID reader,\nand the PC). Our solution was to have the receive line go to the RFID reader (to the PC), and have\nthe transmit line go to the 8051 (from the PC). This meant that our 8051 couldn't talk back, so we\nhad to hope that things were working right. Additionally, Richard developed a simple serial language\nfor the 8051. If the 8051 received an ASCII 0 through 7, it would turn on that pin on the port we\nwere using. This could easily be modified to operate with all the ports on the 8051 to control 24\npumps, or even with some addressing logic to control a huge number of pumps.\n\nBelow is our hardware schematic, which should give you some idea of how it's all connected.\n\n\n\nIn my next post, I'll be talking about the software design. Stay tuned!\n","tags":[]},{"date":"2009-05-11T00:00:00.000Z","tags":["idd"],"title":"Intelligent Drink Dispenser in the news!","blurb":"So, I've been pretty quiet about my Intelligent Drink Dispenser project so far,\nmostly because there was going to be a competition between myself and\n[Clint Rutkas](http://betterthaneveryone.com/archive/2009/04/11/856.aspx) and\nI didn't want to give the enemy any details.\n","body":"So, I've been pretty quiet about my Intelligent Drink Dispenser project so far,\nmostly because there was going to be a competition between myself and\n[Clint Rutkas](http://betterthaneveryone.com/archive/2009/04/11/856.aspx) and\nI didn't want to give the enemy any details.\n\nWell, the cat's out of the bag: [http://news.mst.edu/2009/05/students_create_smart_way_to_m.html](http://news.mst.edu/2009/05/students_create_smart_way_to_m.html)\n\nThe communications department of my university, Missouri S&T (formerly UMR), gets\nalerts from Google News whenever someone mentions the university's name and since\nClint did just that, his post showed up in their email. After talking with the\ndirector of communications, he decided to run the story. I gotta say, it's a\npretty great way for my Senior Design class to wind down.\n\nFor those interested in the details of the Intelligent Drink Dispenser, stay\ntuned! I'll be posting more information about it soon.\n\nSide note: since the story got posted, my server's been chugging along to serve\nup my website, almost maxing out the upload on my poor cable internet connection.\nHere's the traffic graph from my router:\n\n\n"},{"date":"2009-04-18T00:00:00.000Z","tags":["servers","linux"],"title":"PXE boot with DD-WRT and Ubuntu","blurb":"After spending all afternoon fighting with my new server and my DD-WRT router,\nI finally figured out how to get my server to PXE boot and fire up an Ubuntu\ninstall. All it really involved was setting up TFTP on another box (my desktop,\nto be specific), adding a line to DD-WRT's DNSMasq options, and configuring the\ndamn server to boot from PXE, which was the hardest part. Luckily, for those of\nyou who are struggling with it, here's how I did it.\n","body":"After spending all afternoon fighting with my new server and my DD-WRT router,\nI finally figured out how to get my server to PXE boot and fire up an Ubuntu\ninstall. All it really involved was setting up TFTP on another box (my desktop,\nto be specific), adding a line to DD-WRT's DNSMasq options, and configuring the\ndamn server to boot from PXE, which was the hardest part. Luckily, for those of\nyou who are struggling with it, here's how I did it.\n\n### Setting up the PXE client\n\nI had to get my server to boot PXE in the first place. For most people, this just\nmeans poking around in the BIOS. Not for me though.\n\nAfter poking around the HP site, I've found out that my server is a first\ngeneration Proliant DL360. Since it's an older machine, this means that it doesn't\nhave a built-in BIOS config, but I had to actually download the old Compaq SmartStart\n5.5 CD. I had to hunt around the HP website, but to save you the trouble, you can snag it here:\n\n[http://ftp.hp.com/pub/products/servers/supportsoftware/ZIP/smartstart-5.50-0.zip](http://ftp.hp.com/pub/products/servers/supportsoftware/ZIP/smartstart-5.50-0.zip)\n\nOnce you boot from the CD, you'll want to go into the System Configuration\nUtility when prompted. From there, it's just like a giant BIOS. Just turn PXE\non for whatever ethernet port you're using and it's rarin' to go.\n\n### Setting up the TFTP server\n\nOnce my server was setup for PXE booting, I had to set up a tftp server for it\nto grab the boot image from. Since I was using my desktop, which runs Ubuntu, as\na host, setup was pretty easy. I just used tftpd-hpa per the Ubuntu wiki's recommendation.\n\n # sudo aptitude install tftpd-hpa\n\nI had to also edit the configuration file at /etc/default/tftpd-hpa. Mine looks like this:\n\n #Defaults for tftpd-hpa\n RUN_DAEMON=\"yes\"\n OPTIONS=\"-l -s /var/lib/tftpboot\"\n\nSince I was wanting to PXE boot into an Ubuntu install, I had to extract the\ninstall files into /var/lib/tftpboot as I put in the config file. For example, the\nnetboot image files for Ubuntu 9.04 can be found here:\n\n[http://archive.ubuntu.com/ubuntu/dists/jaunty/main/installer-i386/current/images/netboot/netboot.tar.gz](http://archive.ubuntu.com/ubuntu/dists/jaunty/main/installer-i386/current/images/netboot/netboot.tar.gz)\n\n### Setting up the the DHCP server\n\nDD-WRT uses dnsmasq for DHCP, so if you have a system which uses it too it shouldn't\nbe too much different to setup. Watch out, though! I initially screwed up my configuration\nwhich really messed with my router.\n\nAll you have to do is add a line to the Additional DNSMasq Options found under the Services\ntab. If you're running plain dnsmasq, just add the line to your dnsmasq.conf file. The line\ngoes a little something like this:\n\n dhcp-boot=pxelinux.0,mybox,10.0.0.100\n\nwhere pxelinux.0 is the file to boot, mybox is the hostname of the tftp server, and 10.0.0.100\nis the IP address of the tftp server. You could probably get away with only specifying the\nhostname or just leaving it blank and supplying the IP address. You can also get more fancy\nand send certain boot images to certain machines, etc. This way works just fine on a home\nnetwork like mine.\n\nOnce you get this all setup, any machines that try to PXE boot will receive the image and\nboot to it. If you used the Ubuntu install image like I did, you'll be able to install Ubuntu\non any PXE-capable machine or even boot into a rescue shell! Just remember that if you can't\nsetup a boot order (like my Proliant) make sure to disable the PXE boot in dnsmasq before rebooting.\n"},{"date":"2009-04-17T00:00:00.000Z","tags":["servers"],"title":"New Server","blurb":"Thanks to a generous donation from [Richard Allen](http://rsaxvc.net/), I now have a new server.\n","body":"Thanks to a generous donation from [Richard Allen](http://rsaxvc.net/), I now have a new server.\n\n\n\nIt's a Compaq Proliant DL360. From what I can tell of it's past, a place where another\nfriend of mine was working was getting rid of their old hardware and he snagged a bunch.\nRichard got some of the servers, had no use for this one, and then gave it to me a couple\nof days ago.\n\nIt's probably a first generation DL360, but that doesn't mean it sucks. It's got dual\nPentium IIIs running at 1.266 GHz each, 512 MB of RAM, and two 18.3 GB SCSI drives running\nin RAID1. It's quite an upgrade from my current server, which is dual P3 450 MHz with a\nlittle less than 512 MB of RAM. The best part of the whole thing, though, is the Remote\nInsight Lights-Out Edition II card that came with it. It's a PCI-X card that redirects\nvideo, keyboard, and mouse from the system and supplies it to a web interface. This means\nthat no matter where I am, I can get a physical terminal to my server. Plus, if I plug an\nexternal power supply to it, I can even turn on my server remotely!\n\nI'll probably be moving everything from my current server over to the new one. Since I'm\nmirroring and then cutting over, there shouldn't be any problems with any of the services\nthat my box supplies.\n"},{"date":"2009-04-15T00:00:00.000Z","tags":[],"title":"New Website","blurb":"So, I've decided to redo my website again. My old one was pretty bland and\nupdating stuff was a relatively a pain. Plus, I seem to be doing more interesting\nthings and having more interesting thoughts (hopefully) than I have in the past\ncouple of years. Of course, I am a Computer Engineer (aka nerd), so don't expect\nto see anything like me pondering the wonders of the cosmos here. I'll probably\nmostly post updates on projects I'm fiddling with, my struggles with technology,\nand what I've been up to.\n","body":"So, I've decided to redo my website again. My old one was pretty bland and\nupdating stuff was a relatively a pain. Plus, I seem to be doing more interesting\nthings and having more interesting thoughts (hopefully) than I have in the past\ncouple of years. Of course, I am a Computer Engineer (aka nerd), so don't expect\nto see anything like me pondering the wonders of the cosmos here. I'll probably\nmostly post updates on projects I'm fiddling with, my struggles with technology,\nand what I've been up to.\n\nAs you can see, I decided to go with WordPress. I used it a long time ago, but\nafter seeing my roommate [Ben Murrell](http://benmurrell.com/) use it on the [Missouri S&T ACM site](http://acm.mst.edu/)\nand seeing what it was capable of, I went for it. Probably the most important\nthing for me was the ability to have static pages and link to them in a reasonable\nfashion (as you can see along the top and right sidebar). It just does everything\nI want to do without too much fuss, and it looks pretty while it does it.\n\nI'm still moving stuff from my old website and updating information, but feel\nfree to poke around in the meantime.\n"}],"tags":["servers","linux","idd","programming","networking","cooking","beertraq","car","htpc","beer","git","games","ipv6","bike","touring"]} |