1## This file is part of Scapy
2## See http://www.secdev.org/projects/scapy for more informations
3## Copyright (C) Philippe Biondi <phil@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"""
32HSRP (Hot Standby Router Protocol): proprietary redundancy protocol for Cisco routers.
33"""
34
35from scapy.fields import *
36from scapy.packet import *
37from scapy.layers.inet import UDP
38
39
40class HSRP(Packet):
41    name = "HSRP"
42    fields_desc = [
43        ByteField("version", 0),
44        ByteEnumField("opcode", 0, {0: "Hello", 1: "Coup", 2: "Resign", 3: "Advertise"}),
45        ByteEnumField("state", 16, {0: "Initial", 1: "Learn", 2: "Listen", 4: "Speak", 8: "Standby", 16: "Active"}),
46        ByteField("hellotime", 3),
47        ByteField("holdtime", 10),
48        ByteField("priority", 120),
49        ByteField("group", 1),
50        ByteField("reserved", 0),
51        StrFixedLenField("auth", "cisco" + "\00" * 3, 8),
52        IPField("virtualIP", "192.168.1.1")]
53
54    def guess_payload_class(self, payload):
55        if self.underlayer.len > 28:
56            return HSRPmd5
57        else:
58            return Packet.guess_payload_class(self, payload)
59
60
61class HSRPmd5(Packet):
62    name = "HSRP MD5 Authentication"
63    fields_desc = [
64        ByteEnumField("type", 4, {4: "MD5 authentication"}),
65        ByteField("len", None),
66        ByteEnumField("algo", 0, {1: "MD5"}),
67        ByteField("padding", 0x00),
68        XShortField("flags", 0x00),
69        IPField("sourceip", None),
70        XIntField("keyid", 0x00),
71        StrFixedLenField("authdigest", "\00" * 16, 16)]
72
73    def post_build(self, p, pay):
74        if self.len is None and pay:
75            l = len(pay)
76            p = p[:1] + hex(l)[30:] + p[30:]
77        return p
78
79bind_layers(UDP, HSRP, dport=1985, sport=1985)
80