udp.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package packetparse
  2. import (
  3. "github.com/google/gopacket"
  4. "github.com/google/gopacket/layers"
  5. "github.com/v2fly/v2ray-core/v5/common/net"
  6. )
  7. var errNotIPPacket = newError("not an IP packet")
  8. var errNotUDPPacket = newError("not a UDP packet")
  9. var nullDestination = net.UnixDestination(net.DomainAddress("null"))
  10. func TryParseAsUDPPacket(packet []byte) (src, dst net.Destination, data []byte, err error) {
  11. parsedPacket := gopacket.NewPacket(packet, layers.LayerTypeIPv4, gopacket.DecodeOptions{
  12. Lazy: true,
  13. NoCopy: false,
  14. SkipDecodeRecovery: false,
  15. DecodeStreamsAsDatagrams: false,
  16. })
  17. var srcIP net.Address
  18. var dstIP net.Address
  19. ipv4Layer := parsedPacket.Layer(layers.LayerTypeIPv4)
  20. if ipv4Layer == nil {
  21. parsedPacketAsIPv6 := gopacket.NewPacket(packet, layers.LayerTypeIPv6, gopacket.DecodeOptions{
  22. Lazy: true,
  23. NoCopy: false,
  24. SkipDecodeRecovery: false,
  25. DecodeStreamsAsDatagrams: false,
  26. })
  27. ipv6Layer := parsedPacketAsIPv6.Layer(layers.LayerTypeIPv6)
  28. if ipv6Layer == nil {
  29. return nullDestination, nullDestination, nil, errNotIPPacket
  30. }
  31. ipv6 := ipv6Layer.(*layers.IPv6)
  32. srcIP = net.IPAddress(ipv6.SrcIP)
  33. dstIP = net.IPAddress(ipv6.DstIP)
  34. parsedPacket = parsedPacketAsIPv6
  35. } else {
  36. ipv4 := ipv4Layer.(*layers.IPv4)
  37. srcIP = net.IPAddress(ipv4.SrcIP)
  38. dstIP = net.IPAddress(ipv4.DstIP)
  39. }
  40. udpLayer := parsedPacket.Layer(layers.LayerTypeUDP)
  41. if udpLayer == nil {
  42. return nullDestination, nullDestination, nil, errNotUDPPacket
  43. }
  44. udp := udpLayer.(*layers.UDP)
  45. srcPort := net.Port(udp.SrcPort)
  46. dstPort := net.Port(udp.DstPort)
  47. src = net.UDPDestination(srcIP, srcPort)
  48. dst = net.UDPDestination(dstIP, dstPort)
  49. data = udp.Payload
  50. return
  51. }
  52. func TryConstructUDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {
  53. if src.Address.Family().IsIPv4() && dst.Address.Family().IsIPv4() {
  54. return constructIPv4UDPPacket(src, dst, data)
  55. }
  56. if src.Address.Family().IsIPv6() && dst.Address.Family().IsIPv6() {
  57. return constructIPv6UDPPacket(src, dst, data)
  58. }
  59. return nil, newError("not supported")
  60. }
  61. func constructIPv4UDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {
  62. ipv4 := &layers.IPv4{
  63. Version: 4,
  64. Protocol: layers.IPProtocolUDP,
  65. SrcIP: src.Address.IP(),
  66. DstIP: dst.Address.IP(),
  67. }
  68. udp := &layers.UDP{
  69. SrcPort: layers.UDPPort(src.Port),
  70. DstPort: layers.UDPPort(dst.Port),
  71. }
  72. err := udp.SetNetworkLayerForChecksum(ipv4)
  73. if err != nil {
  74. return nil, err
  75. }
  76. buffer := gopacket.NewSerializeBuffer()
  77. if err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{
  78. FixLengths: true,
  79. ComputeChecksums: true,
  80. }, ipv4, udp, gopacket.Payload(data)); err != nil {
  81. return nil, err
  82. }
  83. return buffer.Bytes(), nil
  84. }
  85. func constructIPv6UDPPacket(src, dst net.Destination, data []byte) ([]byte, error) {
  86. ipv6 := &layers.IPv6{
  87. Version: 6,
  88. NextHeader: layers.IPProtocolUDP,
  89. SrcIP: src.Address.IP(),
  90. DstIP: dst.Address.IP(),
  91. }
  92. udp := &layers.UDP{
  93. SrcPort: layers.UDPPort(src.Port),
  94. DstPort: layers.UDPPort(dst.Port),
  95. }
  96. err := udp.SetNetworkLayerForChecksum(ipv6)
  97. if err != nil {
  98. return nil, err
  99. }
  100. buffer := gopacket.NewSerializeBuffer()
  101. if err := gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{
  102. FixLengths: true,
  103. ComputeChecksums: true,
  104. }, ipv6, udp, gopacket.Payload(data)); err != nil {
  105. return nil, err
  106. }
  107. return buffer.Bytes(), nil
  108. }