AttributeExtensions.cs 3.2 KB

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