mirror of
https://github.com/soypat/lneto.git
synced 2026-08-21 15:09:05 +00:00
Checksum simplification proposal (#29)
* Simplified checksum calculation and verification * Fixed tests * UDP: using NewBoundedFrame to create a Frame instance limited to the actual frame size. * Minor: renamed some functions * Commented and made more readable consecutive SetCRC calls. * Fixed icmp checksum calculation after rebase * Replaced NewBoundedFrame with explicit validation
This commit is contained in:
+33
-53
@@ -161,27 +161,26 @@ func (pc *PacketBreakdown) CaptureIPv6(dst []Frame, pkt []byte, bitOffset int) (
|
||||
end := bitOffset + 40*octet
|
||||
var protoErrs []error
|
||||
var crc lneto.CRC791
|
||||
if proto == lneto.IPProtoTCP {
|
||||
ifrm6.CRCWritePseudo(&crc)
|
||||
tfrm, err := tcp.NewFrame(ifrm6.Payload())
|
||||
if err == nil {
|
||||
tfrm.CRCWrite(&crc)
|
||||
wantSum := crc.Sum16()
|
||||
gotSum := tfrm.CRC()
|
||||
if wantSum != gotSum {
|
||||
protoErrs = append(protoErrs, &crcError16{protocol: "ipv6+tcp", want: wantSum, got: gotSum})
|
||||
}
|
||||
ifrm6.CRCWritePseudo(&crc)
|
||||
switch proto {
|
||||
case lneto.IPProtoTCP:
|
||||
if crc.PayloadSum16(ifrm6.Payload()) != 0 {
|
||||
protoErrs = append(protoErrs, lneto.ErrBadCRC)
|
||||
}
|
||||
} else if proto == lneto.IPProtoUDP || proto == lneto.IPProtoUDPLite {
|
||||
ifrm6.CRCWritePseudo(&crc)
|
||||
case lneto.IPProtoUDP, lneto.IPProtoUDPLite:
|
||||
ufrm, err := udp.NewFrame(ifrm6.Payload())
|
||||
if err == nil {
|
||||
ufrm.CRCWriteIPv6(&crc)
|
||||
wantSum := crc.Sum16()
|
||||
gotSum := ufrm.CRC()
|
||||
if wantSum != gotSum {
|
||||
protoErrs = append(protoErrs, &crcError16{protocol: "ipv6+udp", want: wantSum, got: gotSum})
|
||||
}
|
||||
if err != nil {
|
||||
protoErrs = append(protoErrs, err)
|
||||
break
|
||||
}
|
||||
ufrm.ValidateSize(pc.validator())
|
||||
if err = pc.validator().ErrPop(); err != nil {
|
||||
protoErrs = append(protoErrs, err)
|
||||
break
|
||||
}
|
||||
frameLen := ufrm.Length()
|
||||
if crc.PayloadSum16(ufrm.RawData()[:frameLen]) != 0 {
|
||||
protoErrs = append(protoErrs, lneto.ErrBadCRC)
|
||||
}
|
||||
}
|
||||
return pc.captureIPProto(proto, dst, pkt, end, protoErrs...)
|
||||
@@ -214,57 +213,48 @@ func (pc *PacketBreakdown) CaptureIPv4(dst []Frame, pkt []byte, bitOffset int) (
|
||||
BitLength: octet * len(options),
|
||||
})
|
||||
}
|
||||
gotSum := ifrm4.CRC()
|
||||
wantSum := ifrm4.CalculateHeaderCRC()
|
||||
if gotSum != wantSum {
|
||||
finfo.Errors = append(finfo.Errors, &crcError16{protocol: "ipv4", want: wantSum, got: gotSum})
|
||||
if ifrm4.CalculateHeaderCRC() != 0 {
|
||||
finfo.Errors = append(finfo.Errors, lneto.ErrBadCRC)
|
||||
}
|
||||
dst = append(dst, finfo)
|
||||
proto := ifrm4.Protocol()
|
||||
end := bitOffset + octet*ifrm4.HeaderLength()
|
||||
var protoErrs []error
|
||||
var crc lneto.CRC791
|
||||
payload := ifrm4.Payload()
|
||||
switch proto {
|
||||
case lneto.IPProtoTCP:
|
||||
ifrm4.CRCWriteTCPPseudo(&crc)
|
||||
tfrm, err := tcp.NewFrame(ifrm4.Payload())
|
||||
tfrm, err := tcp.NewFrame(payload)
|
||||
if err == nil {
|
||||
tfrm.ValidateSize(pc.validator())
|
||||
if pc.vld.HasError() {
|
||||
println("BAD TCP")
|
||||
return dst, pc.vld.ErrPop()
|
||||
}
|
||||
tfrm.CRCWrite(&crc)
|
||||
wantSum := crc.Sum16()
|
||||
gotSum := tfrm.CRC()
|
||||
if wantSum != gotSum {
|
||||
protoErrs = append(protoErrs, &crcError16{protocol: "ipv4+tcp", want: wantSum, got: gotSum})
|
||||
ifrm4.CRCWriteTCPPseudo(&crc)
|
||||
if crc.PayloadSum16(payload) != 0 {
|
||||
protoErrs = append(protoErrs, lneto.ErrBadCRC)
|
||||
}
|
||||
}
|
||||
case lneto.IPProtoUDP:
|
||||
ifrm4.CRCWriteUDPPseudo(&crc)
|
||||
ufrm, err := udp.NewFrame(ifrm4.Payload())
|
||||
ufrm, err := udp.NewFrame(payload)
|
||||
if err == nil {
|
||||
ufrm.ValidateSize(pc.validator())
|
||||
if pc.vld.HasError() {
|
||||
println("BAD UDP")
|
||||
return dst, pc.vld.ErrPop()
|
||||
}
|
||||
ufrm.CRCWriteIPv4(&crc)
|
||||
wantSum := crc.Sum16()
|
||||
gotSum := ufrm.CRC()
|
||||
if wantSum != gotSum {
|
||||
protoErrs = append(protoErrs, &crcError16{protocol: "ipv4+udp", want: wantSum, got: gotSum})
|
||||
frameLen := ufrm.Length()
|
||||
ifrm4.CRCWriteUDPPseudo(&crc, frameLen)
|
||||
if crc.PayloadSum16(ufrm.RawData()[:frameLen]) != 0 {
|
||||
protoErrs = append(protoErrs, lneto.ErrBadCRC)
|
||||
}
|
||||
}
|
||||
case lneto.IPProtoICMP:
|
||||
ifrm, err := icmpv4.NewFrame(ifrm4.Payload())
|
||||
_, err := icmpv4.NewFrame(payload)
|
||||
if err == nil {
|
||||
ifrm.CRCWrite(&crc)
|
||||
wantSum := crc.Sum16()
|
||||
gotSum := ifrm.CRC()
|
||||
if wantSum != gotSum {
|
||||
protoErrs = append(protoErrs, &crcError16{protocol: "icmpv4", want: wantSum, got: gotSum})
|
||||
if crc.PayloadSum16(payload) != 0 {
|
||||
protoErrs = append(protoErrs, lneto.ErrBadCRC)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1309,13 +1299,3 @@ func remainingFrameInfo(proto any, class FieldClass, pktBitOffset, pktBitLen int
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
type crcError16 struct {
|
||||
protocol string
|
||||
want uint16
|
||||
got uint16
|
||||
}
|
||||
|
||||
func (cerr *crcError16) Error() string {
|
||||
return fmt.Sprintf("%s:incorrect checksum. want 0x%x, got 0x%x", cerr.protocol, cerr.want, cerr.got)
|
||||
}
|
||||
|
||||
@@ -447,6 +447,7 @@ func ExampleFormatter_dhcp() {
|
||||
totalLen := ipv4Size + udpSize + dhcpLen
|
||||
ifrm.SetTotalLength(uint16(totalLen))
|
||||
ufrm.SetLength(uint16(udpSize + dhcpLen))
|
||||
// The CRC field is already zero here.
|
||||
ifrm.SetCRC(ifrm.CalculateHeaderCRC())
|
||||
|
||||
pkt = pkt[:ethSize+totalLen]
|
||||
|
||||
Reference in New Issue
Block a user