]> git.ipfire.org Git - oddments/cappie.git/blobdiff - cappie/protocol.py
Splitted into daemon and python module.
[oddments/cappie.git] / cappie / protocol.py
diff --git a/cappie/protocol.py b/cappie/protocol.py
new file mode 100644 (file)
index 0000000..ed5f4a3
--- /dev/null
@@ -0,0 +1,95 @@
+#!/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