Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/vrrp.py: 69%

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

45 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) Philippe Biondi <phil@secdev.org> 

5# Copyright (C) 6WIND <olivier.matz@6wind.com> 

6 

7""" 

8VRRP (Virtual Router Redundancy Protocol). 

9""" 

10 

11from scapy.packet import Packet, bind_layers 

12from scapy.fields import BitField, ByteField, FieldLenField, FieldListField, \ 

13 IPField, IP6Field, IntField, MultipleTypeField, StrField, XShortField 

14from scapy.compat import chb, orb 

15from scapy.layers.inet import IP, in4_chksum, checksum 

16from scapy.layers.inet6 import IPv6, in6_chksum 

17from scapy.error import warning 

18 

19IPPROTO_VRRP = 112 

20 

21# RFC 3768 - Virtual Router Redundancy Protocol (VRRP) 

22 

23 

24class VRRP(Packet): 

25 fields_desc = [ 

26 BitField("version", 2, 4), 

27 BitField("type", 1, 4), 

28 ByteField("vrid", 1), 

29 ByteField("priority", 100), 

30 FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), 

31 ByteField("authtype", 0), 

32 ByteField("adv", 1), 

33 XShortField("chksum", None), 

34 FieldListField("addrlist", [], IPField("", "0.0.0.0"), 

35 count_from=lambda pkt: pkt.ipcount), 

36 IntField("auth1", 0), 

37 IntField("auth2", 0)] 

38 

39 def post_build(self, p, pay): 

40 if self.chksum is None: 

41 ck = checksum(p) 

42 p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:] 

43 return p 

44 

45 @classmethod 

46 def dispatch_hook(cls, _pkt=None, *args, **kargs): 

47 if _pkt and len(_pkt) >= 9: 

48 ver_n_type = orb(_pkt[0]) 

49 if ver_n_type >= 48 and ver_n_type <= 57: # Version == 3 

50 return VRRPv3 

51 return VRRP 

52 

53 

54# RFC 5798 - Virtual Router Redundancy Protocol (VRRP) Version 3 

55class VRRPv3(Packet): 

56 fields_desc = [ 

57 BitField("version", 3, 4), 

58 BitField("type", 1, 4), 

59 ByteField("vrid", 1), 

60 ByteField("priority", 100), 

61 FieldLenField("ipcount", None, count_of="addrlist", fmt="B"), 

62 BitField("res", 0, 4), 

63 BitField("adv", 100, 12), 

64 XShortField("chksum", None), 

65 MultipleTypeField( 

66 [ 

67 (FieldListField("addrlist", [], IPField("", "0.0.0.0"), 

68 count_from=lambda pkt: pkt.ipcount), 

69 lambda p: isinstance(p.underlayer, IP)), 

70 (FieldListField("addrlist", [], IP6Field("", "::"), 

71 count_from=lambda pkt: pkt.ipcount), 

72 lambda p: isinstance(p.underlayer, IPv6)), 

73 ], 

74 StrField("addrlist", "") 

75 ) 

76 ] 

77 

78 def post_build(self, p, pay): 

79 if self.chksum is None: 

80 if isinstance(self.underlayer, IP): 

81 ck = in4_chksum(112, self.underlayer, p) 

82 elif isinstance(self.underlayer, IPv6): 

83 ck = in6_chksum(112, self.underlayer, p) 

84 else: 

85 warning("No IP(v6) layer to compute checksum on VRRP. " 

86 "Leaving null") 

87 ck = 0 

88 p = p[:6] + chb(ck >> 8) + chb(ck & 0xff) + p[8:] 

89 return p 

90 

91 @classmethod 

92 def dispatch_hook(cls, _pkt=None, *args, **kargs): 

93 if _pkt and len(_pkt) >= 16: 

94 ver_n_type = orb(_pkt[0]) 

95 if ver_n_type < 48 or ver_n_type > 57: # Version != 3 

96 return VRRP 

97 return VRRPv3 

98 

99 

100# IPv6 is supported only on VRRPv3 

101# Warning: those layers need to be un-binded in the CARP contrib module. 

102# If you add/remove any, remember to also edit the one in CARP.py 

103bind_layers(IP, VRRP, proto=IPPROTO_VRRP) 

104bind_layers(IP, VRRPv3, proto=IPPROTO_VRRP) 

105bind_layers(IPv6, VRRPv3, nh=IPPROTO_VRRP)