packet_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. package iputil
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "net"
  6. "testing"
  7. "github.com/stretchr/testify/assert"
  8. "golang.org/x/net/ipv4"
  9. "golang.org/x/net/ipv6"
  10. )
  11. func Test_CreateRejectPacket(t *testing.T) {
  12. h := ipv4.Header{
  13. Len: 20,
  14. Src: net.IPv4(10, 0, 0, 1),
  15. Dst: net.IPv4(10, 0, 0, 2),
  16. Protocol: 1, // ICMP
  17. }
  18. b, err := h.Marshal()
  19. if err != nil {
  20. t.Fatalf("h.Marhshal: %v", err)
  21. }
  22. b = append(b, []byte{0, 3, 0, 4}...)
  23. expectedLen := ipv4.HeaderLen + 8 + h.Len + 4
  24. out := make([]byte, expectedLen)
  25. rejectPacket := CreateRejectPacket(b, out)
  26. assert.NotNil(t, rejectPacket)
  27. assert.Len(t, rejectPacket, expectedLen)
  28. // ICMP with max header len
  29. h = ipv4.Header{
  30. Len: 60,
  31. Src: net.IPv4(10, 0, 0, 1),
  32. Dst: net.IPv4(10, 0, 0, 2),
  33. Protocol: 1, // ICMP
  34. Options: make([]byte, 40),
  35. }
  36. b, err = h.Marshal()
  37. if err != nil {
  38. t.Fatalf("h.Marhshal: %v", err)
  39. }
  40. b = append(b, []byte{0, 3, 0, 4, 0, 0, 0, 0}...)
  41. expectedLen = maxIPv4RejectPacketSize
  42. out = make([]byte, MaxRejectPacketSize)
  43. rejectPacket = CreateRejectPacket(b, out)
  44. assert.NotNil(t, rejectPacket)
  45. assert.Len(t, rejectPacket, expectedLen)
  46. // TCP with max header len
  47. h = ipv4.Header{
  48. Len: 60,
  49. Src: net.IPv4(10, 0, 0, 1),
  50. Dst: net.IPv4(10, 0, 0, 2),
  51. Protocol: 6, // TCP
  52. Options: make([]byte, 40),
  53. }
  54. b, err = h.Marshal()
  55. if err != nil {
  56. t.Fatalf("h.Marhshal: %v", err)
  57. }
  58. b = append(b, []byte{0, 3, 0, 4}...)
  59. b = append(b, make([]byte, 16)...)
  60. expectedLen = ipv4.HeaderLen + 20
  61. out = make([]byte, expectedLen)
  62. rejectPacket = CreateRejectPacket(b, out)
  63. assert.NotNil(t, rejectPacket)
  64. assert.Len(t, rejectPacket, expectedLen)
  65. }
  66. func Test_CreateRejectPacket_NoFragment(t *testing.T) {
  67. out := make([]byte, MaxRejectPacketSize)
  68. // IPv4: non-zero fragment offset should not generate reject packet
  69. h := ipv4.Header{
  70. Len: 20,
  71. Src: net.IPv4(10, 0, 0, 1),
  72. Dst: net.IPv4(10, 0, 0, 2),
  73. Protocol: 17, // UDP
  74. }
  75. b, err := h.Marshal()
  76. if err != nil {
  77. t.Fatalf("h.Marshal: %v", err)
  78. }
  79. b = append(b, make([]byte, 8)...)
  80. // Set fragment offset to non-zero (byte 6-7, offset in 8-byte units)
  81. b[6] = 0x00
  82. b[7] = 0x01
  83. assert.Nil(t, CreateRejectPacket(b, out))
  84. // MF flag with zero offset (first fragment) should still generate reject
  85. b[6] = 0x20 // MF flag set
  86. b[7] = 0x00
  87. assert.NotNil(t, CreateRejectPacket(b, out))
  88. // Non-fragment should still generate reject packet
  89. b[6] = 0x00
  90. b[7] = 0x00
  91. assert.NotNil(t, CreateRejectPacket(b, out))
  92. // DF flag only (not a fragment) should still generate reject packet
  93. b[6] = 0x40
  94. b[7] = 0x00
  95. assert.NotNil(t, CreateRejectPacket(b, out))
  96. }
  97. func Test_CreateRejectPacketIPv6_NoFragment(t *testing.T) {
  98. src := net.ParseIP("fd00::1")
  99. dst := net.ParseIP("fd00::2")
  100. out := make([]byte, MaxRejectPacketSize)
  101. // IPv6 with Fragment header and non-zero offset should not generate reject
  102. fragHeader := []byte{
  103. 17, // next header: UDP
  104. 0, // reserved
  105. 0, 9, // fragment offset=1 (shifted left 3), M=1
  106. 0, 0, 0, 1, // identification
  107. }
  108. udpPayload := make([]byte, 8)
  109. payload := append(fragHeader, udpPayload...)
  110. packet := makeIPv6Packet(src, dst, 44, payload) // next header 44 = Fragment
  111. assert.Nil(t, CreateRejectPacket(packet, out))
  112. // Fragment header with zero offset (first fragment) should still generate reject
  113. fragHeader[2] = 0
  114. fragHeader[3] = 1 // offset=0, M=1
  115. payload = append(fragHeader, udpPayload...)
  116. packet = makeIPv6Packet(src, dst, 44, payload)
  117. assert.NotNil(t, CreateRejectPacket(packet, out))
  118. }
  119. func Test_CreateRejectPacket_NoICMPError(t *testing.T) {
  120. out := make([]byte, MaxRejectPacketSize)
  121. // ICMP error types should not generate reject packets
  122. icmpErrorTypes := []byte{3, 4, 5, 11, 12}
  123. for _, icmpType := range icmpErrorTypes {
  124. h := ipv4.Header{
  125. Len: 20,
  126. Src: net.IPv4(10, 0, 0, 1),
  127. Dst: net.IPv4(10, 0, 0, 2),
  128. Protocol: 1, // ICMP
  129. }
  130. b, err := h.Marshal()
  131. if err != nil {
  132. t.Fatalf("h.Marshal: %v", err)
  133. }
  134. b = append(b, icmpType, 0, 0, 0, 0, 0, 0, 0)
  135. rejectPacket := CreateRejectPacket(b, out)
  136. assert.Nil(t, rejectPacket, "ICMP type %d should not generate a reject packet", icmpType)
  137. }
  138. // ICMP non-error types should still generate reject packets
  139. icmpNonErrorTypes := []byte{0, 8, 13, 14}
  140. for _, icmpType := range icmpNonErrorTypes {
  141. h := ipv4.Header{
  142. Len: 20,
  143. Src: net.IPv4(10, 0, 0, 1),
  144. Dst: net.IPv4(10, 0, 0, 2),
  145. Protocol: 1, // ICMP
  146. }
  147. b, err := h.Marshal()
  148. if err != nil {
  149. t.Fatalf("h.Marshal: %v", err)
  150. }
  151. b = append(b, icmpType, 0, 0, 0, 0, 0, 0, 0)
  152. rejectPacket := CreateRejectPacket(b, out)
  153. assert.NotNil(t, rejectPacket, "ICMP type %d should generate a reject packet", icmpType)
  154. }
  155. }
  156. // Test_CreateRejectPacket_RespectsCap ensures it is impossible for
  157. // an oversized ICMPv6 reject to overwrite the neighbor segment's bytes.
  158. func Test_CreateRejectPacket_RespectsCap(t *testing.T) {
  159. src := net.ParseIP("fd00::1")
  160. dst := net.ParseIP("fd00::2")
  161. // Inner IPv6 UDP packet. An ICMPv6 reject copies the whole inner packet
  162. // plus a 48-byte header (40 IPv6 + 8 ICMPv6), so it needs 48 more bytes
  163. // than the inner packet length.
  164. inner := makeIPv6Packet(src, dst, 17, make([]byte, 20))
  165. // The ciphertext scratch reused as the reject buffer is the received
  166. // datagram: 16-byte Nebula header + inner + 16-byte AEAD tag. That is only
  167. // 32 bytes of slack, so a full ICMPv6 reject overruns it by 16 bytes.
  168. const nebulaOverhead = 32
  169. segLen := len(inner) + nebulaOverhead
  170. // Shared backing row laid out as [segment][neighbor's 16-byte Nebula header].
  171. const neighborHdr = 16
  172. sentinel := bytes.Repeat([]byte{0xAB}, neighborHdr)
  173. // Uncapped: the slice's capacity reaches into the neighbor, reproducing
  174. // the overrun that silently drops the neighbor packet.
  175. backing := make([]byte, segLen+neighborHdr)
  176. copy(backing[segLen:], sentinel)
  177. reject := CreateRejectPacket(inner, backing[:segLen])
  178. assert.NotNil(t, reject, "uncapped buffer reaches into the neighbor, so the reject is built")
  179. assert.NotEqual(t, sentinel, backing[segLen:segLen+neighborHdr],
  180. "without the cap the oversized reject overruns into the neighbor segment")
  181. // Capped (the fix): cap==len, so the builder cannot exceed the segment. The
  182. // reject does not fit, so it is refused rather than corrupting the neighbor.
  183. backing = make([]byte, segLen+neighborHdr)
  184. copy(backing[segLen:], sentinel)
  185. reject = CreateRejectPacket(inner, backing[:segLen:segLen])
  186. assert.Nil(t, reject, "capped segment is 16 bytes too small for a full ICMPv6 reject, so it is refused")
  187. assert.Equal(t, sentinel, backing[segLen:segLen+neighborHdr],
  188. "capped segment must leave the neighbor untouched")
  189. }
  190. func makeIPv6Packet(src, dst net.IP, nextHeader uint8, payload []byte) []byte {
  191. b := make([]byte, ipv6.HeaderLen+len(payload))
  192. b[0] = ipv6.Version << 4
  193. binary.BigEndian.PutUint16(b[4:], uint16(len(payload)))
  194. b[6] = nextHeader
  195. b[7] = 64
  196. copy(b[8:24], src.To16())
  197. copy(b[24:40], dst.To16())
  198. copy(b[ipv6.HeaderLen:], payload)
  199. return b
  200. }
  201. func Test_CreateRejectPacketIPv6_ICMP(t *testing.T) {
  202. src := net.ParseIP("fd00::1")
  203. dst := net.ParseIP("fd00::2")
  204. // Small UDP packet: entire original included in body
  205. udpPayload := make([]byte, 20)
  206. udpPayload[0] = 0x00 // src port high
  207. udpPayload[1] = 0x50 // src port low (80)
  208. udpPayload[2] = 0x01 // dst port high
  209. udpPayload[3] = 0xBB // dst port low (443)
  210. packet := makeIPv6Packet(src, dst, 17, udpPayload)
  211. out := make([]byte, MaxRejectPacketSize)
  212. rejectPacket := CreateRejectPacket(packet, out)
  213. assert.NotNil(t, rejectPacket)
  214. // Small packet fits entirely: 40 (ipv6 hdr) + 8 (icmpv6 hdr) + 60 (original)
  215. expectedLen := ipv6.HeaderLen + 8 + len(packet)
  216. assert.Len(t, rejectPacket, expectedLen)
  217. // Verify version
  218. assert.Equal(t, byte(ipv6.Version<<4), rejectPacket[0]&0xf0)
  219. // Verify next header is ICMPv6 (58)
  220. assert.Equal(t, byte(58), rejectPacket[6])
  221. // Verify src/dst are swapped
  222. assert.Equal(t, dst.To16(), net.IP(rejectPacket[8:24]))
  223. assert.Equal(t, src.To16(), net.IP(rejectPacket[24:40]))
  224. // Verify ICMPv6 type=1 (Dest Unreachable), code=1 (Administratively prohibited)
  225. assert.Equal(t, byte(1), rejectPacket[ipv6.HeaderLen])
  226. assert.Equal(t, byte(1), rejectPacket[ipv6.HeaderLen+1])
  227. // Verify entire original packet is included in body
  228. assert.Equal(t, packet, rejectPacket[ipv6.HeaderLen+8:])
  229. // Large packet: body is truncated to 1000 bytes
  230. largePkt := makeIPv6Packet(src, dst, 17, make([]byte, 1200))
  231. rejectPacket = CreateRejectPacket(largePkt, out)
  232. assert.NotNil(t, rejectPacket)
  233. assert.Len(t, rejectPacket, ipv6.HeaderLen+8+1000)
  234. assert.Equal(t, largePkt[:1000], rejectPacket[ipv6.HeaderLen+8:])
  235. }
  236. func Test_CreateRejectPacketIPv6_TCP(t *testing.T) {
  237. src := net.ParseIP("fd00::1")
  238. dst := net.ParseIP("fd00::2")
  239. // TCP SYN packet (next header 6)
  240. tcpPayload := make([]byte, 20)
  241. tcpPayload[0] = 0x00 // src port high
  242. tcpPayload[1] = 0x50 // src port low (80)
  243. tcpPayload[2] = 0x01 // dst port high
  244. tcpPayload[3] = 0xBB // dst port low (443)
  245. binary.BigEndian.PutUint32(tcpPayload[4:], 1000) // seq
  246. binary.BigEndian.PutUint32(tcpPayload[8:], 0) // ack seq
  247. tcpPayload[12] = (20 >> 2) << 4 // data offset
  248. tcpPayload[13] = 0b00000010 // SYN flag
  249. packet := makeIPv6Packet(src, dst, 6, tcpPayload)
  250. out := make([]byte, MaxRejectPacketSize)
  251. rejectPacket := CreateRejectPacket(packet, out)
  252. assert.NotNil(t, rejectPacket)
  253. // Expected: 40 (ipv6 hdr) + 20 (tcp RST)
  254. expectedLen := ipv6.HeaderLen + 20
  255. assert.Len(t, rejectPacket, expectedLen)
  256. // Verify version
  257. assert.Equal(t, byte(ipv6.Version<<4), rejectPacket[0]&0xf0)
  258. // Verify next header is TCP (6)
  259. assert.Equal(t, byte(6), rejectPacket[6])
  260. // Verify src/dst are swapped
  261. assert.Equal(t, dst.To16(), net.IP(rejectPacket[8:24]))
  262. assert.Equal(t, src.To16(), net.IP(rejectPacket[24:40]))
  263. // Verify ports are swapped
  264. tcpOut := rejectPacket[ipv6.HeaderLen:]
  265. assert.Equal(t, uint16(443), binary.BigEndian.Uint16(tcpOut[0:2]))
  266. assert.Equal(t, uint16(80), binary.BigEndian.Uint16(tcpOut[2:4]))
  267. // RST+ACK flags (since input was SYN without ACK)
  268. assert.Equal(t, byte(0b00010100), tcpOut[13])
  269. // ack_seq = original seq (1000) + SYN (1) + FIN (0) + segment data (0)
  270. assert.Equal(t, uint32(1001), binary.BigEndian.Uint32(tcpOut[8:]))
  271. }
  272. func Test_CreateRejectPacketIPv6_TCPWithACK(t *testing.T) {
  273. src := net.ParseIP("fd00::1")
  274. dst := net.ParseIP("fd00::2")
  275. // TCP packet with ACK set
  276. tcpPayload := make([]byte, 20)
  277. tcpPayload[0] = 0x00
  278. tcpPayload[1] = 0x50
  279. tcpPayload[2] = 0x01
  280. tcpPayload[3] = 0xBB
  281. binary.BigEndian.PutUint32(tcpPayload[4:], 1000) // seq
  282. binary.BigEndian.PutUint32(tcpPayload[8:], 2000) // ack seq
  283. tcpPayload[12] = (20 >> 2) << 4 // data offset
  284. tcpPayload[13] = 0b00010000 // ACK flag
  285. packet := makeIPv6Packet(src, dst, 6, tcpPayload)
  286. out := make([]byte, MaxRejectPacketSize)
  287. rejectPacket := CreateRejectPacket(packet, out)
  288. assert.NotNil(t, rejectPacket)
  289. tcpOut := rejectPacket[ipv6.HeaderLen:]
  290. // RST only (no ACK) since input had ACK
  291. assert.Equal(t, byte(0b00000100), tcpOut[13])
  292. // seq = original ack_seq
  293. assert.Equal(t, uint32(2000), binary.BigEndian.Uint32(tcpOut[4:]))
  294. }
  295. func Test_CreateRejectPacketIPv6_NoICMPError(t *testing.T) {
  296. src := net.ParseIP("fd00::1")
  297. dst := net.ParseIP("fd00::2")
  298. out := make([]byte, MaxRejectPacketSize)
  299. // ICMPv6 error types (1-4) should not generate reject packets
  300. for icmpType := byte(1); icmpType <= 4; icmpType++ {
  301. payload := make([]byte, 8)
  302. payload[0] = icmpType
  303. packet := makeIPv6Packet(src, dst, 58, payload)
  304. rejectPacket := CreateRejectPacket(packet, out)
  305. assert.Nil(t, rejectPacket, "ICMPv6 type %d should not generate a reject packet", icmpType)
  306. }
  307. // ICMPv6 non-error types should still generate reject packets
  308. nonErrorTypes := []byte{128, 129, 133, 134}
  309. for _, icmpType := range nonErrorTypes {
  310. payload := make([]byte, 8)
  311. payload[0] = icmpType
  312. packet := makeIPv6Packet(src, dst, 58, payload)
  313. rejectPacket := CreateRejectPacket(packet, out)
  314. assert.NotNil(t, rejectPacket, "ICMPv6 type %d should generate a reject packet", icmpType)
  315. }
  316. }
  317. func Test_CreateRejectPacketIPv6_TooShort(t *testing.T) {
  318. // Packet too short to be valid IPv6
  319. out := make([]byte, MaxRejectPacketSize)
  320. assert.Nil(t, CreateRejectPacket([]byte{0x60}, out))
  321. assert.Nil(t, CreateRejectPacket(make([]byte, 39), out))
  322. }
  323. func Test_CreateRejectPacketIPv6_ExtensionHeaders(t *testing.T) {
  324. src := net.ParseIP("fd00::1")
  325. dst := net.ParseIP("fd00::2")
  326. // IPv6 + Hop-by-Hop extension header + TCP
  327. hopByHop := []byte{
  328. 6, // next header: TCP
  329. 0, // length (8 bytes total)
  330. 0, 0, // padding
  331. 0, 0, 0, 0,
  332. }
  333. tcpPayload := make([]byte, 20)
  334. tcpPayload[0] = 0x00
  335. tcpPayload[1] = 0x50
  336. tcpPayload[2] = 0x01
  337. tcpPayload[3] = 0xBB
  338. binary.BigEndian.PutUint32(tcpPayload[4:], 1000)
  339. binary.BigEndian.PutUint32(tcpPayload[8:], 2000)
  340. tcpPayload[12] = (20 >> 2) << 4
  341. tcpPayload[13] = 0b00010000 // ACK
  342. payload := append(hopByHop, tcpPayload...)
  343. packet := makeIPv6Packet(src, dst, 0, payload) // next header 0 = Hop-by-Hop
  344. out := make([]byte, MaxRejectPacketSize)
  345. rejectPacket := CreateRejectPacket(packet, out)
  346. assert.NotNil(t, rejectPacket)
  347. // Should produce TCP RST
  348. expectedLen := ipv6.HeaderLen + 20
  349. assert.Len(t, rejectPacket, expectedLen)
  350. assert.Equal(t, byte(6), rejectPacket[6]) // next header is TCP
  351. tcpOut := rejectPacket[ipv6.HeaderLen:]
  352. assert.Equal(t, byte(0b00000100), tcpOut[13]) // RST only
  353. }
  354. func TestCreateICMPEchoResponse_IPv4(t *testing.T) {
  355. // Build a simple IPv4 ICMP Echo Request
  356. packet := make([]byte, 28)
  357. packet[0] = 0x45 // version 4, IHL 5
  358. binary.BigEndian.PutUint16(packet[2:], uint16(28)) // total length
  359. packet[8] = 64 // TTL
  360. packet[9] = 1 // protocol ICMP
  361. copy(packet[12:16], net.IPv4(10, 0, 0, 1).To4()) // src
  362. copy(packet[16:20], net.IPv4(10, 0, 0, 2).To4()) // dst
  363. packet[20] = 8 // ICMP Echo Request
  364. out := make([]byte, len(packet))
  365. result := CreateICMPEchoResponse(packet, out)
  366. assert.NotNil(t, result)
  367. assert.Equal(t, byte(0x45), result[0])
  368. // src/dst swapped
  369. assert.Equal(t, net.IPv4(10, 0, 0, 2).To4(), net.IP(result[12:16]))
  370. assert.Equal(t, net.IPv4(10, 0, 0, 1).To4(), net.IP(result[16:20]))
  371. // ICMP Echo Reply
  372. assert.Equal(t, byte(0), result[20])
  373. }
  374. func TestCreateICMPEchoResponse_IPv6(t *testing.T) {
  375. src := net.ParseIP("fd00::1").To16()
  376. dst := net.ParseIP("fd00::2").To16()
  377. // Build an IPv6 ICMPv6 Echo Request packet
  378. // IPv6 header (40 bytes) + ICMPv6 (8 bytes)
  379. packet := make([]byte, 48)
  380. packet[0] = 0x60 // version 6
  381. payloadLen := uint16(8) // ICMPv6 header only
  382. binary.BigEndian.PutUint16(packet[4:], payloadLen)
  383. packet[6] = 58 // Next Header: ICMPv6
  384. packet[7] = 64 // Hop Limit
  385. copy(packet[8:24], src) // src address
  386. copy(packet[24:40], dst) // dst address
  387. // ICMPv6 Echo Request
  388. icmp := packet[40:]
  389. icmp[0] = 128 // type: Echo Request
  390. icmp[1] = 0 // code
  391. binary.BigEndian.PutUint16(icmp[4:], 1) // identifier
  392. binary.BigEndian.PutUint16(icmp[6:], 1) // sequence number
  393. // Compute correct checksum for the request
  394. csum := ipv6PseudoheaderChecksum(src, dst, 58, uint32(payloadLen))
  395. binary.BigEndian.PutUint16(icmp[2:], tcpipChecksum(icmp, csum))
  396. out := make([]byte, len(packet))
  397. result := CreateICMPEchoResponse(packet, out)
  398. assert.NotNil(t, result)
  399. // Version should still be 6
  400. assert.Equal(t, byte(6), result[0]>>4)
  401. // src/dst swapped
  402. assert.Equal(t, dst, net.IP(result[8:24]))
  403. assert.Equal(t, src, net.IP(result[24:40]))
  404. // ICMPv6 Echo Reply type
  405. assert.Equal(t, byte(129), result[40])
  406. // Verify checksum is valid (tcpipChecksum returns 0 when data+checksum is correct)
  407. respIcmp := result[40:]
  408. verifyCsum := ipv6PseudoheaderChecksum(result[8:24], result[24:40], 58, uint32(payloadLen))
  409. assert.Equal(t, uint16(0), tcpipChecksum(respIcmp, verifyCsum))
  410. }
  411. func TestCreateICMPEchoResponse_IPv6_NotEchoRequest(t *testing.T) {
  412. src := net.ParseIP("fd00::1").To16()
  413. dst := net.ParseIP("fd00::2").To16()
  414. packet := make([]byte, 48)
  415. packet[0] = 0x60
  416. binary.BigEndian.PutUint16(packet[4:], 8)
  417. packet[6] = 58
  418. packet[7] = 64
  419. copy(packet[8:24], src)
  420. copy(packet[24:40], dst)
  421. // ICMPv6 type 1 (Destination Unreachable) - not Echo Request
  422. packet[40] = 1
  423. out := make([]byte, len(packet))
  424. result := CreateICMPEchoResponse(packet, out)
  425. assert.Nil(t, result)
  426. }
  427. func TestCreateICMPEchoResponse_IPv6_NotICMPv6(t *testing.T) {
  428. src := net.ParseIP("fd00::1").To16()
  429. dst := net.ParseIP("fd00::2").To16()
  430. packet := make([]byte, 48)
  431. packet[0] = 0x60
  432. binary.BigEndian.PutUint16(packet[4:], 8)
  433. packet[6] = 6 // TCP, not ICMPv6
  434. packet[7] = 64
  435. copy(packet[8:24], src)
  436. copy(packet[24:40], dst)
  437. out := make([]byte, len(packet))
  438. result := CreateICMPEchoResponse(packet, out)
  439. assert.Nil(t, result)
  440. }