我试图阐明哪种是在 Linux 中与设备交互的最有用(就功能而言)方法。据我了解,设备文件只公开了部分功能(块设备中的地址块,字符设备中的流等......)。 ioctl(2)似乎是最常用的,但有人说它不安全,等等。
一些好的文章或其他相关的指针将受到欢迎。
所以我正在寻找的是一个接口索引(或名称),但真正的。
if_nametoindex(3)并且ioctl(2)似乎没有帮助我在这里。现在我发现如何做到这一点的唯一方法是通过/sys. 让我举例说明我需要什么:
# cat /sys/class/net/bond0.1007/ifindex
26
# cat /sys/class/net/bond0.1007/iflink
23 <-- I need either this or a reference to bond0
# cat /sys/class/net/bond0/ifindex
23
Run Code Online (Sandbox Code Playgroud)
有没有办法通过函数调用来做到这一点,或者唯一的方法是sysfs?
我已经发现在 Linux 上我可以列出网络设备
(cd /proc/net/dev_snmp6/ && for device in *; do echo $device; done|sort)
Run Code Online (Sandbox Code Playgroud)
但是我怎样才能获得设备的 ipv4 地址呢?
我没有安装ifconfig/ip - 我想保持这种方式。
我有一个最小的 Linux 系统。
INIT是/bin/bash,只有最低限度以库/lib/,/dev/静态填充,没有运行的守护进程(无udev的,..)
当 bash 启动时,我收到以下错误:
bash: cannot set terminal process group (-1) inappropriate ioctl for device
bash: no job control in this shell
Run Code Online (Sandbox Code Playgroud)
当我用 strace 启动 bash 时,我得到以下输出:
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
open("/dev/tty", O_RDWR|O_NONBLOCK) = -1 ENXIO (No such device or address)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
....
readlink("/proc/self/fd/0", "/dev/console"..., 4095) = 12
stat("/dev/console", {st_mode=S_IFCHR|0600, st_rdev=makedev(5, 1), ...}) = 0
open("/dev/console", O_RDWR|O_NONBLOCK) = …Run Code Online (Sandbox Code Playgroud) 我正在尝试用 Rust 编写一个 tun/tap 程序。由于我不希望它以 root 身份运行,因此我已将 CAP_NET_ADMIN 添加到二进制文件的功能中:
$sudo setcap cap_net_admin=eip target/release/tunnel
$getcap target/release/tunnel
target/release/tunnel = cap_net_admin+eip
Run Code Online (Sandbox Code Playgroud)
然而,这是行不通的。我读到的所有内容都表明这是创建 tun 所需的唯一功能,但程序在 ioctl 上获得了 EPERM。在 strace 中,我看到这个错误:
openat(AT_FDCWD, "/dev/net/tun", O_RDWR|O_CLOEXEC) = 3
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
ioctl(3, TUNSETIFF, 0x7ffcdac7c7c0) = -1 EPERM (Operation not permitted)
Run Code Online (Sandbox Code Playgroud)
我已经验证二进制文件可以在完全 root 权限下成功运行,但我不希望这需要 sudo 才能运行。为什么 CAP_NET_ADMIN 在这里不够用?
作为参考,我发现Linux version 4.15.0-45这个 ioctl 只有几种方法可以在内核中返回 EPERM(https://elixir.bootlin.com/linux/v4.15/source/drivers/net/tun.c #L2194),其中至少有一个似乎感到满意。我不知道如何探究其他人:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
...
if (tun_not_capable(tun))
return -EPERM;
...
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
return -EPERM;
Run Code Online (Sandbox Code Playgroud) 由医生。, ioctl 签名是int ioctl(int fd, int request, ...). request是ioctl的代码。
有什么方法可以知道我的 linux 中可用的所有可能的 ioctl 请求代码是什么?也许想知道每个代码映射到哪个内核模块?
我想ioctl EVIOCGRAB在基于 C 的程序中使用该函数,并且通过谷歌搜索我找到了使用该函数的各种示例源代码,但我正在努力寻找正确描述如何正确使用它的明确文档。
我从ioctl(2)看到,ioctl函数被定义为
int ioctl(int d, unsigned long request, …);
Run Code Online (Sandbox Code Playgroud)
然后:
The third argument is an untyped pointer to memory. It's traditionally char
*argp (from the days before void * was valid C), and will be so named
for this discussion.
Run Code Online (Sandbox Code Playgroud)
我希望EVIOCGRAB在ioctl_list(2) 中找到,但事实并非如此。
所以我不知道EVIOCGRAB函数的第三个参数应该是什么。在看到各种示例代码之后,我所能做的就是假设一个非零值抓住了设备,而一个零值释放了它。
我从随机代码示例中得到的,例如
int grab = 1;
ioctl(fd, EVIOCGRAB, &grab);
..
ioctl(fd, EVIOCGRAB, NULL);
Run Code Online (Sandbox Code Playgroud)
或者
ioctl(fd, EVIOCGRAB, (void*)1);
..
ioctl(fd, EVIOCGRAB, …Run Code Online (Sandbox Code Playgroud) 我无法再安装我的加密设备。
错误是:
device mapper: create ioctl failed
device or resource busy
Run Code Online (Sandbox Code Playgroud)
两个不同的程序访问 TrueCrypt 加密设备时都会出现此错误:TrueCrypt 和 Tc-play。
在这种情况下,建议删除/dev/mapper/truecrypt*目录,或查找阻塞设备的进程。但是,没有/dev/mapper/truecrypt*目录,并且不lsof返回任何内容。
一个 TrueCrypt 设备需要整个 HDD。根据fdisk,这个分区是用 HPFS/NTFS 格式化的。
另一个 TrueCrypt 设备位于 上的分区上/dev/sda。根据fdisk,这个分区是“Linux”(ext3 或 ext4,如果我没记错的话)。
什么可能导致错误?
软件:
我正在阅读rmlint手册,其中一个重复的处理程序是 clone 和 reflink:
·克隆:仅限btrfs。尝试使用 BTRFS_IOC_FILE_EXTENT_SAME ioctl(3p) 克隆这两个文件。这将物理删除重复的范围。至少需要内核 4.2。
· reflink:尝试将重复文件重新链接到原始文件。另请参阅 man 1 cp 中的 --reflink。如果文件系统不支持,则失败。
这个克隆到底做了什么,它与引用链接有什么不同?BTRFS_IOC_FILE_EXTENT_SAME ioctl 有什么作用?
我使用cdc_acm驱动程序通过 USB 连接了一个 Arduino Uno 。它可以在/dev/ttyACM0。
Arduino 串行接口的约定是用于DTR复位信号的信号——当使用集成串行转 USB 适配器时,DTR/RTS/DSR/CTS 信号;或者,当使用 RS-232 电缆时,引脚 4 或 5(可能还有 6 或 8)连接到RESET引脚。
这种复位途径具有重要的优势,即使不是真正的带外,至少也非常接近故障安全(由于通过始终带外串行控制器与非正常用户一起实现) -可控看门狗电路),虽然它可以被物理禁用(通过将电容器或电阻器连接到RESET引脚,取决于型号),这样做会完全破坏这个重要的终止开关和所有相关的实用程序。
不幸的是,目前,当任何程序出于任何原因连接到 ACM 设备时,Linux似乎总是发送此信号,并且(与 Windows 不同)没有提供甚至模糊已知的可靠方法来防止这种情况发生。
(目前两种-hupcl,“当最后一个进程关闭TTY发送挂起信号”和-clocal,“禁用调制解调器控制信号”也没有阻止发送这个信号每次设备被打开。)
/dev/ttyACM0不向其发送 DTR/RTS/DSR/CTS 信号的情况下访问(在硬件级别阻止信号)?ioctl ×10
linux ×5
sysfs ×2
bash ×1
btrfs ×1
capabilities ×1
devices ×1
proc ×1
programming ×1
reflink ×1
rmlint ×1
serial-port ×1
tap ×1
terminal ×1
tty ×1