Skip to content

Commit

Permalink
fix: Fix the ARP packet parsing code to adapt to the scenario where t…
Browse files Browse the repository at this point in the history
…he switch adds extra padding bytes to ARP packets to meet the 64-byte minimum frame size.

Signed-off-by: jiasheng.yu <[email protected]>
  • Loading branch information
jiasheng.yu committed Jan 14, 2025
1 parent 009740f commit 9d77e4f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
10 changes: 10 additions & 0 deletions protocol/arp.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type ARP struct {
IPSrc net.IP
HWDst net.HardwareAddr
IPDst net.IP
// The actual test shows that ARP reply packets sent by the H3C switch include an additional 14 bytes.
// This is done by the switch to meet the minimum frame length requirement of 64 bytes.
Padding []byte
}

func NewARP(opt int) (*ARP, error) {
Expand All @@ -43,6 +46,8 @@ func NewARP(opt int) (*ARP, error) {
func (a *ARP) Len() (n uint16) {
n = 8
n += uint16(a.HWLength*2 + a.ProtoLength*2)
// Including the padding bytes, an inaccurate length can cause a panic in PacketIn2PropPacket.UnmarshalBinary.
n += uint16(len(a.Padding))
return
}

Expand Down Expand Up @@ -91,5 +96,10 @@ func (a *ARP) UnmarshalBinary(data []byte) error {
n += int(a.HWLength)
a.IPDst = make([]byte, a.ProtoLength)
copy(a.IPDst, data[n:n+int(a.ProtoLength)])
n += int(a.ProtoLength)
if len(data[n:]) > 0 {
a.Padding = make([]byte, len(data[n:]))
copy(a.Padding, data[n:])
}
return nil
}
18 changes: 18 additions & 0 deletions protocol/arp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package protocol

import (
"encoding/hex"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_ARPUnmarshalBinary(t *testing.T) {
data, err := hex.DecodeString("00010800060400027057bf301a03c0a8ac01525400ec4b98c0a8accc0000000000000000000000000000")
assert.Nil(t, err)
arp := new(ARP)
err = arp.UnmarshalBinary(data)
assert.Nil(t, err)
assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, arp.Padding)
assert.Equal(t, 42, arp.Len())
}

0 comments on commit 9d77e4f

Please sign in to comment.