无法使用 Firefox-Copper 插件将 CoAP 消息发送到本地地址以外的地址 (::1)

Can't send CoAP messages with Firefox-Copper plugin to other than local address(::1)

我正在尝试使用 RIOT-OS 建立 CoAP 网络。我正在研究 Windows 7 64 位,使用 VMWare 模拟 Ubuntu 14.04.2。 Guest 和 Host 之间的网络连接是 Nat: Share the host's IP address

我基本上复制了 microcoap pkg 并将其修改为 IPv6.I 我正在使用 Copper Firefox 插件(在来宾 Ubuntu 机器上)来测试客户端是否正常工作,以及我是否将::1 的套接字地址可以正常工作,但如果我将其更改为我想要的任何其他内容,Copper 似乎无法找到它。 (顺便说一句,我是网络建设的新手,我从来没有实施过一个,只是阅读了有关它们的信息,我只知道这一定是一些微不足道的问题所以请原谅我的笨拙或者我提供的信息太少)

Copper 始终可以连接到 ::1,即使 CoAP 客户端不是 运行,只有当我尝试发出 GET/POST 或任何其他命令时,它才会显示 Network/Host是无法访问的,但是如果我尝试其他 Ipv6 地址,请说 fe80::20c:29ff:fe40:e46e/64 或 fe80::20c:29ff:fe40:e46d/64 (在这种情况下是 eth0 的 IPv6 地址)它会直接说Network/Host 无法访问。

(这是来自 VMWare Guest Ubuntu 的所有数据,我认为我们不需要来自 Host Windows7 机器的数据,但是如果您认为是的话,我当然可以提供它问题埋在哪里)

ifconfig:

docker0   Link encap:Ethernet  HWaddr 22:ba:7c:00:36:d6  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::20ba:7cff:fe00:36d6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:65 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:9367 (9.3 KB)

eth0      Link encap:Ethernet  HWaddr 00:0c:29:40:e4:6d  
          inet addr:192.168.159.130  Bcast:192.168.159.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe40:e46d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9828 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4668 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:9443160 (9.4 MB)  TX bytes:542254 (542.2 KB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:1153 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1153 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:117380 (117.3 KB)  TX bytes:117380 (117.3 KB)

一开始我想到的是防火墙,或者路由问题,或者Ipv6 forwarindg,但是好像都没问题。 奇怪的是,如果我尝试 ::1 以外的任何其他操作,Wireshark 不会显示任何内容,甚至 ICMPv6 或 NDP 也不会显示任何内容,而在 ::1 处,至少当我单击 GET 或 P[= 时它会显示 CoAP 消息59=]T 按钮。

net.IPv6.conf.all.forwarding 设置为 1

ip6tables 为空,默认设置为 ACCEPT

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

我的 ufw 看起来像这样:

# /etc/default/ufw
#

# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6=yes

# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="ACCEPT"

# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="ACCEPT"

# Set the default forward policy to ACCEPT, DROP or REJECT.  Please note that
# if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="ACCEPT"

# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please
# note that setting this to ACCEPT may be a security risk. See 'man ufw' for
# details
DEFAULT_APPLICATION_POLICY="SKIP"

# By default, ufw only touches its own chains. Set this to 'yes' to have ufw
# manage the built-in chains too. Warning: setting this to 'yes' will break
# non-ufw managed firewall rules
MANAGE_BUILTINS=no

#
# IPT backend
#
# only enable if using iptables backend
IPT_SYSCTL=/etc/ufw/sysctl.conf

# Extra connection tracking modules to load. Complete list can be found in
# net/netfilter/Kconfig of your kernel source. Some common modules:
# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
# nf_conntrack_netbios_ns: NetBIOS (samba) client support
# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
# nf_conntrack_ftp, nf_nat_ftp: active FTP support
# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"

我的路由 -A inet6 是这样的(aaaa::XXX 和双 fe80::/64 eth0 只是我的实验,试图让它与其他 IP 地址一起工作):

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
aaaa::212:7402:2:202/128       ::                         !n   1   0    12 lo
aaaa::212:7402:2:202/128       ::                         UH   1   0     0 eth0
fe80::20c:29ff:fe40:e46d/128   ::                         UH   1   0     0 eth0
fe80::/64                      ::                         U    1   0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 docker0
::/0                           ::                         !n   -1  1   412 lo
::1/128                        ::                         Un   0   3   117 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::/128                     ::                         Un   0   1     0 lo
fe80::20c:29ff:fe40:e46d/128   ::                         Un   0   1    79 lo
fe80::20ba:7cff:fe00:36d6/128  ::                         Un   0   1     0 lo
ff00::/8                       ::                         U    256 0     0 eth0
ff00::/8                       ::                         U    256 0     0 docker0
::/0                           ::                         !n   -1  1   412 lo

这是我正在使用的 RIOT-OS 代码,其中创建了文件描述符和套接字:

#include <stdio.h>

#include "shell.h"

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdbool.h>
#include <strings.h>

#include "coap.h"

#define PORT 5683

int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;
    puts("Starting the RIOT\n");
    int fd;
    struct sockaddr_in6 servaddr, cliaddr;
    uint8_t buf[4096];//maybe need bigger becouse IPv6
    uint8_t scratch_raw[4096];
    coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)};

    fd = socket(AF_INET6,SOCK_DGRAM,0);//Socket file descriptor init


    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin6_family = AF_INET6;//inet family
    servaddr.sin6_flowinfo = 0;//??

    servaddr.sin6_addr.s6_addr[0] = (uint8_t)0xfe;//IPv6 Address 1
    servaddr.sin6_addr.s6_addr[1] = (uint8_t)0x80;
    servaddr.sin6_addr.s6_addr[2] = (uint8_t)0x00;//IPv6 Address 2
    servaddr.sin6_addr.s6_addr[3] = (uint8_t)0x00;
    servaddr.sin6_addr.s6_addr[4] = (uint8_t)0x00;//IPv6 Address 3
    servaddr.sin6_addr.s6_addr[5] = (uint8_t)0x00;
    servaddr.sin6_addr.s6_addr[6] = (uint8_t)0x00;//IPv6 Address 4
    servaddr.sin6_addr.s6_addr[7] = (uint8_t)0x00;
    servaddr.sin6_addr.s6_addr[8] = (uint8_t)0x02;//IPv6 Address 5
    servaddr.sin6_addr.s6_addr[9] = (uint8_t)0x0c;
    servaddr.sin6_addr.s6_addr[10] = (uint8_t)0x29;//IPv6 Address 6
    servaddr.sin6_addr.s6_addr[11] = (uint8_t)0xff;
    servaddr.sin6_addr.s6_addr[12] = (uint8_t)0xfe;//IPv6 Address 7
    servaddr.sin6_addr.s6_addr[13] = (uint8_t)0x40;
    servaddr.sin6_addr.s6_addr[14] = (uint8_t)0xe4;//IPv6 Address 8
    servaddr.sin6_addr.s6_addr[15] = (uint8_t)0x6e;

    servaddr.sin6_port = htons(PORT);       //PORT (5683)
    bind(fd,(struct sockaddr *)&servaddr, sizeof(servaddr));

    endpoint_setup();

    while(1)
    {
        int n, rc;
        socklen_t len = sizeof(cliaddr);
        coap_packet_t pkt;

        n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, &len);
