Reputation: 1113
I am opening a socket like this:
skfd = socket( AF_INET, SOCK_DGRAM, 0 );
and then doing an ioctl on skfd like: ioctl(skfd, SIOCETHTOOL, &ifr)
I want to know which driver is handling this IOCTL in my kernel.
I know that had it been a character driver, I could have looked up for the major number of the file I am opening and then do a cat /proc/devices
to find which driver is registered with that major number.
Must be some similar way here.
Upvotes: 3
Views: 4270
Reputation: 2079
You are calling ioctl on a filedescriptor that is representing socket. If you examine net/socket.c
file, you will find socket_file_ops
structure that defines sock_ioctl
as a ioctl callback. For SIOCETHTOOL
, this function will call sock_do_ioctl
which in turn (after checking that this particular socket type (AF_INET - af_inet.c, inet_ioctl function) does not handle this ioctl by itself) will call dev_ioctl
which can handle SIOCETHTOOL
by calling dev_ethtool
. If your driver defines ethtool_ops
, this should be supported.
Now finding which device driver supports your network interface is another thing but this isn't really hard. One way to do this is to use sysfs, just check what is this symlink pointing to (substituting eth0
with your interface name):
readlink /sys/class/net/eth0/device/driver/module
../../../../module/e1000e
So my ethernet card is driven by module e1000e
.
Now I found this out by reading the code. I do know something about kernel code so I knew where I should look. If I wouldn't, however, there's other way to find this out - tracing. Now I'm not sure if all this works on 2.6.32, but at least I tested this on kernel 3.2 (which isn't that much different). I won't go into details on how to configure your kernel to have all those functionalities. Ubuntu 12.04 has all that is needed and if you're interested google for ftrace
:
You need debugfs
mounted and a 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 set ftrace
to only care about current PID, enable function tracer and exec the command specified as an argument (without forking as that would change the PID).
Now, if your application that is using this ioctl is /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've got:
<...>-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.
Upvotes: 7