브리지와 튜닝/탭 장치에 문제가 있습니다.
사실 가장 큰 문제는 컴파일하기 전에 브리지와 탭 인터페이스를 만들려고 한다는 것입니다. 내 코드는 컴파일 타임에 이 인터페이스를 사용해야 합니다. 내 프로젝트 코드에서 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;
}