1

我想用我的程序设置一些本地 sysctl 参数,我按照这里给出的指示:http ://www.linux.it/~rubini/docs/sysctl/

例如,这是我为/proc/sys/net/ipv6/conf/tun0/accept_ra. 我刚刚tun0在此调用之前配置了我的界面。(我确认我的接口已启动,并且我也能够分配 IP 地址)

int path_len = 5;
int tun0_accept_ra_path[] =  { CTL_NET,
                               NET_IPV6,
                               NET_IPV6_CONF,
                               ifr6.ifr6_ifindex, // This ifindex comes from an interface configured above
                               NET_IPV6_ACCEPT_RA };
int tun0_accept_ra_value = 0;
if (sysctl(tun0_accept_ra_path,
           path_len,
           NULL,
           0,
           &tun0_accept_ra_value,
           sizeof(tun0_accept_ra_value)) < 0) {
  printf("set sysctl 'accept_ra' failed. errno: %d\n", errno);
}

我得到:set sysctl 'accept_ra' failed. errno: 38 Function not implemented

有什么想法可能是错的吗?我以 sudo 身份运行,所以我认为我不应该有访问权限问题。

我在树莓派上运行 Debian GNU/Linux 7.0 (wheezy)。

4

1 回答 1

7

你用的教程太老了!如果你想要这个系统调用的参考,你应该查看这个链接: http: //man7.org/linux/man-pages/man2/sysctl.2.html

您收到SIGSYS错误,因为 sysctl 不存在。该系统的正确名称是 *_syscall* 并且 glibc 不提供包装器,因为不应调用此系统调用(它将从下一个 Linux 版本中删除)。您可以使用/proc接口获得相同的结果。

如果你想保留你的解决方案,你应该改变代码如下(我没有测试,对不起):

#include <sys/syscall.h> 

int path_len = 5;
int tun0_accept_ra_path[] =  { CTL_NET,
                               NET_IPV6,
                               NET_IPV6_CONF,
                               ifr6.ifr6_ifindex, 
                               NET_IPV6_ACCEPT_RA };
int tun0_accept_ra_value = 0;
if (syscall(__NR_sysctl, 
           tun0_accept_ra_path,
           path_len,
           NULL,
           0,
           &tun0_accept_ra_value,
           sizeof(tun0_accept_ra_value)) < 0) {
  printf("set sysctl 'accept_ra' failed. errno: %d\n", errno);
}

更好的解决方案可能是:

int tun0_accept_ra_value = 0;

if ((fd=open("/proc/sys/net/ipv6/conf/tun0/accept_ra", O_RDWR)) < 0) 
   perror("OPEN"); 

if (write (fd, &tun0_accept_ra_value, sizeof(int)) < 0)
   perror("WRITE"); 

close(fd); 

我希望我有用。

于 2013-07-24T22:56:52.077 回答