#! /usr/bin/env python
# -*- mode:python -*-
# $Id: dfd_sniff.py 11415 2006-03-05 22:35:14Z user $

"""
Description
"""

from pcapy import *

import socket

class dfd_client:
    """
    A prototype due to turn into its own project.
    This is a client library for commanding a (potentially remote)
    instance of DFD.
    """
    def __init__(self, host = "", port = 8007):
        # NOTE: Empty string host means localhost
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.host = host
        self.port = port
    def command(self, s):
        self.sock.connect((self.host, self.port))
        self.sock.send(s + "\n")
        self.sock.close()

if __name__ == '__main__':

    # There is nothing sane I can set this to by default on BSD.
    # So I do Linux here.  Why should I have to care about what
    # chip family you use on your NIC?
    interface="eth0"
    snaplen=2048
    promisc=0
    timeout=100

    # Parse command-line options.
    import getopt, sys

    usage = "Usage: %s\n" % sys.argv[0]
    try:
        opts, args = getopt.getopt(sys.argv[1:], "i:hs:t:",
                                   [ "interface=s", "snaplen=d", "timeout=d",
                                     "help" ])
    except getopt.GetoptError:
        sys.stderr.write(usage)
        sys.exit(1)

    for o, a in opts:
        if o in ("-i", "--interface"):
            interface = a
        if o in ("-s", "--snaplen"):
            snaplen = a
        if o in ("-t", "--timeout"):
            timeout = a
        if o in ("-h", "--help"):
            print usage
            sys.exit(0)

    r = open_live(interface, snaplen, promisc, timeout)

    # TODO: Filter for local hosts hitting remote sites, not vice versa.
    filter = "tcp[tcpflags] & tcp-syn != 0 and (" + \
             " or ".join([ "dst port " + str(x) for x in range(6881, 6890)]) \
             + ")"
    r.setfilter(filter)
    l2 = r.datalink

    from impacket import ImpactDecoder, ImpactPacket

    decoder = ImpactDecoder.EthDecoder()

    bt_host = None
    cli = dfd_client()

    def bittorrent_seen(hdr, contents):
        global bt_host
        global cli
        ep = decoder.decode(contents)
        ip = ep.child()
        tmp = ip.get_ip_src()
        if tmp != bt_host:
            bt_host = tmp
            cli.command("bittorrent " + bt_host)

    r.loop(-1, bittorrent_seen)
    sys.exit(0)
