Tips for debugging RTMP traffic

Debugging network traffic is hard enough to start with. When you’re trying to reverse-engineer a protocol like Adobe’s RTMP, then it becomes a nightmare. These tips helped me a bit (but it still is painful):

  • A very throrough explation of the protocol is at
  • Use Wireshark for packet-sniffing (don’t bother with Fiddler, since it doesn’t support RTMP). In the “Options”, make sure “Enable network name resolution” is checked.

Building rtmpdump for Win32, without cygwin

I’ve been following Adobe’s RTMP protocol for awhile, and kudos go out to all the brave souls that have tried to build alternative clients for it. There are various projects in Java, Python, and a notable closed-source app, the Orbitz Downloader, also seems to work if you don’t mind a standalone browser plugin.

For C/C++, the XBMC team wrote the only client I’ve seen in their libRTMP namespace, and this was used as the basis for the excellent rtmpdump project on sourceforge, which was ported over to linux (and for Windows, cygwin). I should note that there’s also Gnash, the open-source Flash player, but it has a lot of dependencies to build (and the latest Win32 binary release is from 2007; no one builds it regularly on Windows apparently) so I haven’t really looked at it.

As an experiment I wanted to see if I could get rtmpdump 1.3d running on pure-Windows, no cygwin needed (you still need the Boost C++ libraries, but of course these are platform-independent). In the end, I was able to compile it on Visual Studio 2008 on Vista, and it “mostly” runs.

The porting steps were:

  1. Install the Windows SDK v6.1. You need at least XP or later for this SDK I believe.
  2. Install the Boost libraries with the Windows installer
  3. In rtmpdump, get rid of the linux headers and replace them with the Win32 equivalents. The tips at was the key here.
  4. Since the time-related stuff is far different in Win32, I changed rtmpdump::GetTime(). Not positive I did this correctly though – it’s possible that a logic error here may cause downloads to get rejected (see below).
  5. getopts() had to be replaced with XGetOpt, an alternate (public-domain) implementation I found. No longopts support but it works with the “short” options.
  6. The longopts[] initializer doesn’t compile with VS, so I took it out – it’s not needed anyway because of #5.

Everything I changed is marked with “TODO” if you want to see the diffs. After configuring the include and library paths for #1 and #2, you should be able to build the VS2008 solution. So it runs (and indeed behaves the same as the Cygwin version I built to compare it to) but I should note that neither one actually downloads an FLV file from a real-life RTMP server for me. But at least both codebases now behave the same. Specifically if I try a real Flash Media Server url, I get something like:

C:\rtmpdump-v1.3d\Debug>rtmpdump -r rtmp:// -o out.flv
RTMPDump v1.3d
(c) 2009 Andrej Stepanchuk, license: GPL
DEBUG: Setting buffer time to: 36000000ms
Connecting to rtmp:// ...
DEBUG: Hostname:
DEBUG: Port: 1935
DEBUG: connected, hand shake:
DEBUG: handshaked
Starting download at 0.000 KB
DEBUG: RTMP_LIB::CRTMP::GetNextMediaPacket, received: invoke
DEBUG: Property:
DEBUG: Property:
DEBUG: Property: NULL
DEBUG: Property:
DEBUG: Property:
DEBUG: Property:
DEBUG: Property:
DEBUG: RTMP_LIB::CRTMP::HandleInvoke, server invoking <_error>
ERROR: rtmp server sent error
DEBUG: RTMP_LIB::CRTMP::GetNextMediaPacket, received: invoke
DEBUG: Property:
DEBUG: Property:
DEBUG: RTMP_LIB::CRTMP::HandleInvoke, server invoking
ERROR: rtmp server requested close
DEBUG: zero read!
Closing connection... done!

Now I hope that I am just missing a “real-life” parameter like swfURL or app, but as I said, at least it works like the Cygwin version for this limited test case. Anyone got any real-life parameters I can try?

Anyway, thanks again to the rtmpdump and XBMC guys. They did all the hard work!

Download the Visual Studio 2008 project here: