Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/hsrp.py: 82%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Mathieu RENARD <mathieu.renard(at)gmail.com>
6"""
7HSRP (Hot Standby Router Protocol)
8A proprietary redundancy protocol for Cisco routers.
10- HSRP Version 1: RFC 2281
11- HSRP Version 2:
12 http://www.smartnetworks.jp/2006/02/hsrp_8_hsrp_version_2.html
13"""
15from scapy.config import conf
16from scapy.compat import orb
17from scapy.fields import ByteEnumField, ByteField, IntField, IPField, \
18 ShortEnumField, ShortField, SourceIPField, StrFixedLenField, \
19 XIntField, XShortField
20from scapy.packet import Packet, bind_layers, bind_bottom_up
21from scapy.layers.inet import DestIPField, UDP
24_HSRP_OPCODES = {0: "Hello", 1: "Coup", 2: "Resign", 3: "Advertise"}
25_HSRP_STATES = {
26 0: "Initial",
27 1: "Learn",
28 2: "Listen",
29 4: "Speak",
30 8: "Standby",
31 16: "Active",
32}
33_HSRP_ADVERTISE_TYPES = {1: "HSRP interface state"}
34_HSRP_ADVERTISE_STATES = {1: "Active", 2: "Passive"}
37class HSRP(Packet):
38 name = "HSRP"
39 fields_desc = [
40 ByteField("version", 0),
41 ByteEnumField("opcode", 0, _HSRP_OPCODES),
42 ByteEnumField("state", 16, _HSRP_STATES),
43 ByteField("hellotime", 3),
44 ByteField("holdtime", 10),
45 ByteField("priority", 120),
46 ByteField("group", 1),
47 ByteField("reserved", 0),
48 StrFixedLenField("auth", b"cisco" + b"\00" * 3, 8),
49 IPField("virtualIP", "192.168.1.1")
50 ]
52 @classmethod
53 def dispatch_hook(cls, _pkt=None, *args, **kargs):
54 if _pkt and len(_pkt) >= 2 and orb(_pkt[1:2]) == 3:
55 return HSRPAdvertise
56 return cls
58 def guess_payload_class(self, payload):
59 if self.underlayer.len > 28:
60 return HSRPmd5
61 else:
62 return Packet.guess_payload_class(self, payload)
65class HSRPAdvertise(Packet):
66 name = "HSRP Advertise"
67 fields_desc = [
68 ByteField("version", 0),
69 ByteEnumField("opcode", 3, _HSRP_OPCODES),
70 ShortEnumField("type", 1, _HSRP_ADVERTISE_TYPES),
71 ShortField("length", 10),
72 ByteEnumField("state", 1, _HSRP_ADVERTISE_STATES),
73 ByteField("reserved1", 0),
74 ShortField("activegroups", 0),
75 ShortField("passivegroups", 0),
76 IntField("reserved2", 0),
77 ]
79 @classmethod
80 def dispatch_hook(cls, _pkt=None, *args, **kargs):
81 if _pkt and len(_pkt) >= 2 and orb(_pkt[1:2]) != 3:
82 return HSRP
83 return cls
86class HSRPmd5(Packet):
87 name = "HSRP MD5 Authentication"
88 fields_desc = [
89 ByteEnumField("type", 4, {4: "MD5 authentication"}),
90 ByteField("len", None),
91 ByteEnumField("algo", 0, {1: "MD5"}),
92 ByteField("padding", 0x00),
93 XShortField("flags", 0x00),
94 SourceIPField("sourceip"),
95 XIntField("keyid", 0x00),
96 StrFixedLenField("authdigest", b"\00" * 16, 16)]
98 def post_build(self, p, pay):
99 if self.len is None and pay:
100 tmp_len = len(pay)
101 p = p[:1] + hex(tmp_len)[30:] + p[30:]
102 return p
105bind_bottom_up(UDP, HSRP, dport=1985)
106bind_bottom_up(UDP, HSRP, sport=1985)
107bind_bottom_up(UDP, HSRP, dport=2029)
108bind_bottom_up(UDP, HSRP, sport=2029)
109bind_layers(UDP, HSRP, dport=1985, sport=1985)
110bind_layers(UDP, HSRP, dport=2029, sport=2029)
111DestIPField.bind_addr(UDP, "224.0.0.2", dport=1985)
112if conf.ipv6_enabled:
113 from scapy.layers.inet6 import DestIP6Field
114 DestIP6Field.bind_addr(UDP, "ff02::66", dport=2029)