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.

+3


source to share


1 answer


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.

+5


source







All Articles