如何删除 Ubuntu 中 SCTP 数据包中的 "IPv4 address parameter" 字段(可选)

How to remove "IPv4 address parameter" field (optional) in a SCTP packet in Ubuntu

我想在 Ubuntu 20.04 中使用 L2TP VPN 将 SCTP 数据包发送到服务器。为此,我设置了 L2TP VPN,并且可以使用 ping 命令成功测试连接。现在我的 ifconfig 输出如下:

enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet x.x.x.x  netmask 255.255.255.248  broadcast p.p.p.p
    ...

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
    ...

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1400
        inet y.y.y.y  netmask 255.255.255.255  destination q.q.q.q
    ...

在此输出中,x.x.x.x 是我的 LAN IP,y.y.y.y 是我的 VPN IP。

但是当我发送我的 INIT SCTP 数据包时,两个可选字段,即 IPv4 地址参数 ,出现在 INIT chunk Wireshark 日志中的子树如下。这些参数包含我的 IP。

Stream Control Transmission Protocol, Src Port: a (a), Dst Port: b (b)
    Source port: a
    Destination port: b
    Verification tag: 0x00000000
    [Association index: 65535]
    Checksum: 0x06cf8029 [unverified]
    [Checksum Status: Unverified]
    INIT chunk (Outbound streams: 3, inbound streams: 3)
        Chunk type: INIT (1)
            0... .... = Bit: Stop processing of the packet
            .0.. .... = Bit: Do not report
        Chunk flags: 0x00
        Chunk length: 52
        Initiate tag: 0xd1d6f19b
        Advertised receiver window credit (a_rwnd): 106496
        Number of outbound streams: 3
        Number of inbound streams: 3
        Initial TSN: 1216798565
        IPv4 address parameter (Address: x.x.x.x)
        IPv4 address parameter (Address: y.y.y.y)
        Supported address types parameter (Supported types: IPv4)
        ECN parameter
        Forward TSN supported parameter

最后,这是发送和接收的数据包:

我认为 IPv4 地址参数(地址:x.x.x.x)(我的局域网 IP)在我的 INIT 数据包中,已导致从服务器接收 ABORT 数据包。当我关闭我的 VPN 时,这两个可选字段不会出现。

如何在打开 VPN 后删除 Ubuntu 中的这两个可选字段?

需要手动分配客户端 IP 才能删除 SCTP 数据包中的“IPv4 地址参数”字段。因此,在 C++ 中需要以下代码:

int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
if(sock < 0)
{
    //handle error
}
struct sockaddr_in clientAddr;
memset(&clientAddr,0, sizeof(struct sockaddr_in));
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.s_addr = inet_addr("y.y.y.y"); 
clientAddr.sin_port = htons(a);
if( ::bind(sock, (struct sockaddr*)&clientAddr, sizeof(struct sockaddr)) < 0 )
{
    //handle error
}