What driver is handling my IOCTL
I open a socket like this
skfd = socket( AF_INET, SOCK_DGRAM, 0 );
and then doing an ioctl on skfd like this: ioctl(skfd, SIOCETHTOOL, &ifr)
I want to know which driver is handling this IOCTL in my kernel.
I know that if it were a character driver, I could search for the major file number that I open, and then do cat /proc/devices
to find which driver is registered with that major number.
There should be something similar here.
source to share
A fish
You are calling ioctl on the filedescriptor that represents the socket. If you browse the file net/socket.c
, you will find a structure socket_file_ops
that defines sock_ioctl
how the ioctl callback is. For SIOCETHTOOL
this function will call sock_do_ioctl
, which in turn (after checking that the given socket type (AF_INET - af_inet.c, inet_ioctl) does not handle this ioctl by itself) will call dev_ioctl
, which can handle SIOCETHTOOL
by calling dev_ethtool
. If your driver detects ethtool_ops
it should be supported.
Now, finding which device driver your network interface supports is another thing, but it's not very difficult. One way to do this is to use sysfs, just check what this symlink points to (substituting eth0
your interface name):
readlink /sys/class/net/eth0/device/driver/module
../../../../module/e1000e
So my Ethernet card is being controlled by a module e1000e
.
Fishing rod
Now I figured it out by reading the code. I know a thing or two about kernel code, so I knew where to look. However, if I didn't want to find it - tracking. Now I'm not sure if this all works on 2.6.32, but at least I've tested this on a 3.2 kernel (which isn't that much different). I will not go into details on how to configure the kernel to have all of these features. Ubuntu 12.04 has everything you need, and if you're interested in Google for ftrace
:
You need to debugfs
mount and script like this:
#!/bin/sh
DEBUGFS=`/sys/kernel/debug/`
echo $$ > $DEBUGFS/tracing/set_ftrace_pid
echo function > $DEBUGFS/tracing/current_tracer
exec $*
This script will install ftrace
just to only care about the current PID, enable the tracer function and execute the command given as an argument (no markup, as that would change the PID).
Now, if your application using this ioctl /tmp/a.out
, you can call:
~/bin/ftraceme.sh /tmp/a.out
echo -n "" > /sys/kernel/debug/tracing/current_tracer
grep ioctl /sys/kernel/debug/tracing/trace
In my case, I have:
<...>-11009 [007] 596251.750675: sys_ioctl <-system_call_fastpath (1)
<...>-11009 [007] 596251.750675: fget_light <-sys_ioctl
<...>-11009 [007] 596251.750675: security_file_ioctl <-sys_ioctl
<...>-11009 [007] 596251.750676: cap_file_ioctl <-security_file_ioctl
<...>-11009 [007] 596251.750676: do_vfs_ioctl <-sys_ioctl
<...>-11009 [007] 596251.750676: sock_ioctl <-do_vfs_ioctl (2)
<...>-11009 [007] 596251.750677: sock_do_ioctl <-sock_ioctl (3)
<...>-11009 [007] 596251.750677: inet_ioctl <-sock_do_ioctl (4)
<...>-11009 [007] 596251.750677: udp_ioctl <-inet_ioctl
<...>-11009 [007] 596251.750678: dev_ioctl <-sock_do_ioctl (5)
<...>-11009 [007] 596251.750678: _cond_resched <-dev_ioctl
<...>-11009 [007] 596251.750679: dev_load <-dev_ioctl
<...>-11009 [007] 596251.750680: rtnl_lock <-dev_ioctl
<...>-11009 [007] 596251.750680: dev_ethtool <-dev_ioctl (6)
<...>-11009 [007] 596251.750684: rtnl_unlock <-dev_ioctl
<...>-11009 [007] 596251.750685: _cond_resched <-dev_ioctl
Which proves what I wrote above.
source to share