Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow gratuitous ARP requests. #1684

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from

Conversation

Dimi1010
Copy link
Collaborator

@Dimi1010 Dimi1010 commented Jan 7, 2025

This PR is a potential implementation of #1682.

Specific header constructors

ArpLayer has been expanded with constructors accepting the following structures that build a respective ARP header inside the layer.

  • ArpRequest
  • ArpReply
  • GratuitousArpRequest
  • GratuitousArpReply

… / reply.

- NB: Removed zeroing of MAC address if the ArpLayer contains a opcode ARP_REQUEST.
- Added new structs with only required data to construct a certain packet.
@Dimi1010 Dimi1010 requested a review from seladb as a code owner January 7, 2025 22:11
@Dimi1010 Dimi1010 requested a review from tigercosmos January 7, 2025 22:12
@Dimi1010 Dimi1010 linked an issue Jan 7, 2025 that may be closed by this pull request
@Dimi1010 Dimi1010 marked this pull request as draft January 7, 2025 22:35
@Dimi1010 Dimi1010 force-pushed the refactor/gratuitous-arp-request branch from 679bdbd to d0a507a Compare January 8, 2025 07:46
- Added a new private constructor to handle populating the header.
The old constructor is forwarded to this one with the caveat that the target MAC address is ignored and zeroed if a request is to be made.
Copy link

codecov bot commented Jan 9, 2025

Codecov Report

Attention: Patch coverage is 97.90210% with 3 lines in your changes missing coverage. Please review.

Project coverage is 83.18%. Comparing base (bc5c08d) to head (0e0a69f).

Files with missing lines Patch % Lines
Packet++/src/ArpLayer.cpp 93.61% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1684      +/-   ##
==========================================
+ Coverage   82.54%   83.18%   +0.63%     
==========================================
  Files         277      277              
  Lines       48081    48294     +213     
  Branches     9341     9923     +582     
==========================================
+ Hits        39688    40171     +483     
+ Misses       7491     7228     -263     
+ Partials      902      895       -7     
Flag Coverage Δ
alpine320 75.18% <94.80%> (?)
fedora40 75.21% <94.80%> (?)
macos-13 80.69% <98.55%> (+0.04%) ⬆️
macos-14 80.69% <98.55%> (+0.04%) ⬆️
macos-15 80.66% <98.55%> (+0.04%) ⬆️
mingw32 70.90% <82.60%> (-0.02%) ⬇️
mingw64 70.84% <82.60%> (-0.02%) ⬇️
npcap 85.31% <95.23%> (+<0.01%) ⬆️
rhel94 75.05% <94.80%> (?)
ubuntu2004 58.55% <55.11%> (?)
ubuntu2004-zstd 58.67% <55.11%> (?)
ubuntu2204 74.97% <94.80%> (?)
ubuntu2204-icpx 61.43% <81.48%> (?)
ubuntu2404 75.22% <94.80%> (?)
unittest 83.18% <97.90%> (+0.63%) ⬆️
windows-2019 85.34% <95.23%> (+<0.01%) ⬆️
windows-2022 85.37% <95.23%> (+<0.01%) ⬆️
winpcap 85.33% <95.23%> (+0.01%) ⬆️
xdp 50.62% <89.61%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@seladb
Copy link
Owner

seladb commented Jan 10, 2025

@Dimi1010 the main issue I see with this approach is that it's quite strict and limits users to specific options to create ARP messages. Creating a non-standard ARP message is not possible unless they use the deprecated c'tor.

My suggestion here keeps the existing c'tor which gives the most freedom while creating another c'tor for gratuitous ARP requests which AFAIK are quite rarely used (no one requested it until now, even though ARP exists for many years in PcapPlusPlus)

@Dimi1010
Copy link
Collaborator Author

Dimi1010 commented Jan 10, 2025

@Dimi1010 the main issue I see with this approach is that it's quite strict and limits users to specific options to create ARP messages. Creating a non-standard ARP message is not possible unless they use the deprecated c'tor.

My suggestion here keeps the existing c'tor which gives the most freedom while creating another c'tor for gratuitous ARP requests which AFAIK are quite rarely used (no one requested it until now, even though ARP exists for many years in PcapPlusPlus)

