Extend Captcp

Documentation

Writing your own Captcp Module

Hello World Example

We start with a Hello-World example. This module parse commandline options. Print a short packet summary for each received packet and at the end the number of processed packets is printed. We start with a simple skeleton:

class ExampleMod(Mod):

		def initialize(self):
				pass

		def pre_process_packet(self, ts, packet):
				pass

		def process_packet(self, ts, packet):
				pass

		def process_final(self):
				pass

The method names and the function signature say everything:

  • initialize() is called at program start - option must be parsed here
  • pre_process_packet() is called for each captured packet. Parsing can be done here
  • process_packet() is also called for each packet. We will see why parser function is called twice
  • process_final() is called shortly before captcp is exited

Next step is to register the module. That captcp can call the module like every other module. This is done by add a line to the modes variable in the Captcp class:

	[...]
	"sound":    [ "SoundMod", "Play sound based on payload/ack packets" ],
	"show":     [ "ShowMod", "Tcpdump/tshark like mode" ],
	"example":  [ "ExampleMod", "Hello World Module" ],
	[...]
}

Extend Hello World Example

In the next step we remove pre_process_packet(), because it is not used in this example. The two stage packet processing is mainly used if the second stage depends on results of the first stage. Of course it is also possible to save the packets locally in a list. But it may consume a lot of memory to store many packets in the list. Thus the two stage processing is a easy way to pre-process and process the packets in two successive methods.

In initialize() and process_packet() we introduce a new counter. Increase the counter at each packet and print the final number of packets to the terminal - thats all here.

class ExampleMod(Mod):

		def initialize(self):
				self.packets = 0

		def process_packet(self, ts, packet):
				self.packets += 1

		def process_final(self):
				sys.stdout.write("processed %d packets\n" % (self.packets))

Now lets account the transmitted bytes at link layer level and count the number where SYN flag is set. We ignore all packets except TCP.

class ExampleMod(Mod):

		def initialize(self):
				self.bytes = 0
				self.syn_packets = 0

		def process_packet(self, ts, packet):
				if type(packet.data) != TCP:
						return

				if PacketInfo(packet).is_syn_flag()
						self.syn_packets += 1

				self.bytes += len(packet)

		def process_final(self):
				sys.stdout.write("processed %d bytes with %d SYN packets\n" %
												 (self.bytes, self.syn_packets))