--- /dev/null
+#!/usr/bin/python
+###############################################################################
+# #
+# Cappie #
+# Copyright (C) 2010 Michael Tremer #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+import struct
+
+from constants import *
+from errors import *
+
+def val2int(val):
+ return int("".join(["%02d" % ord(c) for c in val]), 16)
+
+def val2ip4(val):
+ return ".".join(["%d" % ord(i) for i in val])
+
+def val2mac(val):
+ return ":".join(["%02x" % ord(i) for i in val])
+
+def decode_packet(data):
+ for func in (decode_arp_packet,):
+ try:
+ p = func(data)
+ except PacketTypeError:
+ continue
+
+ return p
+
+ raise PacketTypeError, "Could not determine type of packet"
+
+def decode_arp_packet(data):
+ operationmap = {
+ 1 : OPERATION_REQUEST,
+ 2 : OPERATION_RESPONSE,
+ }
+
+ #if not len(data) == 42:
+ # raise DecodeError, "Data has wrong length: %d" % len(data)
+
+ ret = {
+ "type" : TYPE_ARP,
+ }
+
+ #"hwtype" : data[:2],
+ protocol = val2int(struct.unpack("!2s", data[12:14])[0])
+ hw_addr_size = val2int(struct.unpack("!1s", data[18:19])[0])
+ hw_prot_size = val2int(struct.unpack("!1s", data[19:20])[0])
+ operation = val2int(struct.unpack("!2s", data[20:22])[0])
+
+ # Sanity checks
+ if not protocol == 0x0806:
+ raise PacketTypeError, "Not an ARP packet"
+
+ # TODO Must check hwtype here...
+
+ try:
+ ret["operation"] = operationmap[operation]
+ except KeyError:
+ raise DecodeError, "Unknown operation type"
+
+ address_length = hw_addr_size + hw_prot_size
+ unpack_str = "!%ss%ss" % (hw_addr_size, hw_prot_size)
+
+ ret["source_address"], ret["source_ip_address"] = \
+ struct.unpack(unpack_str, data[22:22 + address_length])
+
+ ret["destination_address"], ret["destination_ip_address"] = \
+ struct.unpack(unpack_str, data[22 + address_length:22 + address_length * 2])
+
+ for i in ("source_address", "destination_address"):
+ ret[i] = val2mac(ret[i])
+
+ for i in ("source_ip_address", "destination_ip_address"):
+ ret[i] = val2ip4(ret[i])
+
+ return ret
+
+def decode_ndp_packet(data):
+ raise PacketTypeError