1 ## This file is part of Scapy 2 ## See http://www.secdev.org/projects/scapy for more informations 3 ## Copyright (C) Philippe Biondi <phil (at] secdev.org> 4 ## This program is published under a GPLv2 license 5 6 ############################################################################# 7 ## ## 8 ## hsrp.py --- HSRP protocol support for Scapy ## 9 ## ## 10 ## Copyright (C) 2010 Mathieu RENARD mathieu.renard(at)gmail.com ## 11 ## ## 12 ## This program is free software; you can redistribute it and/or modify it ## 13 ## under the terms of the GNU General Public License version 2 as ## 14 ## published by the Free Software Foundation; version 2. ## 15 ## ## 16 ## This program is distributed in the hope that it will be useful, but ## 17 ## WITHOUT ANY WARRANTY; without even the implied warranty of ## 18 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## 19 ## General Public License for more details. ## 20 ## ## 21 ############################################################################# 22 ## HSRP Version 1 23 ## Ref. RFC 2281 24 ## HSRP Version 2 25 ## Ref. http://www.smartnetworks.jp/2006/02/hsrp_8_hsrp_version_2.html 26 ## 27 ## $Log: hsrp.py,v $ 28 ## Revision 0.2 2011/05/01 15:23:34 mrenard 29 ## Cleanup code 30 31 """ 32 HSRP (Hot Standby Router Protocol): proprietary redundancy protocol for Cisco routers. 33 """ 34 35 from scapy.fields import * 36 from scapy.packet import * 37 from scapy.layers.inet import DestIPField, UDP 38 from scapy.layers.inet6 import DestIP6Field 39 40 41 class HSRP(Packet): 42 name = "HSRP" 43 fields_desc = [ 44 ByteField("version", 0), 45 ByteEnumField("opcode", 0, {0: "Hello", 1: "Coup", 2: "Resign", 3: "Advertise"}), 46 ByteEnumField("state", 16, {0: "Initial", 1: "Learn", 2: "Listen", 4: "Speak", 8: "Standby", 16: "Active"}), 47 ByteField("hellotime", 3), 48 ByteField("holdtime", 10), 49 ByteField("priority", 120), 50 ByteField("group", 1), 51 ByteField("reserved", 0), 52 StrFixedLenField("auth", b"cisco" + b"\00" * 3, 8), 53 IPField("virtualIP", "192.168.1.1")] 54 55 def guess_payload_class(self, payload): 56 if self.underlayer.len > 28: 57 return HSRPmd5 58 else: 59 return Packet.guess_payload_class(self, payload) 60 61 62 class HSRPmd5(Packet): 63 name = "HSRP MD5 Authentication" 64 fields_desc = [ 65 ByteEnumField("type", 4, {4: "MD5 authentication"}), 66 ByteField("len", None), 67 ByteEnumField("algo", 0, {1: "MD5"}), 68 ByteField("padding", 0x00), 69 XShortField("flags", 0x00), 70 SourceIPField("sourceip", None), 71 XIntField("keyid", 0x00), 72 StrFixedLenField("authdigest", b"\00" * 16, 16)] 73 74 def post_build(self, p, pay): 75 if self.len is None and pay: 76 l = len(pay) 77 p = p[:1] + hex(l)[30:] + p[30:] 78 return p 79 80 bind_layers(UDP, HSRP, dport=1985, sport=1985) 81 bind_layers(UDP, HSRP, dport=2029, sport=2029) 82 DestIPField.bind_addr(UDP, "224.0.0.2", dport=1985) 83 DestIP6Field.bind_addr(UDP, "ff02::66", dport=2029) 84