Skip to content

feat: added hsrpv2 support layer#5032

Open
pengsies wants to merge 7 commits into
secdev:masterfrom
pengsies:feat/add-hsrpv2-support
Open

feat: added hsrpv2 support layer#5032
pengsies wants to merge 7 commits into
secdev:masterfrom
pengsies:feat/add-hsrpv2-support

Conversation

@pengsies

@pengsies pengsies commented Jul 2, 2026

Copy link
Copy Markdown

context

hi! This is my first pull request to an open-source project, so please let me know if there is anything I should adjust.

so while working with HSRP packet building for a poc in my uni's hsrp network security project, i noticed that scapy’s existing hsrp layer supports the classic hsrpv1 packet format, but not the tlv-based format of hsrpv2. of course, because Scapy does not currently expose a native hsrpv2 layer, this means that packets of that nature would have to be constructed manually as raw udp payloads which was what i did. for example, the group state tlv and text authentication tlv need to be packed manually before being attached as Raw(load=...).. but in any case, i thought that it would
thought it would be useful for Scapy to support hsrpv2 directly, which resulted in this small contribution :D

tldr; PR adds a hsrpv2 support layer without changing any existing hsrpv1 packet model(s).

description

PR adds native hsrpv2 tlv support, and includes:

  • A new hsrpv2 tlv container layer.
  • tlv dispatching for hsrpv2 payloads.
  • hsrpv2 Group State tlv support.
  • hsrpv2 Interface State tlv support.
  • hsrpv2 Text Authentication tlv support.
  • unknown tlv preservation for unsupported tlv types.
  • ipv4 and ipv6virtual IP handling for the hsrpv2 Group State TLV.
  • Dispatch logic to distinguish hsrpv1 fixed-format packets from hsrpv2 tlv-based packets on UDP:1985.
  • ipv6 hsrpv2 binding on UDP:2029.
  • tests that check for hsrpv1 compatibility and hsrpv2 build behavior.

notes

previous behavior is intended to remain unchanged.

for ipv4 hsrpv2, UDP:1985 is shared with hsrpv1. because of that, i thought that Scapy should not automatically change the ipv4 destination address default to 224.0.0.102 in case it was meant for hsrpv1. this would mean that when building ipv4 hsrpv2 packets, users should explicitly set the multicast destination as:

IP(dst="224.0.0.102") / UDP(sport=1985, dport=1985) / HSRPv2()

instead of relying scapy to infer the destination automatically usually as shown below

IP() / UDP(sport=1985, dport=1985) / HSRPv2()

however, for IPv6 HSRPv2, there would be no issue, as this change would automatically binds hsrpv2 to UDP:2029 and ff02::66.

MD5 Authentication tlvs are dissected using HSRPv2MD5AuthTLV, which includes the algorithm, padding, flags, source IP, key ID, and authentication digest fields.

tests

on top of existing hsrpv1 tests, i checked for:

  • tlv build tests for hsrpv2's Group State/Text Authentication/Interface State/other unknowns
  • hsrpv2 dispatch on ipv4 (UDP:1985) and binding on ipv6 (UDP:2029)
  • ipv4 virtual IP encoding as a 4-byte ipv4 address to the 16-byte hsrpv2 virtual IP field and ipv6 virtual IP encoding as a full 16-byte ipv6 address.

closing remarks!

thanks for reviewing! please do let me know if there are any remarks or changes that i might need to make

@polybassa

Copy link
Copy Markdown
Contributor

Thanks for the PR!

@pengsies
pengsies force-pushed the feat/add-hsrpv2-support branch from 34d5336 to 00566d3 Compare July 3, 2026 14:34
@pengsies

pengsies commented Jul 9, 2026

Copy link
Copy Markdown
Author

oops no worries! thanks :D

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.34951% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.24%. Comparing base (326cf5e) to head (e821839).

Files with missing lines Patch % Lines
scapy/layers/hsrp.py 88.34% 12 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #5032   +/-   ##
=======================================
  Coverage   80.23%   80.24%           
=======================================
  Files         388      388           
  Lines       96517    96616   +99     
=======================================
+ Hits        77442    77525   +83     
- Misses      19075    19091   +16     
Files with missing lines Coverage Δ
scapy/layers/hsrp.py 89.11% <88.34%> (-2.56%) ⬇️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@polybassa

Copy link
Copy Markdown
Contributor

Please fix the code health checks.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds native TLV-based HSRPv2 parsing/building support to Scapy’s existing HSRP implementation, while aiming to preserve current HSRPv1 behavior (notably on UDP/1985 for IPv4).

Changes:

  • Added new HSRPv2 + TLV container/dispatch logic, including Group State / Interface State / Text Auth / MD5 Auth TLVs and unknown TLV preservation.
  • Updated UDP binding/dispatch to distinguish HSRPv1 vs HSRPv2 on IPv4 UDP/1985 and bind IPv6 HSRPv2 on UDP/2029 with ff02::66.
  • Added regression tests covering HSRPv1 compatibility and HSRPv2 TLV build/dissection behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
scapy/layers/hsrp.py Introduces the HSRPv2/TLV packet model and adjusts dispatch/binding logic for UDP/1985 (IPv4) and UDP/2029 (IPv6).
test/scapy/layers/hsrp.uts Adds tests for HSRPv2 TLV build/dissection, multi-TLV chaining, unknown TLVs, and IPv4/IPv6 port behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scapy/layers/hsrp.py Outdated
Comment on lines +302 to +306
"""
since port 1954 (UDP) would be shared by both hsrpv1 and hsprv2 (ipv4),
users building hsrpv2 (ipv4) packets should set IP(dst="224.0.0.102") explicitly to avoid using wrong multicast destination
"""
# DestIPField.bind_addr(UDP, "224.0.0.102", dport=1985)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edited :D

Comment thread scapy/layers/hsrp.py Outdated
Comment on lines +65 to +66
if tlvtype not in _HSRP_V2_TLV_TYPES:
return False

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

Comment thread scapy/layers/hsrp.py
@pengsies
pengsies force-pushed the feat/add-hsrpv2-support branch from 758055c to 577da9f Compare July 12, 2026 10:33
@polybassa

Copy link
Copy Markdown
Contributor

Please fix flake8

@pengsies
pengsies force-pushed the feat/add-hsrpv2-support branch from 577da9f to 8d35843 Compare July 14, 2026 22:50
@gpotter2 gpotter2 self-assigned this Jul 22, 2026
@pengsies
pengsies force-pushed the feat/add-hsrpv2-support branch from 8d35843 to df556c7 Compare July 22, 2026 16:30
@pengsies
pengsies force-pushed the feat/add-hsrpv2-support branch from df556c7 to e821839 Compare July 23, 2026 15:15
@pengsies

Copy link
Copy Markdown
Author

should be fixed now, i hope

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants