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

49 statements  

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> 

5 

6""" 

7HSRP (Hot Standby Router Protocol) 

8A proprietary redundancy protocol for Cisco routers. 

9 

10- HSRP Version 1: RFC 2281 

11- HSRP Version 2: 

12 http://www.smartnetworks.jp/2006/02/hsrp_8_hsrp_version_2.html 

13""" 

14 

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 

22 

23 

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"} 

35 

36 

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 ] 

51 

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 

57 

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) 

63 

64 

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 ] 

78 

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 

84 

85 

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)] 

97 

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 

103 

104 

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)