Sunday, February 24, 2008

Mad card

During my "add network" testing, I screwed up the command a couple of times by putting the network key in the wrong place. This effectively put random gunk in the "key length" field and caused all sorts of fun. The card got a bit warm and eventually, I got this in the logs:

[08:51] IEEE 802.1X RX: version=1 type=3 length=95
[08:51] EAPOL-Key type=254
[08:51] WPA: RX message 1 of 4-Way Handshake from 00:11:95:18:... (ver=1)
[08:51] WPA: Sending EAPOL-Key 2/4
[08:53] Disconnected from WLAN (reason = 4).
[08:53] Done scanning for new photos. Uploads not pending.
[08:53] EAPOL-Key type=254
[08:54] Done scanning for all photos. Uploads not pending.
[08:54] Connection dropped (previous state is 2)
[08:54] Connecting to WLAN "bcdefghijkl"...
[00:00] Eye-Fi firmware 1.0741 Feb 15 2008 17:13:41 started, hardware revision 1, 2016768/32768 KB storage.
[00:00] Card was reset due to an exception or assertion failure at PC = 0x800029f4. Dump saved.
[00:03] 11216 bytes allocated, 34524 bytes free (34524 bytes largest)
[00:03] Card is in online and desktop transfer mode (timestamp 1203796494).
I wonder if it needs a bit more sanity checking when it is parsing network add data. Although, I can't really fault it for having trouble when I poke basically random data into it. It's really cool that it does recover so nicely.

In any case, I do have add network working quite reliably now.

Dump Log Command

If your EyeFi card is malfunctioning and you contact support, they'll likely ask you to dump the card's log. You can do this from the tray icon in Windows.

The first step in dumping a log is issuing an 'o' command. The 'o' command is the EyeFi's own ioctl(). It is a multiplexed command that can do several things depending on the byte after the 'o'. 0x1 seems to fetch the card's MAC address, for instance. An "o 0x7" command is always issued right before the log is dumped. It always (as far as I have seen) returns 0x00010000. That happens to be the length of the log: ~64k. But, the RSPM file is only 16k in length. So, how do we dump a 64k log 16k at a time?

'm' is the log dump command. It looks like this:
struct dump_log {
char cmd; // 'm'
u32 offset;
};
The card's MIPS cpu runs in big-endian mode (MIPS is bi-endian), so that offset needs to be byte-swapped if you're running the control software on an x86 machine.

The result in RSPM is all ASCII, except for the first 8 bytes for offset 0; I thought these were garbage for a while, but when I started comparing the logs to those obtained from Windows I realized that my logs were shifted around. The end of my logs didn't contain the latest entry; it was somewhere in the middle. It turns out that those first 8 bytes are actually two 4-byte numbers giving two offsets into the log data. The log data returned from this command are actually a circular buffer and those 8 bytes specify its start and end. The log file actually begins and ends in the middle of the buffer. So, the data that comes back from the card after issuing 4 of those 'm' commands looks like this:
struct log_buf {
u32 log_end_offset;
u32 log_start_offset;
char data[16384*4-8];
};
There was one last thing. The logs I got back were a bit smaller than the Windows logs. That's because, coming back from the card, the data has UNIX-style carriage returns. But, the manager turns them into DOS-style before writing the file.

Add Network Working

As I said, I've been playing with Chris Davies' software a bit. I just got the 'a' command working for the first time, which is the add network command. It's a lot more simple than I thought a first. It's a real advantage decoding this stuff when you have so much smart logic on the card.

Most of what we first thought were complex encodings for adding the card appear to really just be garbage left in memory from previous operations. Even watching the Windows software after a log is dumped, you sometimes see the log data come back in the results of subsequent commands. This makes things a bit harder to decode and it would be really nice if the card zeroed things out, first.

Anyway, in the case of add network, the command is a struct like this:
struct add_net {
char cmd; // always 'a'
char net_name_len;
char net_name[32]; // always null padded
char net_password_len;
char net_password_hex[32];
};
Notice that there isn't a field for the encryption type, channel, MAC address of the AP or anything. The card evidently figures this all out internally, which is really nice.

Oh, and you know how you actually have to let the manager software successfully test for a network before you can add it? I think that's a bit of a disadvantage sometimes. Like if you're going over to your Aunt Betty's house and you know her essid before you go, you can't program it into the card in advance. You would need to be there before you can add it. This is a pretty user-friendly feature because it ensures that people don't mistakenly add networks and get confused about why it never works when they just entered the password wrong. I think generally this is way nicer than what I have on my desktop today.

Well, that feature looks to actually be implemented in the manager software, not the card. I believe you can just issue an 'add' command to the card without actually testing it, first. The manager software just happens to always test it in advance. It might be nice to have a "force-add" feature in the future.

Friday, February 22, 2008

The lights go on

OK, I've been stabbing in the dark on the OS all day, but I think I have it now. No, really. Really.
Check out this Atheros Bulletin. Atheros provides eCos for the ar6001 chips and they call it "eCOS BSP - Basic Kernel." There are references to the "BSP version AR6000-..." in the firmware *and* eCos has a 'devfs'. Then, there's this post from Berend about using lwIP with eCos.

Any eCos hackers out there?

Firmware Fetching

