在Unix中使用IPv6的MCAST_JOIN_SOURCE_GROUP setsockopt的optval格式是什么?



我正在尝试为我的本地网络创建一个多播测试工具。我还没有工作的唯一功能是Linux上的IPv6 SSM。我已经使用strace来尝试和调试,这是我在尝试加入多播组时收到的错误:

setsockopt(67, SOL_IPV6, MCAST_JOIN_SOURCE_GROUP, "327270v3778207eC!"..., 264) = -1 EADDRNOTAVAIL (Cannot assign requested address)

Optval =03000000000000001700 b80b00000000ff38000000000000000000008765432100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001700000000000000fe8000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 .

我正在使用接口3,试图连接到FF38::8765:4321端口3000与FE80::1作为我的源。这对我来说似乎是正确的,任何想法是什么可能导致错误?

编辑:这是我的代码来进行系统调用:

[DllImport("libc", SetLastError = true)]
static extern int setsockopt(int sockfd, int level, int optname, void *optval, int size);
fixed(void* data = &joinData[0])
{
setsockopt((int)socket.Handle, 41, 46, data, joinData.Length);
}

,下面是我填充optval的代码:

byte[] joinBytes;
GroupSourceReqModel v6ssmJoin = new GroupSourceReqModel();
v6ssmJoin.gr_interface = (uint)selections.LocalIp.ScopeId;
SocketAddressIpv6InputModel mGroupIn = new SocketAddressIpv6InputModel
{
sin6_family = (ushort)selections.MulticastAddress.AddressFamily,
sin6_port = (ushort)selections.Port,
sin6_scope_id = 0
};
for (int i = 0; i < selections.MulticastAddress.GetAddressBytes().Length; i++)
{
mGroupIn.sin6_addr[i] = selections.MulticastAddress.GetAddressBytes()[i];
}
SocketAddressStorageModel groupSock = new SocketAddressStorageModel();       
byte[] groupSockInData = ConvertToBytes(mGroupIn);
Console.WriteLine(Convert.ToHexString(groupSockInData));
byte* groupSockPointer = (byte*)&groupSock;
for (int i = 0; i < groupSockInData.Length; i++)
{
groupSockPointer[i] = groupSockInData[i];         // Now populate the groupSock object with the byte data of mGroupIn
}
v6ssmJoin.gsr_group = groupSock;    
SocketAddressIpv6InputModel sGroupIn = new SocketAddressIpv6InputModel
{
sin6_family = (ushort)selections.SourceAddress.AddressFamily,
sin6_port = 0,
sin6_scope_id = 0
};
for (int i = 0; i < selections.SourceAddress.GetAddressBytes().Length; i++)
{
sGroupIn.sin6_addr[i] = selections.SourceAddress.GetAddressBytes()[i];
}
SocketAddressStorageModel sourceSock = new SocketAddressStorageModel
{
ss_family = (short)selections.SourceAddress.AddressFamily
};
byte[] sourceSockInData = ConvertToBytes(sGroupIn);
byte* sourceSockPointer = (byte*)&sourceSock;
for (int i = 0; i < sourceSockInData.Length; i++)
{
sourceSockPointer[i] = sourceSockInData[i];
}
v6ssmJoin.gsr_source = sourceSock;
joinBytes = ConvertToBytes(v6ssmJoin);
return joinBytes;
public static unsafe byte[] ConvertToBytes<T>(T value) where T : unmanaged
{
byte* pointer = (byte*)&value;
byte[] bytes = new byte[sizeof(T)];
for (int i = 0; i < sizeof(T); i++)
{
bytes[i] = pointer[i];
}
return bytes;
}

如果它是相关的,我正在运行的内核版本5.4.0-122-generic。

Linux中IPv6的地址族是10,在这里的内核源代码中可以看到,它与c#使用的Windows值不同。此外,端口值以大端序存储。

相关内容

  • 没有找到相关文章

最新更新