//#ifdef DEBUG
        printf("Received: ");
        coap_dump(buf, n, true);
        printf("\n");
//#endif

        if (0 != (rc = coap_parse(&pkt, buf, n)))
            printf("Bad packet rc=%d\n", rc);
        else
        {
            size_t rsplen = sizeof(buf);
            coap_packet_t rsppkt;
#ifdef DEBUG
            coap_dumpPacket(&pkt);
#endif
            coap_handle_req(&scratch_buf, &pkt, &rsppkt);

            if (0 != (rc = coap_build(buf, &rsplen, &rsppkt)))
                printf("coap_build failed rc=%d\n", rc);
            else
            {
#ifdef DEBUG
                printf("Sending: ");
                coap_dump(buf, rsplen, true);
                printf("\n");
#endif
#ifdef DEBUG
                coap_dumpPacket(&rsppkt);
#endif

                sendto(fd, buf, rsplen, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
            }
        }
    }
}

因此,如果我将 servaddr.sin6_addr.s6_addr 更改为 ::1,它会起作用,但我当然想要我提供给客户的 IPv6 地址。

此外,我似乎无法 ping6 ipv6.google.com,尽管我也无法从主机 Windows 7 机器上 ping 通它,不知道为什么,也不知道'不知道有没有关系。

稍后我想同时创建 1 个以上的客户端 运行,可能通过网桥连接,连接到 TAP,运行 在 6lowpan 上,但现在我只想使一台设备工作。 (sry 不能添加 wireshark 图片,还没有这样的声誉:<)

fe80::/10 范围内的 IPv6 地址是 link-本地地址。相同的 link-local 地址范围出现在主机的每个接口上。如果您尝试使用该地址范围进行通信,这会给主机带来问题,因为主机不知道要使用哪个接口。在大多数操作系统中,您必须将区域(接口)ID 添加到 link-local 地址的末尾才能使用它。某些应用程序对此有问题。

您应该使用可路由地址。全局地址范围是 2000::/3(用于基准测试的 2001:2::/48 或用于文档的 2001:db8::/32 是测试的良好候选者,但它们不能在 Internet 上使用)。 Unique Local地址范围为fc00::/7(该范围内的fd00::/8可用于本地分配,具有特定的伪随机分配规则),地址不能在Internet上使用。

最好的解决方案是从您的 ISP 处获取一个范围,如果您想访问 Internet 以执行 ping Google.

之类的操作,请使用该范围