@@ -26,6 +26,10 @@ const (
2626 // Port offsets in TCP/UDP headers
2727 sourcePortOffset = 0
2828 destinationPortOffset = 2
29+
30+ // IP address offsets in IPv4 header
31+ sourceIPOffset = 12
32+ destinationIPOffset = 16
2933)
3034
3135// ipv4Checksum calculates IPv4 header checksum.
@@ -374,17 +378,17 @@ func (m *Manager) translateInboundReverse(packetData []byte, d *decoder) bool {
374378 return true
375379}
376380
377- // rewritePacketDestination replaces the destination IP in the packet and updates checksums.
378- func (m * Manager ) rewritePacketDestination (packetData []byte , d * decoder , newIP netip.Addr ) error {
381+ // rewritePacketIP replaces an IP address (source or destination) in the packet and updates checksums.
382+ func (m * Manager ) rewritePacketIP (packetData []byte , d * decoder , newIP netip.Addr , ipOffset int ) error {
379383 if len (packetData ) < 20 || d .decoded [0 ] != layers .LayerTypeIPv4 || ! newIP .Is4 () {
380384 return ErrIPv4Only
381385 }
382386
383- var oldDst [4 ]byte
384- copy (oldDst [:], packetData [16 : 20 ])
385- newDst := newIP .As4 ()
387+ var oldIP [4 ]byte
388+ copy (oldIP [:], packetData [ipOffset : ipOffset + 4 ])
389+ newIPBytes := newIP .As4 ()
386390
387- copy (packetData [16 : 20 ], newDst [:])
391+ copy (packetData [ipOffset : ipOffset + 4 ], newIPBytes [:])
388392
389393 ipHeaderLen := int (d .ip4 .IHL ) * 4
390394 if ipHeaderLen < 20 || ipHeaderLen > len (packetData ) {
@@ -398,9 +402,9 @@ func (m *Manager) rewritePacketDestination(packetData []byte, d *decoder, newIP
398402 if len (d .decoded ) > 1 {
399403 switch d .decoded [1 ] {
400404 case layers .LayerTypeTCP :
401- m .updateTCPChecksum (packetData , ipHeaderLen , oldDst [:], newDst [:])
405+ m .updateTCPChecksum (packetData , ipHeaderLen , oldIP [:], newIPBytes [:])
402406 case layers .LayerTypeUDP :
403- m .updateUDPChecksum (packetData , ipHeaderLen , oldDst [:], newDst [:])
407+ m .updateUDPChecksum (packetData , ipHeaderLen , oldIP [:], newIPBytes [:])
404408 case layers .LayerTypeICMPv4 :
405409 m .updateICMPChecksum (packetData , ipHeaderLen )
406410 }
@@ -409,39 +413,14 @@ func (m *Manager) rewritePacketDestination(packetData []byte, d *decoder, newIP
409413 return nil
410414}
411415
416+ // rewritePacketDestination replaces the destination IP in the packet and updates checksums.
417+ func (m * Manager ) rewritePacketDestination (packetData []byte , d * decoder , newIP netip.Addr ) error {
418+ return m .rewritePacketIP (packetData , d , newIP , destinationIPOffset )
419+ }
420+
412421// rewritePacketSource replaces the source IP address in the packet and updates checksums.
413422func (m * Manager ) rewritePacketSource (packetData []byte , d * decoder , newIP netip.Addr ) error {
414- if len (packetData ) < 20 || d .decoded [0 ] != layers .LayerTypeIPv4 || ! newIP .Is4 () {
415- return ErrIPv4Only
416- }
417-
418- var oldSrc [4 ]byte
419- copy (oldSrc [:], packetData [12 :16 ])
420- newSrc := newIP .As4 ()
421-
422- copy (packetData [12 :16 ], newSrc [:])
423-
424- ipHeaderLen := int (d .ip4 .IHL ) * 4
425- if ipHeaderLen < 20 || ipHeaderLen > len (packetData ) {
426- return errInvalidIPHeaderLength
427- }
428-
429- binary .BigEndian .PutUint16 (packetData [10 :12 ], 0 )
430- ipChecksum := ipv4Checksum (packetData [:ipHeaderLen ])
431- binary .BigEndian .PutUint16 (packetData [10 :12 ], ipChecksum )
432-
433- if len (d .decoded ) > 1 {
434- switch d .decoded [1 ] {
435- case layers .LayerTypeTCP :
436- m .updateTCPChecksum (packetData , ipHeaderLen , oldSrc [:], newSrc [:])
437- case layers .LayerTypeUDP :
438- m .updateUDPChecksum (packetData , ipHeaderLen , oldSrc [:], newSrc [:])
439- case layers .LayerTypeICMPv4 :
440- m .updateICMPChecksum (packetData , ipHeaderLen )
441- }
442- }
443-
444- return nil
423+ return m .rewritePacketIP (packetData , d , newIP , sourceIPOffset )
445424}
446425
447426// updateTCPChecksum updates TCP checksum after IP address change per RFC 1624.
0 commit comments