AttributeExtensions.cs 3.1 KB

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