Thanks to EyeFi's Berend and his kind comments explaining the difference between "pure zlib data" and gzip formats I've put together a script to download from the EyeFi web site and decode a copy of the firmware using a random card's mac address. Now if I can just figure out what format the firmware is in...

I also made a mistake. Reading wpa_supplicant's license agreement, I saw the GPL in there and missed the part about it being dual licensed. However, the nice folks at EyeFi were quick to point out:
The Eye-Fi software utilizes LGPL, BSD, Apache, MIT, ZLib, IJG (Independent JPEG Group) and Boost licensed open-source components. None of these licenses require disclosure of the source code.
So, I guess there's no Linux in there after all.

They also pointed out that EyeFi is acting in good faith and sharing improvements they make to open-source components that they use. This bug filing would seem to indicate that they use IwIP for their TCP/IP stack. This might be why p0f doesn't seem to be able to detect the card's OS.

Firmware, press releases and the GPL

First of all, it's great to know that some of the EyeFi engineers are reading this! Berend (who I think is one of the EyeFi Founders) pointed out that:
The API call simply returns the data in gzipped and Base64-encoded format.
That's what I suspected, but I can't seem to get uudecode to give me anything that looks like gzip in its output. The sizes line up, but there's no gzip header.

Berend also noted that the bits about the chipset being Altheros and MIPS are well documented in press releases. Cool! I'm not just making this stuff up! Let's quote from there:
The solutions also come with full driver support for Windows Mobile CE 6.0 and Linux-based designs.
WinCE does not have a 'devfs' as far as I know, so that would lead me to believe that the card is either running Linux or EyeFi has ported another OS to it. That would be a wee bit interesting if it ran Linux.

Although, the card can't be running Linux since it is GPL'd and would require EyeFi to publish the source code for at least the kernel. They aren't doing that as far as I know, so it can't be running Linux. Just in case, here's a nice informative link which clearly explains a company's obligations under the GPL.

(changed "a commenter" to refer to Berend)

Firmware image

I was able to sniff the latest update to the firmware as it happened. It does download it as far as I can tell from the site I mentioned in an earlier post. However, I can't quite figure out what the download format is.

But, I did manage to catch the manager writing 'EYEFIFWU.BIN' to the root of the card, just before issuing a 'b' command to reboot. I believe this let me get a hold of a complete, decoded firmware image. There's a lot of interesting stuff in there. The card's chipset looks to be a Atheros ar6000 which contains a MIPS core.

It also appears that the card has /public and /private mount points that the card's OS can see. /public is what we get to see on the card itself, and private is where the real fun is stored. There also appears to be a 'devfs'. devfs's exist on at least FreeBSD and older Linux versions, and this doesn't really point in either direction.

But, I don't really see an OS, a bootloader or any executables in the image. I ran 'file' at 1-byte offsets on it and didn't really come up with much. I think it could certainly use another pair of eyes.

Thursday, February 21, 2008

Working Standalone Software!!

So, a reader of this blog has been able to understand many of the interactions with the card. He's written software to:
  1. List configured networks
  2. List scanned networks
  3. Print card MAC address
  4. Print card firmware information
and I've added on to it to fetch the card logs. This is really good progress, and the ability to add networks to the card shouldn't be too horribly far away. I'm sure that the author will be willing to share it publicly soon. I'd post it somewhere, but I don't want to be passing around someone else's code for which I have no permission to distribute. I'll post here as soon as it is available.

BTW, a recent commenter noted that the card can only add ASCII WEP keys, and not hex ones. They didin't get much help from EyeFi support. I've seen the same limitation, and I'm happy to say that the card's hardware accepts hex keys. It's just a limitation of the manager software right now that it only takes ASCII. I've actually watched the manager software program the hex values derived from the ASCII keys into the card.

Sunday, February 10, 2008

Firmware updates

There have been some people talking in the comments about things to do to the firmware. While I'm sure some of you have actually agreed to the license and are likely restrained by its terms, I bet most of you haven't. You also don't necessarily have to agree to a license to simply download files from a web site.

Simply sitting in an airport next to me (or stalking me at my house) you could easily pick up my EyeFi card, its mac address, and watch it do its firmware updates. You might also see the manager fetch a file from the server for its firmware updates in plain text. If you want a firmware file for a souvenir, you could try fetching from these urls which are completely unauthenticated (except that your card has to be registered). So, try a few random ones until you get a hit:

for ((i=0;i<100;i++));
url="http://api.eye.fi/api/rest/eyeserver/v1";
rmac=$(printf '00-18-56-03-%02x-%02x\n'
$((RANDOM%256)) $((RANDOM%256)));
wget "${url}/getCardFirmware?Card=$rmac&Version=1.0496";
done

The error result documents are ~100 bytes, while the real ones are a couple hundred kilobytes.

Monday, February 4, 2008

Why I care about EyeFi on Linux

A recent commenter noted that EyeFi simply supports XP and OSX because of the volume on those platforms. It would be silly for them to support the minuscule number of Linux users. Also, most Linux users at least have one XP machine on which to set up the card.

First of all, I kinda hope EyeFi does not release Linux software. We are a small minority and they surely will waste engineering resources on an operating system that they do not understand. I do hope they release information on how the card works. That will let me set it up myself, or let hundreds of others do the same.

Sure, I could go steal my wife's machine to set up the card. But, what do I do when I'm traveling? Isn't that the time I need to change settings in the card the most?