udp4raw constructs a valid raw IPv4+UDP packet with proper checksums.
(t testing.TB, src, dst netip.Addr, sport, dport uint16, payload []byte)
| 1647 | |
| 1648 | // udp4raw constructs a valid raw IPv4+UDP packet with proper checksums. |
| 1649 | func udp4raw(t testing.TB, src, dst netip.Addr, sport, dport uint16, payload []byte) []byte { |
| 1650 | t.Helper() |
| 1651 | totalLen := header.IPv4MinimumSize + header.UDPMinimumSize + len(payload) |
| 1652 | buf := make([]byte, totalLen) |
| 1653 | |
| 1654 | ip := header.IPv4(buf) |
| 1655 | ip.Encode(&header.IPv4Fields{ |
| 1656 | TotalLength: uint16(totalLen), |
| 1657 | Protocol: uint8(header.UDPProtocolNumber), |
| 1658 | TTL: 64, |
| 1659 | SrcAddr: tcpip.AddrFrom4Slice(src.AsSlice()), |
| 1660 | DstAddr: tcpip.AddrFrom4Slice(dst.AsSlice()), |
| 1661 | }) |
| 1662 | ip.SetChecksum(^ip.CalculateChecksum()) |
| 1663 | |
| 1664 | // Build UDP header + payload. |
| 1665 | u := header.UDP(buf[header.IPv4MinimumSize:]) |
| 1666 | u.Encode(&header.UDPFields{ |
| 1667 | SrcPort: sport, |
| 1668 | DstPort: dport, |
| 1669 | Length: uint16(header.UDPMinimumSize + len(payload)), |
| 1670 | }) |
| 1671 | copy(buf[header.IPv4MinimumSize+header.UDPMinimumSize:], payload) |
| 1672 | |
| 1673 | xsum := header.PseudoHeaderChecksum( |
| 1674 | header.UDPProtocolNumber, |
| 1675 | tcpip.AddrFrom4Slice(src.AsSlice()), |
| 1676 | tcpip.AddrFrom4Slice(dst.AsSlice()), |
| 1677 | uint16(header.UDPMinimumSize+len(payload)), |
| 1678 | ) |
| 1679 | u.SetChecksum(^header.UDP(buf[header.IPv4MinimumSize:]).CalculateChecksum(xsum)) |
| 1680 | return buf |
| 1681 | } |
| 1682 | |
| 1683 | // TestInjectLoopback verifies that the inject goroutine delivers self-addressed |
| 1684 | // packets back into gVisor (via DeliverLoopback) instead of sending them to |
no test coverage detected
searching dependent graphs…