net/netcheck: fix offset of unspecified address in PCP request packet

Fixes #810

(cherry picked from commit 08f94b3b50)
release-branch/1.2
Brad Fitzpatrick 4 years ago
parent aaac9cb0a2
commit e1e930d1f3

@ -756,6 +756,7 @@ var uPnPPacket = []byte("M-SEARCH * HTTP/1.1\r\n" +
var v4unspec, _ = netaddr.ParseIP("0.0.0.0") var v4unspec, _ = netaddr.ParseIP("0.0.0.0")
// pcpPacket generates a PCP packet with a MAP opcode.
func pcpPacket(myIP netaddr.IP, mapToLocalPort int, delete bool) []byte { func pcpPacket(myIP netaddr.IP, mapToLocalPort int, delete bool) []byte {
const udpProtoNumber = 17 const udpProtoNumber = 17
lifetimeSeconds := uint32(1) lifetimeSeconds := uint32(1)
@ -763,17 +764,24 @@ func pcpPacket(myIP netaddr.IP, mapToLocalPort int, delete bool) []byte {
lifetimeSeconds = 0 lifetimeSeconds = 0
} }
const opMap = 1 const opMap = 1
// 24 byte header + 36 byte map opcode
pkt := make([]byte, (32+32+128)/8+(96+8+24+16+16+128)/8) pkt := make([]byte, (32+32+128)/8+(96+8+24+16+16+128)/8)
// The header (https://tools.ietf.org/html/rfc6887#section-7.1)
pkt[0] = 2 // version pkt[0] = 2 // version
pkt[1] = opMap pkt[1] = opMap
binary.BigEndian.PutUint32(pkt[4:8], lifetimeSeconds) binary.BigEndian.PutUint32(pkt[4:8], lifetimeSeconds)
myIP16 := myIP.As16() myIP16 := myIP.As16()
copy(pkt[8:], myIP16[:]) copy(pkt[8:], myIP16[:])
rand.Read(pkt[24 : 24+12])
pkt[36] = udpProtoNumber // The map opcode body (https://tools.ietf.org/html/rfc6887#section-11.1)
binary.BigEndian.PutUint16(pkt[40:], uint16(mapToLocalPort)) mapOp := pkt[24:]
rand.Read(mapOp[:12]) // 96 bit mappping nonce
mapOp[12] = udpProtoNumber
binary.BigEndian.PutUint16(mapOp[16:], uint16(mapToLocalPort))
v4unspec16 := v4unspec.As16() v4unspec16 := v4unspec.As16()
copy(pkt[40:], v4unspec16[:]) copy(mapOp[20:], v4unspec16[:])
return pkt return pkt
} }

Loading…
Cancel
Save