using STUN.Enums;
using STUN.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
namespace STUN.Message.Attributes
{
///
/// https://tools.ietf.org/html/rfc5389#section-15.1
///
public abstract class AddressAttribute : IAttribute
{
public virtual IEnumerable Bytes
{
get
{
if (Address is null)
{
return Array.Empty();
}
var res = new List { 0, (byte)Family };
res.AddRange(Port.ToBe());
res.AddRange(Address.GetAddressBytes());
return res;
}
}
public IpFamily Family { get; set; }
public ushort Port { get; set; }
public IPAddress? Address { get; set; }
public virtual bool TryParse(byte[] bytes)
{
var length = 4;
if (bytes.Length < length)
{
return false;
}
Family = (IpFamily)bytes[1];
switch (Family)
{
case IpFamily.IPv4:
length += 4;
break;
case IpFamily.IPv6:
length += 16;
break;
default:
return false;
}
if (bytes.Length != length)
{
return false;
}
Port = BitUtils.FromBe(bytes[2], bytes[3]);
Address = new IPAddress(bytes.Skip(4).ToArray());
return true;
}
public override string ToString()
{
return Address?.AddressFamily switch
{
AddressFamily.InterNetwork => $@"{Address}:{Port}",
AddressFamily.InterNetworkV6 => $@"[{Address}]:{Port}",
_ => base.ToString()
};
}
}
}