我正在尝试使用RIOT-OS构建CoAP网络。我正在使用Windows 7 64位,使用VMWare模拟Ubuntu 14.04.2。来宾和主机之间的网络连接是Nat:共享主机的IP地址
我基本上复制了microcoap pkg并将其修改为IPv6。我正在使用Copper Firefox插件(在来宾Ubuntu机器上)来测试客户端是否正常工作,如果我将套接字地址设置为:: 1则有效没有问题,但如果我把它改成其他任何我想要的,铜似乎无法找到它。 (顺便说一下,我对网络建设有点新意见,我从来没有实现只读它们,我只知道这一定是一些微不足道的问题,所以请原谅我的noobness或者我提供的信息太少了)
即使CoAP客户端没有运行,铜也可以始终连接到:: 1,只有当我尝试发出GET / POST或任何其他命令时,它表示网络/主机无法访问,但是如果我尝试其他一些Ipv6地址说fe80 :: 20c:29ff:fe40:e46e / 64或fe80 :: 20c:29ff:fe40:e46d / 64(在这种情况下是eth0的IPv6地址)它不情愿地说网络/主机是不可到达的。
(这是来自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,但一切似乎都很好。 奇怪的是Wireshark如果我尝试除了:: 1以外的任何东西都没有显示任何内容,甚至不是ICMPv6或NDP,其中:: 1至少它在我点击GET或POST时显示CoAP消息按钮。
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地址。
另外,我似乎无法ping到ip6 ipv6.google.com,虽然我也无法从主机Windows 7计算机上ping它,不知道为什么,不要&# 39;不知道这是否重要。
后来我想创建多个同时运行的客户端,可能通过网桥连接,连接到TAP,运行在6lowpan上,但是现在我只想让一台设备工作。 (sry无法添加wireshark图片,还没有声誉:&lt;)
答案 0 :(得分:1)
fe80 :: / 10范围内的IPv6地址是链路本地地址。主机的每个接口上都会显示相同的链路本地地址范围。如果您尝试使用该地址范围进行通信,则这会给主机带来问题,因为主机无法知道要使用哪个接口。在大多数操作系统中,您必须在链接本地地址的末尾添加区域(接口)ID才能使用它。有些应用程序存在此问题。
您应该使用可路由的地址。全局地址范围是2000 :: / 3(2001:2:/ / 48用于基准测试或2001:db8 :: / 32用于文档是测试的良好候选者,但它们不能在因特网上使用)。唯一本地地址范围是fc00 :: / 7(该范围内的fd00 :: / 8可用于本地分配,具有关于伪随机分配的特定规则),此范围的地址不能在Internet上使用。
最好的解决方案是从您的ISP获取一个范围,如果您想要通过互联网执行ping Google等操作,请使用该范围。