The name of the struct varies for each device type, however the location remains the same, right after net_device:
linux-2.6.32-358.14.1.el6.x86_64/include/linux/netdevice.h
/** * netdev_priv - access network device private data * @dev: network device * * Get network device private data */ static inline void *netdev_priv(const struct net_device *dev) { return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN); }A search in cscope for netdev_priv will show you many functions within drivers which update the priv structure via pointers, for example this one in e1000_main.c:
struct e1000_adapter *adapter = netdev_priv(netdev);So, given that we know what the device-specific struct is called, and where the device-specific private struct is, how do you find it and read it?
We'll need the ability to read kernel memory using crash, either run on a live system, or in a vmcore captured with kdump:
crash /usr/lib/debug/lib/modules/2.6.32-358.14.1.el6.x86_64/vmlinux /var/crash/2013-08-26/vmcoreWe'll also need the debugging symbols for the driver in question:
crash> mod -s e1000 /usr/lib/debug/lib/modules/2.6.32-358.14.1.el6.x86_64/kernel/drivers/net/e1000/e1000.ko.debug MODULE NAME SIZE OBJECT FILE ffffffffa01550e0 e1000 170678 /usr/lib/debug/lib/modules/2.6.32-358.14.1.el6.x86_64/kernel/drivers/net/e1000/e1000.ko.debugThe net command will show you the network devices in the system:
crash> net NET_DEVICE NAME IP ADDRESS(ES) ffff88007e76b820 lo 127.0.0.1 ffff8800372c0020 eth0 192.168.1.126We can then cast net_device against this to see the in-kernel device struct:
crash> net_device 0xffff8800372c0020 struct net_device { name = "eth0\000\000\060:03.0\000\000\000", ...But we want to get after this struct and cast it against the struct in the driver.
We need to know how big net_device is:
crash> struct -o net_device struct net_device { ... } SIZE: 1728We then find the net address plus the size of net_device:
crash> px 0xffff8800372c0020+1728 $1 = 0xffff8800372c06e0We can now cast the device-specific private struct against this new address:
crash> e1000_adapter 0xffff8800372c06e0 struct e1000_adapter { vlgrp = 0x0, mng_vlan_id = 65535, bd_number = 0, rx_buffer_len = 1522, ...and we're done!
1 comment:
struct -o for the win !
Post a Comment