Deprecating the current ctor is not really a requirement, I deprecated it because people might have been relying on the zeroing the target MAC functionality.

The new private ctor can also be exposed to allow ppl to construct whatever packets they want, which would probably work better, as the MAC addr wont be zeroed out under their feet if they dont want it.

@seladb
Copy link
Owner

seladb commented Jan 10, 2025

ing the current ctor is not really a requirement, I deprecated it because people might have been relying on the zeroing the target MAC functionality.

The new private ctor can also be exposed to

When I think about it, maybe we can just remove zeroing out targetMacAddr in computeCalculateFields() because we don't do it anywhere else 🤔

We probably need to update some tests and examples that use ARP (like Arping) which assume an ARP request always has a targetMacAddr of zero, but maybe that's the most flexible solution that provides a viable fix. The downside is that it's a breaking change for everyone who assumes it's zerod...

@Dimi1010
Copy link
Collaborator Author

Dimi1010 commented Jan 10, 2025

When I think about it, maybe we can just remove zeroing out targetMacAddr in computeCalculateFields() because we don't do it anywhere else 🤔

We probably need to update some tests and examples that use ARP (like Arping) which assume an ARP request always has a targetMacAddr of zero, but maybe that's the most flexible solution that provides a viable fix. The downside is that it's a breaking change for everyone who assumes it's zerod...

I can make the ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); constructor public. It would allow a gentler transition for those that use the zeroing, as the old one will be flagged as deprecated to allow them time to transition.

Also a standard ARP request should have the target mac zeroed. It is in the spec.

@Dimi1010 Dimi1010 marked this pull request as ready for review January 10, 2025 10:13
@Dimi1010 Dimi1010 requested a review from tigercosmos January 10, 2025 10:13
@seladb
Copy link
Owner

seladb commented Jan 11, 2025

When I think about it, maybe we can just remove zeroing out targetMacAddr in computeCalculateFields() because we don't do it anywhere else 🤔
We probably need to update some tests and examples that use ARP (like Arping) which assume an ARP request always has a targetMacAddr of zero, but maybe that's the most flexible solution that provides a viable fix. The downside is that it's a breaking change for everyone who assumes it's zerod...

I can make the ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr, const MacAddress& targetMacAddr, const IPv4Address& targetIpAddr); constructor public. It would allow a gentler transition for those that use the zeroing, as the old one will be flagged as deprecated to allow them time to transition.

Also a standard ARP request should have the target mac zeroed. It is in the spec.

You convinced me 🙂
If we keep the existing c'tor (not deprecated) then I guess we can add the additional c'tors with specific messages, and remove zeroing targetMacAddr

Copy link
Owner

@seladb seladb left a comment

Choose a reason for hiding this comment

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

There are also ARP layers generated in 3 places in ArpSpoofing that we can modify: https://github.com/seladb/PcapPlusPlus/blob/feba0b7124a4536ec2a0a947bc96c146ada099d7/Examples/ArpSpoofing/main.cpp

* @remarks No validation is done on the input parameters. The caller must ensure that the input creates a valid
* header.
*/
ArpLayer(ArpOpcode opCode, const MacAddress& senderMacAddr, const IPv4Address& senderIpAddr,
Copy link
Owner

Choose a reason for hiding this comment

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

Why do we need a new c'tor with the same params as the other c'tor but in a different order?

Copy link
Collaborator Author

@Dimi1010 Dimi1010 Jan 12, 2025

Choose a reason for hiding this comment

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

The new ctor is because the old one still zeroes the targetMacAddress to keep people who are expecting that from forming invalid arp requests. It just does it in the ctor instead of calculateFields.

The new constructor is there because:

  • The targetMacAddr is no longer zeroed. All parameters are directly written in the header.
  • Parameters are reordered because you cant have two constructors with identical signature. Also they are now ordered in the way they appear in the header.

}

{
// TODO: Add an actual packet to test against.
Copy link
Owner

Choose a reason for hiding this comment

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

You can use ArpResponsePacket.dat

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.

Can not build gratuitous ARP request properly
3 participants