[Twisted-Python] twisted irc client + packet capturing

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Fri Nov 8 05:08:55 MST 2013


On 08:50 am, ewong at pw-wspx.org wrote:
>Hi,
>
>I've created a script that would log on to an irc server, while
>capturing packets.
>
>I came across the following link:
>
>http://dound.com/2009/09/integrating-twisted-with-a-pcap-based-python- 
>packet-sniffer/
>
>But I'm using pycap (http://pycap.sourceforge.net/), but I'm having
>some difficulties with getting it to work.
>
>Here's the code:
>
># Copyright (c) Twisted Matrix Laboratories.
># See LICENSE for details.
>
># twisted imports
>from twisted.words.protocols import irc
>from twisted.internet import reactor, protocol
>from twisted.python import log
>from twisted.internet.defer import Deferred
>
># system imports
>import time, sys
>
>import pycap.capture
>
>def run_pcap(f):
>     p = pycap.capture.capture('eth0')
>     p.filter('src host ! 192.168.1.100 and dst host ! 192.168.1.100 and 
>dst port 25')
>     packet = None
>     print "Listening...\n"
>     while 1:
>        if packet:
>           print "Received packet."
>           reactor.callFromThread(f, packet)
>        else:
>           print "no packet\n"
>        packet = p.next()
>
>class LogBot(irc.IRCClient):
>     """A logging IRC bot."""
>
>     nickname = "testbot"
>
>     def packetShow(self, packet):
>         """ booga """
>         msg = "Port 25 hit | From:[%s] To:[%s]" % (packet[1].source, 
>packet[1].destination)
>         self.msg(self.channel, msg)
>
>     def connectionMade(self):
>         irc.IRCClient.connectionMade(self)
>         print "Setting up callInThread\n"
>         reactor.callInThread(run_pcap, self.packetShow)
>         print "Finished setting up callInThread\n"
>
>     def connectionLost(self, reason):
>         irc.IRCClient.connectionLost(self, reason)
>
>     # callbacks for events
>
>     def signedOn(self):
>         """Called when bot has succesfully signed on to server."""
>         print "Signing on to %s.\n" % self.factory.channel
>         # self.join(self.factory.channel)
>         self.sendLine("JOIN %s" % (self.factory.channel,))
>
>     def joined(self, channel):
>         """This will get called when the bot joins the channel."""
>         print "Joining channel %s." % channel
>
>     def privmsg(self, user, channel, msg):
>         """This will get called when the bot receives a message."""
>         user = user.split('!', 1)[0]
>
>         # Check to see if they're sending me a private message
>         if channel == self.nickname:
>             msg = "It isn't nice to whisper!  Play nice with the 
>group."
>             self.msg(user, msg)
>             return
>
>         # Otherwise check to see if it is a message directed at me
>         if msg.startswith(self.nickname + ":"):
>             msg = "%s: I am a log bot" % user
>             self.msg(channel, msg)
>
>     def action(self, user, channel, msg):
>         """This will get called when the bot sees someone do an 
>action."""
>         user = user.split('!', 1)[0]
>
>     # irc callbacks
>
>     def irc_NICK(self, prefix, params):
>         """Called when an IRC user changes their nickname."""
>         old_nick = prefix.split('!')[0]
>         new_nick = params[0]
>
>
>     # For fun, override the method that determines how a nickname is 
>changed on
>     # collisions. The default method appends an underscore.
>     def alterCollidedNick(self, nickname):
>         """
>         Generate an altered version of a nickname that caused a 
>collision in an
>         effort to create an unused related name for subsequent 
>registration.
>         """
>         return nickname + '^'
>
>class LogBotFactory(protocol.ClientFactory):
>     """A factory for LogBots.
>
>     A new protocol instance will be created each time we connect to the 
>server.
>     """
>
>     def __init__(self, channel):
>         self.channel = channel
>
>     def buildProtocol(self, addr):
>         p = LogBot()
>         p.factory = self
>         return p
>
>     def clientConnectionLost(self, connector, reason):
>         """If we get disconnected, reconnect to server."""
>         connector.connect()
>
>     def clientConnectionFailed(self, connector, reason):
>         print "connection failed:", reason
>         reactor.stop()
>
>
>if __name__ == '__main__':
>     # create factory protocol and application
>     f = LogBotFactory("#testx")
>
>     # connect factory to this host and port
>     reactor.connectTCP("192.168.1.170", 6667, f)
>
>     # run bot
>     reactor.run()
>
>I was told that perhaps I could use twisted.pair,
>but I have no idea how to use the module.  The
>documentation is lacking and I've only just started
>programming in Twisted.
>
>Any help appreciated.

I don't know if Twisted Pair will work better for you but you can find 
the start of some documentation about it in this branch:

  https://twistedmatrix.com/trac/browser/branches/tuntap-pytun-6169-3

Additionally, this branch removes the Twisted Pair dependency on the 
"eunuchs" module which is abandoned and difficult to find.

Jean-Paul



More information about the Twisted-Python mailing list