// Given an attribute that represents an address, this function returns the transport address (IP and port number). // // OUTPUT // - The address' family (1 for IPV4 or 2 for IPV6). // - The IP address. // + Example for IPV4: "192.168.0.1" // + Example for IPV6: "0011:2233:4455:6677:8899:AABB:CCDD:EEFF" // - The port number. // - The error flag. func (v *StunAttribute) __getAddress() (uint16, string, uint16, error) { var family, port uint16 var ip string var err error err = binary.Read(bytes.NewBuffer(v.Value[0:2]), binary.BigEndian, &family) if nil != err { return 0, "", 0, err } err = binary.Read(bytes.NewBuffer(v.Value[2:4]), binary.BigEndian, &port) if nil != err { return family, "", 0, err } ip, err = tools.BytesToIp(v.Value[4:]) if nil != err { return family, "", port, errors.New("Invalid IP family.") } return family, ip, port, nil }
// Given an attribute that represents a "XOR mapped" address, this function returns the transport address. // See http://www.nexcom.fr/2012/06/stun-la-base/ // // OUTPUT // - The address' family (1 for IPV4 or 2 for IPV6). // - The IP address. // + Example for IPV4: "192.168.0.1" // + Example for IPV6: "0011:2233:4455:6677:8899:AABB:CCDD:EEFF" // - The port number. // - The XORED IP address (should be equal to the mapped address). // - The XORED port (should be equal to the mapped port). // - The error flag. func (v *StunAttribute) AttributeGetXorMappedAddress() (uint16, string, uint16, string, uint16, error) { var family, port uint16 var ip_string string var xored_ip_string string var err error var cookie []byte = []byte{0x21, 0x12, 0xA4, 0x42} // 0x2112A442 var xored_ip []byte = make([]byte, 0, 16) var xored_port uint16 err = binary.Read(bytes.NewBuffer(v.Value[0:2]), binary.BigEndian, &family) if nil != err { return 0, "", 0, "", 0, err } if (STUN_ATTRIBUT_FAMILY_IPV4 != family) && (STUN_ATTRIBUT_FAMILY_IPV6 != family) { return 0, "", 0, "", 0, errors.New(fmt.Sprintf("Invalid address' family: 0x%02x", family)) } err = binary.Read(bytes.NewBuffer(v.Value[2:4]), binary.BigEndian, &port) if nil != err { return family, "", 0, "", 0, err } if STUN_ATTRIBUT_FAMILY_IPV4 == family { // IPV4 if len(v.Value[4:]) != 4 { return 0, "", 0, "", 0, errors.New(fmt.Sprintf("Invalid IPV4 address: % x", v.Value[4:])) } for i := 0; i < 4; i++ { xored_ip = append(xored_ip, v.Value[i+4]^cookie[i]) } } else { // IPV6 var long_magic []byte = make([]byte, 0, 16) if len(v.Value[4:]) != 16 { return 0, "", 0, "", 0, errors.New(fmt.Sprintf("Invalid IPV6 address: % x", v.Value[4:])) } long_magic = append(long_magic, cookie...) long_magic = append(long_magic, v.Packet.id[0:12]...) for i := 0; i < 16; i++ { xored_ip = append(xored_ip, v.Value[i+4]^cookie[i]) } } // Calculate the values to return. // - family // - ip_string // - port // - xored_ip_string // - xored_port ip_string, err = tools.BytesToIp(v.Value[4:]) if nil != err { return 0, "", 0, "", 0, err } xored_ip_string, err = tools.BytesToIp(xored_ip) if nil != err { return 0, "", 0, "", 0, err } xored_port = port ^ 0x2112 return family, ip_string, port, xored_ip_string, xored_port, nil }