Archive for the ‘Nerdery’ Category

Don’t printf when you can tcpdump

Tuesday, November 10th, 2009

I’m working on an app that talks to a web service, and in the course of debugging it’s good to know what exactly is being sent to and from the web server. I had been doing so with the tried and true method of printf() debugging (this is Cocoa, so NSLog() debugging, actually), but it was getting to be a pain:

  1. If I print all network traffic all the time, it overwhelms my console, making it useless for any other kind of output. So instead, I’m constantly inserting or removing NSLog() statements as I work. Not to mention having to reproduce a request because the right logging statements weren’t in place the first time around.
  2. NSURLConnection returns downloaded information as an NSData object, so simply passing it to NSLog() dumps a lot of useless hexadecimal code to the screen. That means I must first create an NSString from the data, print it, then release it. (I can’t use %s, the data isn’t null terminated.)
  3. NSURLConnection does a lot of behind the scenes work, like storing cookies and setting Content-Length headers. That’s nice, but that makes it hard to know exactly what’s being sent on the wire.

And that’s when it occurred to me: why not just watch what’s on the wire? tcpdump is a command line utility which monitors network traffic and prints out packets that you specify.

Here’s the incantation to monitor HTTP traffic to and from a specified host:

sudo tcpdump -l -q -A "host (Specified Host) and tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)"

To explain briefly, sudo runs the command as root, -l enables line buffering, -q hides some of the less interesting protocol information, and -A prints the content of each packet in ASCII. The filtering expression that follows selects packets to or from (Specified Host), to or from port 80, and ignoring SYN, FIN, ACK-only, and other non-data packets. I’ll confess, I don’t understand that last part completely, I copied it from the tcpdump man page.

To make the output a little easier to read, I pipe the output to a Perl script I quickly hacked together which watches for the packet header lines and outputs the ANSI escape codes to render them in bold. But I’ll leave that as an exercise to you, dear reader.

There’s no need to download anything, tcpdump is already installed on your Mac. (I don’t know if it’s part of the standard install or the Developer Tools, but what do you care?)

Now, what would be really sweet is a graphical app to do this. I found Cocoa Packet Analyzer, but it’s a little low-level for me. I don’t care about packet specifics; I’d prefer something that reconstructed the tcp streams in an easy to navigate way.

A Spam Filter for Facebook Events

Friday, October 16th, 2009

I love that Facebook exports events as a calendar that I can subscribe to in Apple iCal or Google Calendar. It saves much copying and pasting. Unfortunately, somebody is almost always creating an event that spans several days. Then my calendar looks like this:

Giant event messing up my calendar

This is annoying, because that purple monster isn’t even a real event; it’s just a notice that somebody’s film is available for download from Amazon. As much as I encourage everybody to watch that film, I don’t want it eating up my calendar. I am routinely invited to events like this, and they are always announcements, or “I’m looking for a roommate,” or “I was too lazy to create four separate events for the show I’m doing four times this month.” In other words, calendar spam.

This would be tolerable, if there were some way to hide individual events, but there isn’t. Facebook includes every event you’ve been invited to, even if you RSVP: Not Attending. You can uninvite yourself using the “Remove from My Events” link, but it’s tedious and doesn’t protect you from being re-invited in the future. It’s also of no use if you’re away from the computer and viewing your calendar on your iPhone.

How to Clean Your Calendar

I solved the problem with a program that acts as a proxy between your calendar app and Facebook, removing events that are longer than 12 hours. It’s on the web, so you can use it, too.

First, find your Facebook Calendar URL by going to Facebook Events and clicking “Export Events” in the top left corner. A box will appear with an address that looks something like this:

http://www.facebook.com/ical/u.php?uid=123456&key=789abcdef

To use the filter, change the first part of the address (everything before the question mark) so that it looks like this:

http://www.benzado.com/bin/icalproxy.php?uid=123456&key=789abcdef

Then you can use the new address to subscribe to your filtered calendar in apps like Apple iCal or Google Calendar.

Note that using my filter means your events pass through my web server, and even though I’m not really interested in looking at them, I could. So if you’re super concerned about your privacy, keep that in mind.

If you’d like to see how the script works or make a copy to run on your own server, you can view the source code. If you extend it in any interesting ways, please let me know.

Avoid defining your iPhone app’s default values in two places

Tuesday, October 6th, 2009

This is a guide to using XSLT to extract default values from your iPhone app’s Settings bundle into a separate property list file. That file can be loaded by your app at runtime, sparing you the need to maintain the same data in two places and avoiding the risk of a mismatch leading to buggy behavior.

(more…)