Skip to content

feat: added hsrpv2 support layer#5032

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

feat: added hsrpv2 support layer#5032
pengsies wants to merge 6 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 be neat if ____, so i ____.
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 currently preserved as unknown tlvs rather than fully dissected, pending verified packet captures or specification confirmation for the exact ivp4/ipv6 layout.

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 84.61538% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.21%. Comparing base (f967117) to head (00566d3).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
scapy/layers/hsrp.py 84.61% 16 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5032      +/-   ##
==========================================
- Coverage   80.21%   80.21%   -0.01%     
==========================================
  Files         387      387              
  Lines       96405    96505     +100     
==========================================
+ Hits        77331    77409      +78     
- Misses      19074    19096      +22     
Files with missing lines Coverage Δ
scapy/layers/hsrp.py 86.48% <84.61%> (-5.19%) ⬇️

... 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
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)
Comment thread scapy/layers/hsrp.py
Comment on lines +65 to +66
if tlvtype not in _HSRP_V2_TLV_TYPES:
return False
Comment thread scapy/layers/hsrp.py
Comment on lines +234 to +238
class HSRPv2MD5AuthTLV(_HSRPv2TLVPayload):
name = "HSRPv2 MD5 Authentication TLV"
fields_desc = [
ByteEnumField("type", 4, _HSRP_V2_TLV_TYPES),
ByteField("len", None),
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.

3 participants