Skip to content

Instantly share code, notes, and snippets.

@robbmanes
Last active May 14, 2019 08:05
Show Gist options
  • Select an option

  • Save robbmanes/5d7b7578d85b86a78a02fbce2c821f6f to your computer and use it in GitHub Desktop.

Select an option

Save robbmanes/5d7b7578d85b86a78a02fbce2c821f6f to your computer and use it in GitHub Desktop.
A SystemTap script listing all currently assigned IP addresses in all networking namespaces
/*
* global_ip_list.stp
* Author: Robert Thomas Manes <[email protected]>
*
* With special thanks to Sterling Alexander and Kyle Walker.
*
* This systemtap script lists all currently assigned IP addresses in
* all network namespaces on the system in which it is run.
*
* It is currently only tested on Red Hat Enterprise Linux 7.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* It's vital to replace this net_namespace_list with your actual address
* for namespaces. To get the proper address, pull it from the symbol table
* like so:
*
* # grep 'D net_namespace_list' /proc/kallsyms | awk '{print $1}'
*/
global net_namespace_list = 0xffffffff91712ac0;
probe begin {
printf("Listing all available IP addresses regardless of network namespace...\n");
list_addresses_per_namespace();
exit();
}
probe end {
printf("Done.\n");
}
function list_addresses_per_namespace() {
net_list_head = @cast(net_namespace_list, "list_head")->next;
net_list_cur = net_list_head;
// walk namespace list
for(;@cast(net_list_cur, "list_head")->next != net_list_head;) {
namespace = & @container_of(net_list_cur, "struct net", list);
if(net_list_cur == net_namespace_list) {
continue;
}
printf("Namespace 0x%x\n", namespace);
dev_head = @cast(namespace, "net")->dev_base_head->next;
dev_cur = @cast(dev_head, "list_head")->next;
// walk device list
for(;dev_head != dev_cur;) {
netdev = & @container_of(dev_cur, "struct net_device", dev_list);
netdev_name = kernel_string(@cast(netdev, "net_device")->name);
printf(" %s\n", netdev_name);
// From the net_device, grab the ip_ptr which contains the ifa_list
ip_ptr = @cast(netdev, "net_device")->ip_ptr;
if(ip_ptr != 0x0)
{
ifa_list = @cast(ip_ptr, "in_device")->ifa_list;
for(;ifa_list != 0x0;)
{
addr = @cast(ifa_list, "in_ifaddr")->ifa_address;
printf(" %s\n", format_ipaddr(addr, 2));
ifa_list = @cast(ifa_list, "in_ifaddr")->ifa_next;
}
}
dev_cur = @cast(dev_cur, "list_head")->next;
}
net_list_cur = @cast(net_list_cur, "list_head")->next;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment