<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The life and times of Jeffrey Forman. &#187; Open Source/Internet</title>
	<atom:link href="http://blog.jeffreyforman.net/category/open-sourceinternet/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jeffreyforman.net</link>
	<description>That&#039;s my story, and I&#039;m sticking to it.</description>
	<lastBuildDate>Sat, 23 Apr 2011 20:13:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Remind Me: Initial Data in a Django class-based Form</title>
		<link>http://blog.jeffreyforman.net/2011/04/23/remind-me-initial-data-in-a-django-class-based-form/</link>
		<comments>http://blog.jeffreyforman.net/2011/04/23/remind-me-initial-data-in-a-django-class-based-form/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 20:11:22 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=643</guid>
		<description><![CDATA[I love Django&#8216;s class-based way of handling forms. You name the class, articulate each field (data point of your form), and attach it to a view. Voila. But what happens when you want some initial data in the form? Initial &#8230; <a href="http://blog.jeffreyforman.net/2011/04/23/remind-me-initial-data-in-a-django-class-based-form/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.djangoproject.com">Django</a>&#8216;s class-based way of handling <a href="http://docs.djangoproject.com/en/dev/ref/forms/fields/">forms</a>. You name the class, articulate each field (data point of your form), and attach it to a view. Voila. But what happens when you want some initial data in the form?</p>
<p>Initial to the rescue!</p>
<p>What your class might look like:</p>
<pre class="brush: python; title: ; notranslate">
class PersonForm(forms.Form):
    first_name = forms.CharField(max_length=100)
    last_name = forms.CharField(max_length=100)
    gender = forms.CharField(max_length=1)
    hair_color = forms.CharField(max_length=256)
</pre>
<p>If you now wanted to initialize your form for males with blonde hair, include this snippet in your view:</p>
<pre class="brush: python; title: ; notranslate">
form = PersonForm(initial = { 'gender' : &quot;M&quot;, 'hair_color' : &quot;blonde&quot; } )
</pre>
<p>Then pass that form as part of your render return:</p>
<pre class="brush: python; title: ; notranslate">
return render_to_response('add_person.htm', { 'form' : form })
</pre>
<p>This post is brought to you by #neverwantingtosearchtheinternetforthisagain, and StackOverflow for <a href="http://stackoverflow.com/questions/1882616/pass-an-initial-value-to-a-django-form-field">inspiration.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/04/23/remind-me-initial-data-in-a-django-class-based-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boston Barcamp 6, Day Two</title>
		<link>http://blog.jeffreyforman.net/2011/04/17/boston-barcamp-6-day-two/</link>
		<comments>http://blog.jeffreyforman.net/2011/04/17/boston-barcamp-6-day-two/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 22:37:49 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Boston]]></category>
		<category><![CDATA[Open Source/Internet]]></category>
		<category><![CDATA[conferences]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=640</guid>
		<description><![CDATA[Finally got this post out after having a bit of a busy week. &#160; Location based networking, anurag wakhlu (coloci inc) http://goo.gl/mxAtd * location based apps: where are you now? or where will you be? * where are you now: &#8230; <a href="http://blog.jeffreyforman.net/2011/04/17/boston-barcamp-6-day-two/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h4>Finally got this post out after having <a href="http://googleblog.blogspot.com/2011/04/ita-software-acquisition-cleared-for.html">a bit of a busy week</a>.<br />
&nbsp;</p>
<p><strong>Location based networking, anurag wakhlu (coloci inc)</strong><br />
<a href="http://goo.gl/mxAtd"><strong>http://goo.gl/mxAtd</strong></a><br />
* location based apps: where are you now? or where will you be?<br />
* where are you now: foursquare, gowalla, loopt, etc<br />
* where will you be: coloci, fyesa, tripit, plancast<br />
* interest based networking: the reason to talk to someone who is near you. tie an interest: sending someone a coupon when they are near starbucks. if they arent near starbucks, what good is a coupon?<br />
* proactive coupons: dont wait for a check-in. if someone is 2 blocks from starbucks, send them a notification for coupon. ex// minority report. walk by a billboard, recognizes you, tailors ad specifically to you.<br />
52% of US consumers willing to share location for retail perks.<br />
* foursquare background checkin? automatically check you in when you are in a close enough vicinity to a location<br />
* Do privacy concerns have a potential impact on services becoming more popular? ex// European privacy laws about broadcasting who you are, where you are, etc.<br />
* Have to trust your device that when you disallow authority to know your location, it actually does not broadcast where you are.<br />
* Trade off of convenience versus privacy. Debit card is a lot more convenient than cash, people are more than likely to give up privacy.<br />
* If you really want to not be tracked, you really need to disconnect yourself from the computer. Go cash only. Re-education might help. &#8220;You might already be sharing this info somewhere else, so what difference is it now that you do it via your phone?&#8221;<br />
* Tracking someone&#8217;s history via CSS visited tag. Firefox supposedly has fixed this issue where websites cannot do this anymore.<br />
* Using EZpass, who is responsible for giving a ticket if you did 60 miles in faster than 60 minutes? Using your location to know your broke the law.<br />
<em>At the start, Anurag gave a wonderfully succint history of location based networking, highighting the current giants like Foursquare and Facebook Places. We talked about how the potential is there to enable your phone to alert you about consumer deals in your vicinity, having more of a &#8216;push&#8217; aspect to networking, or your phone could alert you to friends being near as well. Eventually though, the attendants turned the talk into a big privacy discussion. Not necessarily as flame-worthy as it could have been, but still talking about how much of our information we want to broadcast and allow to advertisers. Broadcasting location and private information. Could the situation eventually get to the point like Minority Report where your phone is overtly/covertly broadcasting who you are to potential advertisers or other potentially nefarious people.</em></p>
<p><strong>Economics of open source</strong><br />
* reputation is a kind of currency. ancillary benefits of &#8216;being known.&#8217; ex// popular github repo, can get you a book deal, flown to conferences, etc.<br />
* are we cheapening what we do by giving it away? software produces so much cash for people. not everything is oss. still need people to customize it and apply.<br />
* discussion: can donations kill a project? the comptroller decides who gets money, and those who donate time but dont get paid feel slighted, and the project can take a nose dive.<br />
<em>Content of presentation was a bit bland/dry, but the discussion was involved. War story: giving training away for free when a company charges for it. you are hurting the ecosystem by giving it away rather than someone paying for it. This was fairly interesting, delving past the common topic of software being &#8216;free as in beer.&#8217; </em></p>
<p><strong>Interviewing well as a coder round table</strong><br />
* feel okay sitting there for a couple minutes thinking. Dont feel stressed to start writing code right away.<br />
* some questions to ask you to regurgitate syntax. what happens if you get confused between languages.<br />
* design issues &#8220;show us where you would add X feature.&#8221; stylistics versus code syntax.<br />
* code portfolios: employers look at your github profile. see the code you&#8217;ve written. if your code is &#8216;too good&#8217;, employer wants you to find bugs in their code.<br />
* how to practice your whiteboarding skills? codekata: short programming problems.<br />
* asking questions that there is no solution to. can you be an asshole interviewing?<br />
* be prepared for personal questions because employers will google you and find your personal interests<br />
* spin negative questions as positive: what do you see improving in your work environment?<br />
* questions back to employee: what do you hope to improve for our company?<br />
* if you list a skill in your skills list, be ready to whiteboard the code.</p>
<p><strong>Can the internet make you healthier? jason jacobs, runkeeper founder</strong><br />
* convergence of health/athletic data and IT<br />
* virtual coaching: ahead/behind pace, in-app reminders to go faster or slower on their iOS app.<br />
<em>The more data you have over what you&#8217;re doing physically, can help you react. How am I doing against my peers? This was interesting, since Jason sees his company&#8217;s first product &#8216;Run Keeper&#8217; as the jumping off point to more athletic-body sensing applications. The point was raised about what point does the app which suggests a certain pace while running, dance the line of being medical advice. I think it is a good point, that the app needs more information about your health before suggesting a certain distance or pace for exercise. I&#8217;ll be curious myself as I use the app more, how I am improving athletically. </em></p>
<p>Overall, I found the signal-to-noise ratio of the unconference to be very high. For my first Barcamp, I would suggest it to all technically-inclined folks who just want to let their interests and imaginations plot the course of which talks they attend. I know I will be a repeat attendee.</h4>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/04/17/boston-barcamp-6-day-two/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Barcamp Boston 6, Day One</title>
		<link>http://blog.jeffreyforman.net/2011/04/10/barcamp-boston-6-day-one/</link>
		<comments>http://blog.jeffreyforman.net/2011/04/10/barcamp-boston-6-day-one/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 12:13:22 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Boston]]></category>
		<category><![CDATA[Open Source/Internet]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ops]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=633</guid>
		<description><![CDATA[Having never been to a Barcamp before, I knew the overall structure of the conference, but was curious if I would actually like it. Truth be told, I found it full of content, without a lot of fluff, even for &#8230; <a href="http://blog.jeffreyforman.net/2011/04/10/barcamp-boston-6-day-one/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Having never been to a Barcamp before, I knew the overall structure of the conference, but was curious if I would actually like it. Truth be told, I found it full of content, without a lot of fluff, even for the talks I sat in on where I had no prior knowledge. My notes follow, thanks to the great OSX app <a href="http://notational.net/">Notational Velocity</a> hooked up to <a href="http://simplenoteapp.com/">Simplenote</a>. My overall thoughts in italic after each post.:</p>
<p><strong>how to give a presentation people love and learn from</strong><br />
break presentation into 7-10 minute chunks<br />
then transition 7 minutes into the talk to another topic, to keep people&#8217;s attention<br />
insert emotion, a story. rather than just X happened.<br />
<em>(For a talk to be this meta, a presentation about giving presentations, I was not hooked. There weren&#8217;t any real nuggets of information here that made me sit up and say &#8220;Wow, I haven&#8217;t been doing this in the presentation I make.&#8221;)</em></p>
<p><strong>how to run a startup like genghis khan</strong>,<strong> by @wufoo</strong><br />
* work like a nomad<br />
* build an audience first. protect your audience. make the audience part of the show.<br />
* make developers handle support requests. once devs get same question two or three times, they go in and fix the code so they dont get the question again.<br />
<em>(Presenter absolutely killed it. Engaging, fast talking (without mumbling), great slides that presented the information in clear and sometimes humorous ways. Made me think more about engaging the people I am trying to convince to my way of thinking)</em></p>
<p><strong>android developer: war stories and antipatterns</strong><br />
<strong>yoni, lead android dev at scavngr</strong><br />
* dont code splashscreens. more of an iOS thing. if you have to preload data, show a progress bar in the app already open<br />
* dont force orientation (landscape/portrait). support both<br />
* dont assume their screen size. use relative layouts<br />
<em>(I went into this talk curious and with no prior experience or knowledge of writing an Android app. I don&#8217;t even own an Android phone. This was much more a round table, with those devs in the room very willing to share their experiences and war stories. I found they really had good experiential tips, rather than &#8220;This is the best practice&#8221; and moving on.)</em></p>
<p><strong>ask a plasma physics grad student anything</strong><br />
<em>(I must say this was completely over my head. The student at the front of the room, from <a href="http://www.psfc.mit.edu/">MIT&#8217;s Plasma Science and Fusion Center</a>, seemed to know his stuff and was genuienly interested in challenging the audience. What blew me away was the knowledge of the audience, asking very pointed questions with what sounded like real science to back it up.)</em></p>
<p><em></em><strong>building fast websites, making users happy (@jonathanklein)</strong><br />
* google injected 400ms delay into search page, dropped 0.76% searches/users over time.<br />
* phpied.com/the-performance-business-pitch<br />
* faster sites rank better in google. site speed is part of search ranking.<br />
* what&#8217;s load time? server side generation time, client side render time. 80-90% of load time takes place on the client.<br />
* best practices:<br />
* reduce http requests: combine css/js, use image sprites (one download and cut up into multiple images).<br />
* minify css/jss: strip comments out and white space. (yuy, java library). will rename variables into shortest name possible<br />
* gzip all text: html, css, js<br />
* for graphics, use png8 (restricts you to 256 different colors in the image)<br />
* jpegs can be saved at 75% quality<br />
* image compressor: smush.it (from yahoo dev network), lossless compression.<br />
* measuring performance<br />
* google webmaster tools, www.webpagetest.org<br />
* yotta, firebug, yslow, page speed, dynatrace ajax edition<br />
<em>(For an ops guy, I was really interested in this talk. Jonathan blew through his material at break-neck speed, but covered the topics and answered questions without feeling like the talk was broken up. Some really good information through his experiences, and things I would like to dig into more myself.) </em><br />
<strong></strong></p>
<p><strong>nosql round table</strong><br />
* some are relational, others are key value<br />
* redis, redis + resque<br />
* cassandra<br />
* mongodb<br />
* why nosql over mysql? no schema, lack of migrations from version to version. being able to store different things. replication (single threaded)<br />
* keeping mysql in sync with nosql layer about: broadcast updates from mysql over rapidmq(?).  nosql service grabs update from mysql.<br />
* solutions that they discarded:<br />
* cassandra: v0.6, latency spikes between nodes. node would get flagged as awol. cascading failure because data gets rebalanced. use &#8220;hinted handoff&#8221; to prefer the direction of the failover. supposedly better in v0.7. documentation is messy.<br />
* in the cloud or in a dc? mostly EC2. local storage with evs slave.<br />
* search via solr<br />
<em>(Another one where I went in having nothing but curiosity, since noSQL is one of the popular buzz words these days. Very engaged audience who shared war stories, both good and bad, implementing noSQL solutions in their workplaces. Left me with a stalk of websites to dig into.)</em></p>
<p><strong>agile development war stories</strong><br />
* problems it tries to solve: waste. business approach.<br />
* more collab between business and engineering. dont just throw the &#8216;stories&#8217; from biz over the wall.<br />
* focus on testable behavior. how can we test each iteration? should be part of the original story.<br />
* be smaller, quicker, more iterative. ex// dont go off for 18 months planning your solution. business might change underneath you<br />
* people do &#8220;agile but..&#8221; and tend to modify the methodology.<br />
* burn down?<br />
* should tasks stay &lt;1 day? sounds a bit unreasonable, since &#8220;speeding up the server by 20%&#8221; is unable to be done in one day. task size should have a reason.<br />
* average sprint time: 2 weeks<br />
* do a code review before the planning meeting. so estimations on a piece of work can be completed in the meeting. ex// dont trace the code for the 1st time in a meeting.<br />
* software to track scrums/managing stories: soft2, scrum ninja, team foundations studio (windows), white boards, index cards on a wall, ibm rational, pivotal tracker (good for distributed teams), mingle from softworks.<br />
<em>(Another highly-concentrated buzzword round table where I was more curious than anything. Some real good information about what works and what doesn&#8217;t when it comes to managing time and projects. Lots to read up on here, and see if I can apply it to my daily work life.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/04/10/barcamp-boston-6-day-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You go here, you go there. Bending DHCP to your will.</title>
		<link>http://blog.jeffreyforman.net/2011/02/28/you-go-here-you-go-there-bending-dhcp-to-your-will/</link>
		<comments>http://blog.jeffreyforman.net/2011/02/28/you-go-here-you-go-there-bending-dhcp-to-your-will/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 00:31:03 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Open Source/Internet]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=512</guid>
		<description><![CDATA[TL;DR: How to hand out DNS servers in different orders to different clients based upon MAC address. Background: I was connected into my office&#8217;s VPN a few months ago and was noticed some very slow DNS resolution of host names &#8230; <a href="http://blog.jeffreyforman.net/2011/02/28/you-go-here-you-go-there-bending-dhcp-to-your-will/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>TL;DR</strong>: How to hand out DNS servers in different orders to different clients based upon MAC address. </p>
<p><strong>Background</strong>: I was connected into my office&#8217;s VPN a few months ago and was noticed some very slow DNS resolution of host names back at the office. I would attempt to ssh into another host, and the connection would sit there for more than a few seconds before finally proceeding. This didn&#8217;t happen for just ssh, but also for making http requests. I dug into my resolv.conf locally and tried sending a few DNS queries via dig to the two DNS servers I was provided. The first one failed, the second one returned immediately with the correct response. I swapped the two entries and DNS resolution locally was back to where I would expect it, very fast. I alerted our IT group and the issue was fixed (the first DNS server had become hung, and needed a process restart).</p>
<p><strong>Curiosity</strong>: This got me thinking, was everyone suffering my issue? Did the two DNS servers handed out always come in that same order? If so, DNS would have been slow for everyone. We&#8217;d all be timing out trying to query the first server, waiting for our local resolvers to query the second operational server. Could I get a DHCP server to randomize the list of DNS servers to its querying clients?</p>
<p><strong>Assumptions</strong>: I am ignoring the fact that our VPN concentrator might not be running the ISC DHCPD, which my examples are based upon. I will split up each DHCP subnet into two groups, in a binary fashion.</p>
<p><strong>How I did it</strong>: After doing some Google searches, I came across <a href="https://lists.isc.org/pipermail/dhcp-users/2011-February/012784.html">a post on the mailing list for ISC DHCPD users</a>. It explained that you could do some logic on the incoming MAC address, and based upon that, hand out unique information, among it, DNS, routers, domain names, etc.I was curious to see if I could actually get this working.</p>
<p>I figure the easiest way to do this is paste some config data and go from there.</p>
<pre class="brush: plain; title: ; notranslate">
dhcpd.conf:
class &quot;binary-group-0&quot; {
    match if suffix(binary-to-ascii(2, 8, &quot;&quot;, substring(hardware, 6, 1)), 1) = &quot;0&quot;;
}

class &quot;binary-group-1&quot; {
    match if suffix(binary-to-ascii(2, 8, &quot;&quot;, substring(hardware, 6, 1)), 1) = &quot;1&quot;;
}

subnet 10.30.0.0 netmask 255.255.255.0 {
    option routers 10.30.0.1;
    option domain-name &quot;vmtest.jeffreyforman.net&quot;;

    pool {
        allow members of &quot;binary-group-0&quot;;
        range 10.30.0.20 10.30.0.30;
        option domain-name-servers 1.1.1.1, 2.2.2.2;
        on commit {
            execute(&quot;/bin/echo&quot;, &quot;GROUP ZERO&quot;);
        }
    }
    pool {
        allow members of &quot;binary-group-1&quot;;
        range 10.30.0.200 10.30.0.210;
        option domain-name-servers 4.4.4.4, 5.5.5.5;
        on commit {
            execute(&quot;/bin/echo&quot;, &quot;GROUP ONE&quot;);
        }
    }
}
</pre>
<p><strong>Configuration explination</strong>:<br />
On lines 2-8, each named class is populated by clients whose MAC address corresponds to the appropriate &#8216;match&#8217; line. These match do the following: Starting from the 6th byte of the client&#8217;s MAC address, grab one byte of data. Once we have that data, convert the binary data to ascii characters, without a separator using base two, each bit of data being eight bits long. With that data, take a string onecharacter from the end. We have created two classes here, one where the last character is 0 (zero), and the other is 1 (one).</p>
<p>On lines 10-30,we have a standard subnet declaration, with two pools. Each pool (lines 14-20, 21-29) uses the &#8216;allow members of&#8217; to control which class of users from above the pool applies to. In this instance, we hand out two different ranges and sets of domain name servers depending on what class a user belongs. For my own debugging, I stick an &#8216;on commit&#8217; execution in each pool. This outputs in the log when a lease is acquired for a particular client, and gave me some explanation about where I was in the config. These &#8216;on commit&#8217; lines are purely for debugging, and can be removed for production. Clients whose MAC address ends in a binary &#8217;0&#8242;, are placed in the 10.30.0.20-30 range with DNS servers 1.1.1.1 and 2.2.2.2. Those whose MAC address ends in a binary &#8217;1&#8242; are given an address in the 10.30.0.200-210 pool, with DNS servers 4.4.4.4, 5.5.5.5. You could easily put your own DNS servers in this section, modifying the order in any way you please.</p>
<p><strong>Log Output</strong>:<br />
Using a couple of VM&#8217;s on an isolated network at home (and playing with the MAC address of the client), I was able to test my above configuration. Notice on each they are given IP&#8217;s from each appropriate range, with the correct &#8216;echo&#8217; statement being executed.</p>
<pre class="brush: plain; title: ; notranslate">
DHCPDISCOVER from 52:54:00:4c:f3:d4 (testvm1) via re1
DHCPOFFER on 10.30.0.21 to 52:54:00:4c:f3:d4 (testvm1) via re1
execute_statement argv[0] = /bin/echo
execute_statement argv[1] = GROUP ZERO
GROUP ZERO
DHCPREQUEST for 10.30.0.21 (10.30.0.1) from 52:54:00:4c:f3:d4 (testvm1) via re1
DHCPACK on 10.30.0.21 to 52:54:00:4c:f3:d4 (testvm1) via re1

DHCPDISCOVER from 52:54:00:4c:f3:d3 via re1
DHCPOFFER on 10.30.0.201 to 52:54:00:4c:f3:d3 (testvm1) via re1
execute_statement argv[0] = /bin/echo
execute_statement argv[1] = GROUP ONE
GROUP ONE
DHCPREQUEST for 10.30.0.201 (10.30.0.1) from 52:54:00:4c:f3:d3 (testvm1) via re1
DHCPACK on 10.30.0.201 to 52:54:00:4c:f3:d3 (testvm1) via re1
</pre>
<p>Appendix:<br />
For those curious about how I came to breaking up the MAC address of the client, I became painfully familiar with the <a href="http://man.he.net/man5/dhcp-eval">dhcp-eval man page</a>. I honestly would not wish that man page on anyone, it is woefully confusing for someone who does not dabble in DHCPD configuration on a daily basis.</p>
<pre class="brush: plain; title: ; notranslate">
MAC Address: 52:54:00:4c:f3:d3

binary-to-ascii(2, 8, &quot;:&quot;, hardware);
1:1010010:1010100:0:1001100:11110011:11010011

binary-to-ascii(2,8,&quot;.&quot;, substring(hardware,6,1));
11010011

suffix(binary-to-ascii(2, 8, &quot;:&quot;, hardware), 1);
1
</pre>
<p>There you have it. Now you can break up your clients into binary groups, handing them different network information depending on where they fall. Obviously if you want to split them up into more than two groups, the match statements become a bit more verbose for each condition. Ultimately this would not have solved my problem of being given a &#8216;bad&#8217; DNS server first in line for my request (since my MAC address would always be the same), but it does spread the load among DNS servers over local clients. I am now curious, when I get the free time, to play around with creating an on-commit-like command that based upon its execution (generate a random number for example), changes the order of DNS servers handed out to clients.</p>
<p>References:</p>
<ul>
<li>http://easycalculation.com/hex-converter.php</li>
<li>http://www.linuxmanpages.com/man5/dhcpd.conf.5.php</li>
<li>https://lists.isc.org/pipermail/dhcp-users/2011-February/012784.html</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/02/28/you-go-here-you-go-there-bending-dhcp-to-your-will/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remind me: Configuring BIND9 plugin for Munin on FreeBSD</title>
		<link>http://blog.jeffreyforman.net/2011/01/30/remind-me-configuring-bind9-plugin-for-munin-on-freebsd/</link>
		<comments>http://blog.jeffreyforman.net/2011/01/30/remind-me-configuring-bind9-plugin-for-munin-on-freebsd/#comments</comments>
		<pubDate>Sun, 30 Jan 2011 16:33:24 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Open Source/Internet]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[munin]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=482</guid>
		<description><![CDATA[I was attempting to get Munin working on a new FreeBSD machine, monitoring the rate of queries to a Bind9 DNS server. Every time I attempted &#8216;munin-run bind9&#8242; I was presented with the same error: Digging around in the Bind9 &#8230; <a href="http://blog.jeffreyforman.net/2011/01/30/remind-me-configuring-bind9-plugin-for-munin-on-freebsd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was attempting to get Munin working on a new FreeBSD machine, monitoring the rate of queries to a Bind9 DNS server. Every time I attempted &#8216;munin-run bind9&#8242; I was presented with the same error:</p>
<pre class="brush: plain; title: ; notranslate">
2011/01/29-18:09:55 [3581] Error output from bind9:
2011/01/29-18:09:55 [3581]     Died at /usr/local/etc/munin/plugins/bind9 line 41.
2011/01/29-18:09:55 [3581] Service 'bind9' exited with status 2/0.
</pre>
<p>Digging around in the Bind9 Munin plugin, line 41 complains about a state file that Munin uses. The plugin immediately tries to open the state file, without checking if the file is actually present. (TODO: Check to see what ramifications there are to just creating the file if it is not present.)</p>
<p>Line 41:</p>
<pre class="brush: plain; title: ; notranslate">
    open(Q,&amp;quot;&amp;lt; $STATEFILE&amp;quot;) or die;
</pre>
<p>After digging around to figure out the plugin state directory (/var/munin/plugin-state, for those following along at home), I was back in business.</p>
<pre class="brush: plain; title: ; notranslate">
[root@dns1 ~]# cd /var/munin/plugin-state
[root@dns1 /var/munin/plugin-state]# touch bind9.state
[root@dns1 /var/munin/plugin-state]# chgrp munin bind9.state
[root@dns1 /var/munin/plugin-state]# chmod g+rw bind9.state
[root@dns1 /var/munin/plugin-state]# ls -al
total 4
drwxrwxr-x  2 nobody  munin  512 Jan 29 18:13 .
drwxr-xr-x  3 munin   munin  512 Jan 29 14:47 ..
-rw-rw-r--  1 root    munin    0 Jan 29 18:13 bind9.state
</pre>
<p>Relevant bind named.conf stanza for query logging:</p>
<pre class="brush: plain; title: ; notranslate">
logging {
  channel default_queries {
    file &amp;quot;/var/log/queries.log&amp;quot; versions 3 size 500k;
    severity info;
    print-severity yes;
    print-category yes;
    print-time yes;
  };
  category queries { default_queries; };
};
</pre>
<p>With that, &#8216;munin-run bind9&#8242; worked. I restarted the munin-node process and queries are now being graphed as expected.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/01/30/remind-me-configuring-bind9-plugin-for-munin-on-freebsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Munin monitoring your SB6120 Comcast Cable Modem</title>
		<link>http://blog.jeffreyforman.net/2011/01/08/munin-monitoring-your-sb6120-comcast-cable-modem/</link>
		<comments>http://blog.jeffreyforman.net/2011/01/08/munin-monitoring-your-sb6120-comcast-cable-modem/#comments</comments>
		<pubDate>Sun, 09 Jan 2011 01:35:35 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=470</guid>
		<description><![CDATA[For those who have spent time debugging their Comcast Internet connection, we all know the frustration of trying to explain to Comcast that something on their end is the problem. In this case, more data is better: latency history, ping &#8230; <a href="http://blog.jeffreyforman.net/2011/01/08/munin-monitoring-your-sb6120-comcast-cable-modem/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">For those who have spent time debugging their Comcast Internet connection, we all know the frustration of trying to explain to Comcast that something on their end is the problem. In this case, more data is better: latency history, ping times, traceroutes, etc. You can run <a href="http://oss.oetiker.ch/smokeping/">Smokeping</a> to monitor latency between your home connection and a remote Internet IP address for example. You can also print out traceroute examples and email them if you have an astute support contact. But if you want to monitor the data your cable modem is seeing, you need to look at the signal to noise ratio of your connection. This ratio refers to how much of your signal has been disturbed by noise on the physical line (<a href="http://en.wikipedia.org/wiki/Signal-to-noise_ratio">Thanks Wikipedia</a>). Newer cable modems will use multiple channels along the same line to increase your download and upload speed, and each channel can be disturbed independently.</p>
<p style="text-align: justify;">Enter Munin, an RRD-graph based tool that creates easy to understand (for the most part) graphs of data over time. Munin plugins can be written to scrape any data you are able to programatically retrieve and whip it into a pretty graph. The <a href="https://github.com/jforman/munin-surfboard6120">plugin I wrote</a> for Munin scrapes the data from a Motorola Surfboard SB6120 modem&#8217;s status page, and presents it in an easy-to-digest format for Munin. Previous Munin plugins handled the old SB4120 and SB5120 modems. These are old DOCSIS 2.0 products, and therefore the status page has evolved, and displays the connection data in a way where the old plugin does not work on the SB6120 modem.</p>
<p style="text-align: justify;">Without further adieu, the graph produced by my plugin is:<br />
<a href="http://blog.jeffreyforman.net/wp-content/uploads/2011/01/surfboard6120_snr-week.png" rel="lightbox[470]" title="surfboard6120_snr-week"><img class="aligncenter size-medium wp-image-471" title="surfboard6120_snr-week" src="http://blog.jeffreyforman.net/wp-content/uploads/2011/01/surfboard6120_snr-week-300x197.png" alt="" width="342" height="224" /></a>The graph shows the various downstream and upstream channels, graphing the signal-to-noise ratio dB (decibel) of each respective channel.  Suggested values for Comcast in particular can be found in a <a href="http://www.broadbandreports.com/faq/16085">FAQ entry from Broadband Reports</a>. These are just suggestions, and different values will have different effects on your Internet connection. A severe dip in the graph could correspond to your modem being unable to stay sycned with Comcast&#8217;s infrastructure, which translates to an unstable Internet connection.</p>
<p style="text-align: justify;">Installation instructions follow common Munin plugin practices, by creating the plugin (or a symlink to the plugin) in the /etc/munin/plugins/ directory to the plugin code. Mine is written in Python, so a basic Python install is required on your machine. Source can be found can be found in my <a href="https://github.com/jforman/munin-surfboard6120">munin-surfboard6120 repo</a> on <a href="http://www.github.com">Github</a>.</p>
<p style="text-align: justify;">Enjoy! (Comments/criticisms are welcomed to improve the usefulness of this plugin)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2011/01/08/munin-monitoring-your-sb6120-comcast-cable-modem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Am Lazy: Python, to convert a file&#8217;s age in seconds since epoch to a readable format</title>
		<link>http://blog.jeffreyforman.net/2010/12/17/i-am-lazy-python-to-convert-a-files-age-in-seconds-since-epoch-to-a-readable-format/</link>
		<comments>http://blog.jeffreyforman.net/2010/12/17/i-am-lazy-python-to-convert-a-files-age-in-seconds-since-epoch-to-a-readable-format/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 14:55:03 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=468</guid>
		<description><![CDATA[For my own lazyness, so I don&#8217;t need to hunt for this damn chain of syntax. >>> time.strftime(&#8220;%Y%m%d-%H%M.%S&#8221;, time.gmtime(os.path.getctime(&#8220;$path_to_file&#8221;))) &#8217;20101213-1948.58&#8242;]]></description>
			<content:encoded><![CDATA[<p>For my own lazyness, so I don&#8217;t need to hunt for this damn chain of syntax.</p>
<p>>>> time.strftime(&#8220;%Y%m%d-%H%M.%S&#8221;, time.gmtime(os.path.getctime(&#8220;$path_to_file&#8221;)))<br />
&#8217;20101213-1948.58&#8242;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2010/12/17/i-am-lazy-python-to-convert-a-files-age-in-seconds-since-epoch-to-a-readable-format/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Howto: Git, hooks, Nagios, oh my.</title>
		<link>http://blog.jeffreyforman.net/2010/11/16/howto-git-hooks-nagios-oh-my/</link>
		<comments>http://blog.jeffreyforman.net/2010/11/16/howto-git-hooks-nagios-oh-my/#comments</comments>
		<pubDate>Wed, 17 Nov 2010 03:35:11 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=424</guid>
		<description><![CDATA[At work we have a monitoring configuration workflow where our Nagios config files are parsed and generated before they are allowed to be &#8216;svn commit&#8217;ed. I know this verification has saved me many times when trying to add new hosts &#8230; <a href="http://blog.jeffreyforman.net/2010/11/16/howto-git-hooks-nagios-oh-my/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At work we have a monitoring configuration workflow where our Nagios config files are parsed and generated before they are allowed to be &#8216;svn commit&#8217;ed. I know this verification has saved me many times when trying to add new hosts or services, since everything might not be ready for prime time. I wanted to see if I could recreate this scenario at home using Git hooks, if only for my own interest and curiosity.</p>
<p>My proposed workflow: Start with a local clone of the Nagios configs. Add a host,  service, or contact to a local nagios Config file. Git commit locally. Git push to the remote repo on the monitoring box. The Nagios config parser would run remotely verifying the syntactic-correctness of the proposed-check in. If these checks fail, reject the push. If parsing succeeds, accept the push, and restart Nagios (hence reloading the new configs). I wanted to alleviate the need for an admin to log into the monitoring machine at all. This would eliminate the need to add sudo permissions to a group of users to allow them to restart the Nagios service.</p>
<p>Without further delay, on to the code. The first piece, was the pre-receive hook with Git. I used this hook specifically because it has the power to accept or reject a push.</p>
<p>Behold, $git_repo/.hooks/pre-receive:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
while read OLD_SHA1 NEW_SHA1 REFNAME; do
 export GIT_WORK_TREE=/tmp/nagiosworkdir
 /usr/bin/git checkout -f $NEW_SHA1
 sed -i &quot;s|cfg_dir=CHANGEWITHGIT|cfg_dir=${GIT_WORK_TREE}\/config|g&quot; $GIT_WORK_TREE/nagios.cfg
 sudo -u root /bin/chgrp -R nagios $GIT_WORK_TREE
 sudo -u root /usr/sbin/nagios3 -v $GIT_WORK_TREE/nagios.cfg &gt; $GIT_WORK_TREE/check.out
 NAGIOS_CHECK_STATUS=$?
 echo &quot;Nagios Config Check Exit Status:&quot; $NAGIOS_CHECK_STATUS
 if [ &quot;$NAGIOS_CHECK_STATUS&quot; -ne 0 ]
   then
   echo &quot;Your configs did not parse correctly, there was an error. Output follows.&quot;
   cat $GIT_WORK_TREE/check.out
   exit 1
 else
   echo &quot;Your configs look good and parsed correctly.&quot;
   exit 0
 fi
done
</pre>
<p>The operations here flow from checking out the pending push to a &#8216;temporary directory&#8217; (explained below), and then making a slight modification to the nagios.cfg to handle our temp configs being somewhere other than the Nagios install directory. This is needed since we want to parse our configs, and not the ones currently in-use on the machine. After this is done, we parse the output of that check, and based upon that output, either accept or reject the push. In the case of a rejection, the output of the verification is printed for the user to see. This output is pretty clear when explaining where the error is.</p>
<p>And now the post-receive:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
cd /etc/nagios3/testing
/usr/bin/env -i /usr/bin/git pull
echo &quot;Restarting Nagios now&quot;
sudo -u root /usr/sbin/service nagios3 restart
</pre>
<p>The post-receive happens after the entire process is done [1]. We change into the directory of the Git clone of your monitoring config repository. which itself is inside /etc/nagios3, and execute a &#8216;git pull.&#8217; The need to wrap it around &#8216;env&#8217; is because of an issue I also learned in this process. [2] The GIT_DIR directory is set to the directory of your repository. In this case, we must change to another directory on this machine, which is outside of our initial Git repo. Therefore we must &#8216;unset&#8217; this variable, which is what the &#8216;env&#8217; execution does.</p>
<p>This is pretty straightforward for the most part. The part of the process new to me was the GIT_WORK_TREE. I received a a pretty simple explanation from the <a href="https://github.com/sitaramc/gitolite">author of Gitolite</a>. He explained that the work tree directory is a directory where the potential new commit can be checked out before it is actually allowed to be pushed into the remote repository. Essentially, the opposite of a bare repository. The reason I do this is because I want to do the parsing check before I actually allow the push. I can&#8217;t &#8216;git pull&#8217; the new repository directly into the Nagios configuration directory before it is actually committed. GIT_WORK_TREE allows this intermediary functionality.</p>
<p>The reasoning for the &#8216;sed&#8217; modification in that file is that since I will be checking-out the intermediary files into a new directory, I need a Nagios config file that references this intermediary directory. How did I get around this? I copied the nagios.cfg file I would run my install with into the repo, and changed the cfg_dir directory to something I can easily modify during the check in (cfg_dir=CHANGEWITHGIT). This file is not expected to be used on the actual server, so do not copy this one over your actual Nagios.cfg file.</p>
<p>The chgrp magic is because the user who runs the Nagios application must have read access to the configuration files.</p>
<p>Relevant sudoers lines needed:</p>
<pre class="brush: plain; title: ; notranslate">
git ALL=(ALL) NOPASSWD: /bin/chgrp -R nagios /tmp/nagiosworkdir
git ALL=(ALL) NOPASSWD: /usr/sbin/nagios3 -v /tmp/nagiosworkdir/nagios.cfg
git ALL=(ALL) NOPASSWD: /usr/sbin/service nagios3 restart
</pre>
<p>The three lines above are as such. (1) Allow the git user to, without a password, change the group of the temporary Nagios work dir. (2) Allow the git user to, without password, run the verification of the to-be-committed files. (3) Actually restart the Nagios service.</p>
<p>A successful commit, including a restart of Nagios looks like the following:</p>
<pre class="brush: plain; title: ; notranslate">
jforman@merlot:~/devel/testing/config$ git commit . &amp;&amp; git push
[master 2f796e3] testing for the blog post
 1 files changed, 1 insertions(+), 1 deletions(-)
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 394 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Previous HEAD position was ca6dd74... fix now
remote: HEAD is now at 2f796e3... testing for the blog post
remote: Nagios Config Check Exit Status: 0
remote: Your configs look good and parsed correctly.
remote: From /home/git/repositories/testing
remote:    ca6dd74..2f796e3  master     -&gt; origin/master
remote: Updating ca6dd74..2f796e3
remote: Fast-forward
remote:  config/contacts_nagios2.cfg |    2 +-
remote:  1 files changed, 1 insertions(+), 1 deletions(-)
remote: Restarting Nagios now
remote:  * Restarting nagios3 monitoring daemon nagios3
remote:
remote:    ...done.
To git@monitor:testing.git
   ca6dd74..2f796e3  master -&gt; master
</pre>
<p>This was definitely an eye-opening learning process for me into all the moving parts of Git. I hope this Howto helps those out there looking for a solution like this. Enjoy!</p>
<p>Addendum:</p>
<p>For those wondering about the various permissions of the git_work_tree directory and also the repo checkout inside /etc/Nagios3:</p>
<p>monitor:/tmp/nagiosworkdir</p>
<pre class="brush: plain; title: ; notranslate">
drwxrwxr-x  3 git  nagios  4096 2010-11-16 16:13 nagiosworkdir
</pre>
<p>monitor:/etc/nagios3/testing</p>
<pre class="brush: plain; title: ; notranslate">
drwxr-xr-x  4 git  nagios  4096 2010-11-15 08:36 testing
</pre>
<p>[1] <a href="http://progit.org/book/ch7-3.html">http://progit.org/book/ch7-3.html</a></p>
<p>[2] <a href="http://debuggable.com/posts/git-tip-auto-update-working-tree-via-post-receive-hook:49551efe-6414-4e86-aec6-544f4834cda3">http://debuggable.com/posts/git-tip-auto-update-working-tree-via-post-receive-hook:49551efe-6414-4e86-aec6-544f4834cda3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2010/11/16/howto-git-hooks-nagios-oh-my/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Network printing at home, over-engineered.</title>
		<link>http://blog.jeffreyforman.net/2010/09/26/network-printing-at-home-over-engineered/</link>
		<comments>http://blog.jeffreyforman.net/2010/09/26/network-printing-at-home-over-engineered/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 00:52:11 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=393</guid>
		<description><![CDATA[Compared to most other home networks, mine is a bit more complicated. I admit networking has always been an interest of mine, so I run my own OpenBSD firewall/router/vpn-endpoint, which itself runs the ISC Dhcpd v3 and BIND. With these &#8230; <a href="http://blog.jeffreyforman.net/2010/09/26/network-printing-at-home-over-engineered/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Compared to most other home networks, mine is a bit more complicated. I admit networking has always been an interest of mine, so I run my own OpenBSD firewall/router/vpn-endpoint, which itself runs the ISC Dhcpd v3 and BIND. With these together, I am able to run dynamic DNS. But some background first.</p>
<p>Insert my 11-year old <a href="http://h10010.www1.hp.com/wwpc/us/en/sm/WF10a/18972-18972-3328059-14638-3328069-25469.html?jumpid=reg_R1002_USEN">HP2100m</a> printer that I have outfitted with an <a href="http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=bpj06555&amp;locale=en_US&amp;taskId=115&amp;prodSeriesId=27347&amp;prodTypeId=18972">HP Jetdirect 610N 10/100 internal print server</a>. This allows me to stick this printer on my network and print away, no intermediary required. What does this save? The printer is not tied to one computer&#8217;s parallel/USB port. I can shut off my main desktop, and still print over the network.</p>
<p>The next problem: Who wants to print to 10.10.0.205? Hard coding an IP address into the printer config is just asking for bad news, especially with DHCP involved. Better yet, if I shut off the printer for a week, its DHCP lease could expire, and upon restarting the printer, it could grab 10.10.0.215. Now I have to go around and fix my printer config, my wife&#8217;s, and all the other devices.</p>
<p>Enter dynamic DNS:</p>
<p>Snippet from /etc/dhcpd.conf:</p>
<pre class="brush: bash; title: ; notranslate">
# Dynamic Updates
ddns-updates on;
ddns-update-style interim;

host hp2100m {
    hardware ethernet 00:01:e6:23:df:4f;
    ddns-hostname &quot;hp2100m&quot;;
}
</pre>
<p>Here we see I have specified the MAC address of the print server and the dynamic dns host name. According to <a href="http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/">the page which I stole most of the information from</a>, you can specify a ddns-domain-name as well. When trying to do that, I recieved the following error:</p>
<pre class="brush: bash; title: ; notranslate">
/etc/dhcpd.conf line 60: semicolon expected.
ddns-domain-name &quot;home.jeffreyforman.net&quot;
</pre>
<p>Even with the semicolons present, I still need to tinker around with that line and figure out why I can&#8217;t set the domain name explicitly. I can only assume the domain name is deduced according to the layer 3 subnet which the printer is on.</p>
<p>Now you need the BIND configuration from <em>named.conf</em></p>
<pre class="brush: plain; title: ; notranslate">
zone &quot;home.jeffreyforman.net&quot; IN {
 type master;
 file &quot;master/db.home.jeffreyforman.net&quot;;
 allow-update { key &quot;ddns-key&quot;; };
};

zone &quot;0.10.10.in-addr.arpa&quot; IN {
 type master;
 file &quot;master/db.10.10.0&quot;;
 allow-update { key &quot;ddns-key&quot;; };
};
</pre>
<p>These are the forward and reverse DNS respectively. Using a shared key, this enables only the allowed DHCPd to enable DNS records on this particular BIND server.</p>
<p>Snippet from daemon log:</p>
<pre class="brush: plain; title: ; notranslate">
Sep 24 08:29:12 formangate dhcpd: DHCPDISCOVER from 00:01:e6:23:df:4f via vr1
Sep 24 08:29:13 formangate dhcpd: DHCPOFFER on 10.10.0.205 to 00:01:e6:23:df:4f (hp2100m) via vr1
Sep 24 08:29:18 formangate dhcpd: Added new forward map from hp2100m.home.jeffreyforman.net to 10.10.0.205
Sep 24 08:29:18 formangate dhcpd: added reverse map from 205.0.10.10.in-addr.arpa to hp2100m.home.jeffreyforman.net
Sep 24 08:29:18 formangate dhcpd: DHCPREQUEST for 10.10.0.205 (10.10.0.1) from 00:01:e6:23:df:4f (hp2100m) via vr1
Sep 24 08:29:18 formangate dhcpd: DHCPACK on 10.10.0.205 to 00:01:e6:23:df:4f (hp2100m) via vr1
</pre>
<p>This shows the DHCP server interacting with the printer, and then sending the new forward and reverse DNS mappings to the DNS server.</p>
<p>I can now ping hp2100m from machines at home, and configure all printing to use that hostname, no matter what IP address it points to.</p>
<pre class="brush: plain; title: ; notranslate">
jforman@server1f:~$ ping hp2100m
PING hp2100m.home.jeffreyforman.net (10.10.0.205) 56(84) bytes of data.
64 bytes from hp2100m.home.jeffreyforman.net (10.10.0.205): icmp_seq=1 ttl=64 time=5.69 ms
</pre>
<p><em>*Note: The configuration snippets above are not complete, and will require other information to complete this roll out and enable Dynamic DNS.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2010/09/26/network-printing-at-home-over-engineered/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New and Shiny &#8211; Comcast IPv6</title>
		<link>http://blog.jeffreyforman.net/2010/07/25/new-and-shiny-comcast-ipv6/</link>
		<comments>http://blog.jeffreyforman.net/2010/07/25/new-and-shiny-comcast-ipv6/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 02:13:52 +0000</pubDate>
		<dc:creator>Jeff Forman</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Open Source/Internet]]></category>

		<guid isPermaLink="false">http://blog.jeffreyforman.net/?p=373</guid>
		<description><![CDATA[A few months ago Comcast began publicizing their IPv6 trials for their customers. For those who don&#8217;t have a lot of spare time, IPv6 is the next addressing system for the Internet. Currently IPv4 is the predominant addressing system, akin &#8230; <a href="http://blog.jeffreyforman.net/2010/07/25/new-and-shiny-comcast-ipv6/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A few months ago <a href="http://www.comcast.net">Comcast</a> began publicizing their <a href="http://www.comcast6.net">IPv6 trials</a> for their customers. For those who don&#8217;t have a lot of spare time, <a href="http://en.wikipedia.org/wiki/IPv6">IPv6</a> is the next addressing system for the Internet. Currently <a href="http://en.wikipedia.org/wiki/IPv4">IPv4</a> is the predominant addressing system, akin to a phone number. With the growing number of people using the global Internet, these numbers are bound to run out. Various predictions have put this exhaustion anywhere from tomorrow to a hundred years from now for that Internet-apocalypse to arrive. IPv6 among other things, offers a near limit-less number of addresses (2^128 for the curious).</p>
<p>Comcast, loved or hated, started IPv6 trials on their own network, turning up customers on their (trial?) IPv6 network. Since IPv6 is not in widespread use today, and not all destinations on the Internet can handle v6 requests, there are several stop-gap solutions. One of them is IPv6 6RD, where RD stands for &#8220;Rapid deployment.&#8221; From my little understanding, this allows Comcast customers to encapsulate v6 traffic inside v4 packets through Comcast&#8217;s network to the IPv6-enabled destinations.</p>
<p>Without further wait, this is how I did it (save the several weeks of headbanging frustration that ensued):</p>
<p>Comcast provides their customers with some network addressing information:</p>
<pre class="brush: plain; title: ; notranslate">
IPv6 prefix = 2001:55c::/32
6rd BR FQDN = 6rd.comcast.net
IPv4 prefix length = 0&lt;/pre&gt;
</pre>
<p>Having only a very cursory knowledge of IPv6 addressing, I stumbled my way through the configuration. The IPv6 prefix is used to determine the breadth of Comcast&#8217;s v6 network, which octets are network bits, and what bits are host bits. The BR FQDN (border router, fully qualified domain name) is the IPv4 hostname for the gateway in which my firewall will connect to reach the &#8220;v6 Internet.&#8221; IPv6 packets are encapsulated inside v4 packets, and passed through this border router for further transit.</p>
<p>On to the configuration. First off, I use <a href="http://www.openbsd.org">OpenBSD</a> 4.7 on my firewall/router. It runs on a <a href="http://www.netgate.com/product_info.php?cPath=60_88&amp;products_id=650">little embedded box</a>, using <a href="http://openbsd.org/faq/pf/index.html">pf</a> as the firewall packet filter.</p>
<p>First we must set some system variables via sysctl (via command line and commit to /etc/sysctl.conf):</p>
<pre class="brush: plain; title: ; notranslate">
net.inet6.ip6.accept_rtadv=0
net.inet6.ip6.forwarding=0
</pre>
<p>These two variables tell your machine not to accept router advertisements (don&#8217;t act like a DHCP client accepting network configuration), and the second one tells your machine not to forward IPv6 packets. v6 unlike v4, for the most part, obviates the need for NAT. Therefore if this value were &#8217;1&#8242;, you would be forwarding v6 traffic from the external Internet to all v6-enabled devices on your home network. Unless you really intend to open up your home network to the entire Internet, keep this value as 0 for now.</p>
<p>I created a little shell script that creates the tunnel interface (gif0), and then configures the interface and default routes.</p>
<pre class="brush: plain; title: ; notranslate">
#!/bin/sh -x
WANIP=`ifconfig vr0 | grep -v inet6 | grep inet | awk '{print $2}'`
HOSTRD=`host 6rd.comcast.net | awk '{print $4}'`
V6PREFIX=`printf '%02x%02x:%02x%02x' $(echo $WANIP | tr . ' ')`
ifconfig gif0 destroy
ifconfig gif0 create
ifconfig gif0 tunnel ${WANIP} ${HOSTRD}
ifconfig gif0 inet6 2001:55c:${V6PREFIX}::1 prefixlen 32
ifconfig gif0 up
route -n add -inet6 default ::1 -ifp gif0
</pre>
<p>The nasty bits are mostly in the first three variables.<br />
<em>WANIP</em> is the external IPv4 IP of my firewall<br />
<em>HOSTRD</em> is the IPv4 IP of Comcast&#8217;s IPv6 border router<br />
<em>V6PREFIX</em>: This takes WANIP and converts the IP into its hexadecimal equivalent. This is the format used in IPv6 addresses, and will make up the rest of my personal IPv6 prefix.</p>
<p>Most of the script is self explanatory, and large chunks are stolen from others on the Comcast IPv6 message boards. I have set my external IPv6 tunnel interface to $prefix::1, and set the route for all IPv6 traffic to go out over the gif0 tunnel interface.</p>
<p>At this point, if pf is disabled (therefore allowing all packets through to your machine), you should be able to ping6/traceroute6 to various IPv6-enabled Internet sites. These include ipv6.google.com, www.kame.net and ipv6.comcast.net.</p>
<pre class="brush: plain; title: ; notranslate">
# traceroute6 ipv6.google.com
traceroute6: Warning: ipv6.l.google.com has multiple addresses; using 2001:4860:800f::63
traceroute6 to ipv6.l.google.com (2001:4860:800f::63) from 2001:55c:MY:PREFIX::1, 64 hops max, 12 byte packets
1  2001:55c:MY:PREFIX::1  21.491 ms  19.103 ms  22.759 ms
2  2001:558:e0:52::1  20.734 ms  19.227 ms  16.623 ms
3  2001:558:e0:24::1  17.903 ms  18.821 ms  19.193 ms
4  te-0-3-0-4-cr01.newyork.ny.ibone.comcast.net  21.704 ms  23.512 ms  24.715 ms
5  pos-1-12-0-0-cr01.mclean.va.ibone.comcast.net  27.821 ms  41.616 ms  31.4 ms
6  pos-0-3-0-0-pe01.ashburn.va.ibone.comcast.net  25.451 ms  34.823 ms  25.43 ms
7  2001:558:0:f749::2  29.801 ms  39.119 ms  33.211 ms
8  Vlan22.icore1.AEQ-Ashburn.ipv6.as6453.net  34.592 ms  36.29 ms  33.039 ms
9  pr61.iad07.net.google.com  34.766 ms  34.493 ms  39.389 ms
10  2001:4860::1:0:9ff  34.941 ms  35.911 ms  32.12 ms
11  2001:4860:0:1::149  37.298 ms 2001:4860:0:1::14b  48.993 ms 2001:4860:0:1::149  37.446 ms
12  iad04s01-in-x63.1e100.net  36.593 ms  31.367 ms  33.089 ms&lt;/pre&gt;
</pre>
<p>This post only involves getting your gateway machine speaking IPv6. I have been able to wire up the rest of my internal LAN using <a href="http://www.openbsd.org/cgi-bin/man.cgi?query=rtadvd&amp;sektion=8">rtadvd</a>, and allow them IPv6 access. There are a lot more pieces here, including rtadvd and packet filtering that I don&#8217;t quite fully understand yet how they all interact, and will require another post.</p>
<p><strong>Added update</strong><br />
To use tcpdump to watch IPv6 traffic: <code>tcpdump -i $interface ip6 </code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffreyforman.net/2010/07/25/new-and-shiny-comcast-ipv6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

