AttributeExtensions.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using STUN.Enums;
  2. using STUN.Messages;
  3. using STUN.Messages.StunAttributeValues;
  4. using System.Net;
  5. namespace STUN.Utils;
  6. public static class AttributeExtensions
  7. {
  8. public static StunAttribute BuildChangeRequest(bool changeIp, bool changePort)
  9. {
  10. return new StunAttribute
  11. {
  12. Type = AttributeType.ChangeRequest,
  13. Length = 4,
  14. Value = new ChangeRequestStunAttributeValue { ChangeIp = changeIp, ChangePort = changePort }
  15. };
  16. }
  17. public static StunAttribute BuildMapping(IpFamily family, IPAddress ip, ushort port)
  18. {
  19. int length = family switch
  20. {
  21. IpFamily.IPv4 => 4,
  22. IpFamily.IPv6 => 16,
  23. _ => throw new ArgumentOutOfRangeException(nameof(family), family, null)
  24. };
  25. return new StunAttribute
  26. {
  27. Type = AttributeType.MappedAddress,
  28. Length = (ushort)(4 + length),
  29. Value = new MappedAddressStunAttributeValue
  30. {
  31. Family = family,
  32. Address = ip,
  33. Port = port
  34. }
  35. };
  36. }
  37. public static StunAttribute BuildChangeAddress(IpFamily family, IPAddress ip, ushort port)
  38. {
  39. int length = family switch
  40. {
  41. IpFamily.IPv4 => 4,
  42. IpFamily.IPv6 => 16,
  43. _ => throw new ArgumentOutOfRangeException(nameof(family), family, null)
  44. };
  45. return new StunAttribute
  46. {
  47. Type = AttributeType.ChangedAddress,
  48. Length = (ushort)(4 + length),
  49. Value = new ChangedAddressStunAttributeValue
  50. {
  51. Family = family,
  52. Address = ip,
  53. Port = port
  54. }
  55. };
  56. }
  57. public static IPEndPoint? GetMappedAddressAttribute(this StunMessage5389 response)
  58. {
  59. StunAttribute? mappedAddressAttribute = response.Attributes.FirstOrDefault(t => t.Type == AttributeType.MappedAddress);
  60. if (mappedAddressAttribute is null)
  61. {
  62. return null;
  63. }
  64. MappedAddressStunAttributeValue mapped = (MappedAddressStunAttributeValue)mappedAddressAttribute.Value;
  65. return new IPEndPoint(mapped.Address!, mapped.Port);
  66. }
  67. public static IPEndPoint? GetChangedAddressAttribute(this StunMessage5389 response)
  68. {
  69. StunAttribute? changedAddressAttribute = response.Attributes.FirstOrDefault(t => t.Type == AttributeType.ChangedAddress);
  70. if (changedAddressAttribute is null)
  71. {
  72. return null;
  73. }
  74. ChangedAddressStunAttributeValue address = (ChangedAddressStunAttributeValue)changedAddressAttribute.Value;
  75. return new IPEndPoint(address.Address!, address.Port);
  76. }
  77. public static IPEndPoint? GetXorMappedAddressAttribute(this StunMessage5389 response)
  78. {
  79. StunAttribute? mappedAddressAttribute =
  80. response.Attributes.FirstOrDefault(t => t.Type == AttributeType.XorMappedAddress) ??
  81. response.Attributes.FirstOrDefault(t => t.Type == AttributeType.MappedAddress);
  82. if (mappedAddressAttribute is null)
  83. {
  84. return null;
  85. }
  86. AddressStunAttributeValue mapped = (AddressStunAttributeValue)mappedAddressAttribute.Value;
  87. return new IPEndPoint(mapped.Address!, mapped.Port);
  88. }
  89. public static IPEndPoint? GetOtherAddressAttribute(this StunMessage5389 response)
  90. {
  91. StunAttribute? addressAttribute =
  92. response.Attributes.FirstOrDefault(t => t.Type == AttributeType.OtherAddress) ??
  93. response.Attributes.FirstOrDefault(t => t.Type == AttributeType.ChangedAddress);
  94. if (addressAttribute is null)
  95. {
  96. return null;
  97. }
  98. AddressStunAttributeValue address = (AddressStunAttributeValue)addressAttribute.Value;
  99. return new IPEndPoint(address.Address!, address.Port);
  100. }
  101. }