So, Ipoque has published its deep inspection engine under a free license (LGPLv3): OpenDPI This is always good news when a company decides to release source code to the community, so first of all thanks to Ipoque for this.

After downloading the source code on OpenDPI google project’s page, I started to look at it.

Basically, the project looks quite unprepared for release (only a Makefile, no configure script - though no-one can be blamed for not using autotools -), but after looking at the code it seems not so bad:

  • the code is reasonably clean
  • it builds fine on x86 or x86_64 platforms
  • the code is provided with a decent list of identified protocols
  • the demo uses pcap files

There are a few minor annoyances:

  • the provided lib is a static lib … building a shared library would be better !
  • the build system is pretty awful, rebuilding everything each time, without using deps, no install system etc.
  • no docs (looking at the demo file was sufficient to understand most of the function).
  • no correct website, forums or whatever. I’m sure it will get better in the future
  • pcap only

This last point was the most annoying to me, so I decided to rewrite a daemon using the NFQUEUE target. While I could have used the nfqueue-bindings, I decided to use C this time: it was simpler ! I only had to recode the open/close/runloop functions to use nfqueue, extract the packet from the nfqueue callback, and use the exact same callback as for pcap :)

Here is the relevant parts of the interesting code:

static int _nfq_cb(struct nfq_q_handle *qh,
                 struct nfgenmsg *nfmsg,
             struct nfq_data *nfad, void *data)
{
       [...]
    struct nfqnl_msg_packet_hdr *ph = nfq_get_msg_packet_hdr(nfad);

    if (ph)
        id = ntohl(ph->packet_id);

    payload_len = nfq_get_payload(nfad, &payload);
    iph = (struct iphdr*)payload;

    ret = nfq_get_timestamp(nfad, &tv);
    time =
        ((uint64_t) tv.tv_sec) * detection_tick_resolution +
        tv.tv_usec / (1000000 / detection_tick_resolution);

    // process the packet
    packet_processing(time, iph, payload_len, payload_len);

    nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);

    return 0;
}

The proof-of-concept code works fine. As seen on this discussion, maybe Ipoque folks would be interested in a contribution :D No netfilter integration is needed, just playing with nfqueue + mark for filtering should be enough for most cases.

The code is not yet published, because it doesn’t do anything useful yet (just try to identify and follow protocols and flows). If you’re interested, contact me.