
ブリッジとチューニング/タップデバイスに問題があります。
実際、最大の問題は、コンパイルする前にブリッジとタブインターフェイスを作成しようとしていることです。私のコードはコンパイル時にこのインタフェースを使用する必要があります。私のプロジェクトコードからthe Contiki
(https://github.com/contiki-os/contiki) コードがコンパイルされ、タブインタフェースと通信を生成するために使用されます。
コマンドを使用してソースコードを実行するとすべてがうまくいきsudo
ますが、前述のように最初にクリックインターフェイスを作成し、コマンドなしでコードを実行する必要がありますsudo
。
したがって、私のコードがコマンドを使用して実行されると、応答は次のようになりますsudo
。ifconfig tap0
tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fc00::231 prefixlen 7 scopeid 0x0<global>
inet6 fe80::cc9f:ddff:fe50:7d9a prefixlen 64 scopeid 0x20<link>
ether ce:9f:dd:50:7d:9a txqueuelen 1000 (Ethernet)
RX packets 50 bytes 12195 (12.1 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 52 bytes 7869 (7.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
この状態では、私のプロジェクトは正常に実行されます。
ただし、次のコマンドを使用してクリックインターフェイスを作成しようとしています。
sudo ip tuntap add mode tap tap0 user myusername
sudo ifconfig tap0 up
sudo ip link set tap0 up
sudo ip -6 address add fc00::231/7 dev tap0
sudo ip address add dev tap0 scope link fe80::cc9f:ddff:fe50:7d9a
それからifconfig tap0
答えが来ます。
tap0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet6 fe80::cc9f:ddff:fe50:7d9a prefixlen 128 scopeid 0x20<link>
inet6 fc00::231 prefixlen 7 scopeid 0x0<global>
ether 06:ea:8d:0e:66:74 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
だから、Contikiコードを修正した後、tap0インターフェイスを読み取ろうとします。
ret = read(fd, uip_buf, UIP_BUFSIZE);
ただし、ret値は-1です。 (sudoで実行するとint値が返されます。) tap0 インタフェースの状態を変更できればRUNNING
ret値も取得できると思いましたが、どうすればいいかわかりません。
私が何をすべきかを知っている人はいますか?
注:tapdev6.cの修正
void
tapdev_init(void)
{
printf("INIT TAP DEV!!!!!!!!!!!!!!!!! \n");
net_fd = open(DEVTAP, O_RDWR);
if(net_fd == -1) {
perror("tapdev: tapdev_init: open");
return;
}
#ifdef __linux
{
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
printf("INIT0 net_fd %d \n", net_fd);
if (ioctl(/*net_fd*/4, TUNSETIFF, (void *) &ifr) < 0) {
printf("INIT FAIL \n");
perror("Unable to init tunnel interface\n");
//exit(1);
}
printf("INIT1 net_fd %d \n", net_fd);
ioctl(/*net_fd*/4, SIOCGIFHWADDR, &ifr);
printf("INIT2 net_fd %d \n", net_fd);
}
/* Linux (ubuntu) */
char buf[256];
snprintf(buf, sizeof(buf), "ip link set tap0 up");
system(buf);
PRINTF("%s\n", buf);
snprintf(buf, sizeof(buf), "ip -6 address add fc00::231/7 dev tap0");
system(buf);
PRINTF("%s\n", buf);
snprintf(buf, sizeof(buf), "ip -6 route add fc00::0/7 dev tap0");
system(buf);
PRINTF("%s\n", buf);
/* freebsd */
//try to set hw address
// 12:bc:34:76:c9:2f
ifr.ifr_hwaddr.sa_data[0] = 0x12;
ifr.ifr_hwaddr.sa_data[1] = 0xbc;
ifr.ifr_hwaddr.sa_data[2] = 0x34;
ifr.ifr_hwaddr.sa_data[3] = 0x76;
ifr.ifr_hwaddr.sa_data[4] = 0xc9;
ifr.ifr_hwaddr.sa_data[5] = 0x2f;
printf("Lan device %s\n", ifr.ifr_name);
printf("LAN HW addr %02X:%02X:%02X:%02X:%02X:%02X\n",
(unsigned char)ifr.ifr_hwaddr.sa_data[0],
(unsigned char)ifr.ifr_hwaddr.sa_data[1],
(unsigned char)ifr.ifr_hwaddr.sa_data[2],
(unsigned char)ifr.ifr_hwaddr.sa_data[3],
(unsigned char)ifr.ifr_hwaddr.sa_data[4],
(unsigned char)ifr.ifr_hwaddr.sa_data[5]);
#endif /* Linux */
lasttime = 0;
}
答え1
-ESUDO
真剣に、クリックインターフェイスの所有者を設定する必要があります。以下を試してください。
ip tuntap add tap0 mode tap user USER
USER
ユーザーが開いたハンドルを介して読み書きします/dev/net/tun
。失敗した読み取りではなく、ioctl(TUNSETIFF)
戻り値を確認することに気を付けていないようです。
opentap(ifname)
これは、それを実行しているユーザーが正しい権限を持っていると仮定し、Tapインターフェースのfdハンドルを開く必要がある単純な関数です。
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int opentap(char *ifn)
{
int fd;
struct ifreq ifr = { 0 };
if (snprintf(ifr.ifr_name, sizeof ifr.ifr_name, "%s", ifn)
>= sizeof ifr.ifr_name) {
errno = ENAMETOOLONG; return -1;
}
if ((fd = open("/dev/net/tun", O_RDWR)) == -1) return -1;
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if (ioctl(fd, TUNSETIFF, &ifr) == -1) {
int e = errno; close(fd); errno = e; return -1;
}
return fd;
}