-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linux ip.Addr and ip.Link plugins #1079
Open
gcmoreira
wants to merge
15
commits into
volatilityfoundation:develop
Choose a base branch
from
gcmoreira:linux_ifconfig_plugin
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+579
−9
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
82668af
Linux - Added linux.ifconfig.Ifconfig plugin
gcmoreira 6b3bbad
Fix exception. Although it will be auto-instantiated it's better to e…
gcmoreira 6e0ffc9
Plugin renamed. Added net iface status and other improvements from @e…
gcmoreira 97007e8
Minor fixes
gcmoreira 620b9b4
Fix: Explicit returns mixed with implicit (fall through) returns
gcmoreira cd867bf
Merge branch 'volatilityfoundation:develop' into linux_ifconfig_plugin
gcmoreira 5a8a0de
Fix docstring typos
gcmoreira c72fa75
Convert IF_OPER_STATES to enum
gcmoreira 1b153cc
Manage net_device flag default value & error
gcmoreira 6f1e7c2
Add test for linux.ip.Addr and linux-sample-1.bin
gcmoreira 260fbd8
Python os.path module precisely does that by checking the current pla…
gcmoreira 7b1c75c
Linux: Add the linux.ip.Link plugin by @eve-mem
gcmoreira 8b6bd0f
Add linux.ip.Link test using linux-sample-1.bin image
gcmoreira 5219e8a
Remove lowercase matching from linux.ip.Addr test
gcmoreira 828b688
Fix issue with net namespace id and improve code
gcmoreira File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# This file is Copyright 2023 Volatility Foundation and licensed under the Volatility Software License 1.0 | ||
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0 | ||
# | ||
|
||
from typing import List | ||
from volatility3.framework import interfaces, renderers, constants | ||
from volatility3.framework.configuration import requirements | ||
from volatility3.framework.interfaces import plugins | ||
|
||
|
||
class Addr(plugins.PluginInterface): | ||
"""Lists network interface information for all devices""" | ||
|
||
_required_framework_version = (2, 0, 0) | ||
|
||
_version = (1, 0, 0) | ||
|
||
@classmethod | ||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: | ||
return [ | ||
requirements.ModuleRequirement( | ||
name="kernel", | ||
description="Linux kernel", | ||
architectures=["Intel32", "Intel64"], | ||
), | ||
] | ||
|
||
def _gather_net_dev_info(self, net_dev): | ||
mac_addr = net_dev.get_mac_address() | ||
promisc = net_dev.promisc | ||
operational_state = net_dev.get_operational_state() | ||
iface_name = net_dev.get_device_name() | ||
iface_ifindex = net_dev.ifindex | ||
try: | ||
net_ns_id = net_dev.get_net_namespace_id() | ||
except AttributeError: | ||
net_ns_id = renderers.NotAvailableValue() | ||
|
||
# Interface IPv4 Addresses | ||
in_device = net_dev.ip_ptr.dereference().cast("in_device") | ||
for in_ifaddr in in_device.get_addresses(): | ||
prefix_len = in_ifaddr.get_prefix_len() | ||
scope_type = in_ifaddr.get_scope_type() | ||
ip_addr = in_ifaddr.get_address() | ||
yield net_ns_id, iface_ifindex, iface_name, mac_addr, promisc, ip_addr, prefix_len, scope_type, operational_state | ||
|
||
# Interface IPv6 Addresses | ||
inet6_dev = net_dev.ip6_ptr.dereference().cast("inet6_dev") | ||
for inet6_ifaddr in inet6_dev.get_addresses(): | ||
prefix_len = inet6_ifaddr.get_prefix_len() | ||
scope_type = inet6_ifaddr.get_scope_type() | ||
ip6_addr = inet6_ifaddr.get_address() | ||
yield net_ns_id, iface_ifindex, iface_name, mac_addr, promisc, ip6_addr, prefix_len, scope_type, operational_state | ||
|
||
def _generator(self): | ||
vmlinux = self.context.modules[self.config["kernel"]] | ||
|
||
net_type_symname = vmlinux.symbol_table_name + constants.BANG + "net" | ||
net_device_symname = vmlinux.symbol_table_name + constants.BANG + "net_device" | ||
|
||
# 'net_namespace_list' exists from kernels >= 2.6.24 | ||
net_namespace_list = vmlinux.object_from_symbol("net_namespace_list") | ||
for net_ns in net_namespace_list.to_list(net_type_symname, "list"): | ||
for net_dev in net_ns.dev_base_head.to_list(net_device_symname, "dev_list"): | ||
for fields in self._gather_net_dev_info(net_dev): | ||
yield 0, fields | ||
|
||
def run(self): | ||
headers = [ | ||
("NetNS", int), | ||
("Index", int), | ||
("Interface", str), | ||
("MAC", str), | ||
("Promiscuous", bool), | ||
("IP", str), | ||
("Prefix", int), | ||
("Scope Type", str), | ||
("State", str), | ||
] | ||
|
||
return renderers.TreeGrid(headers, self._generator()) | ||
|
||
|
||
class Link(plugins.PluginInterface): | ||
"""Lists information about network interfaces similar to `ip link show`""" | ||
|
||
_required_framework_version = (2, 0, 0) | ||
_version = (1, 0, 0) | ||
|
||
@classmethod | ||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: | ||
return [ | ||
requirements.ModuleRequirement( | ||
name="kernel", | ||
description="Linux kernel", | ||
architectures=["Intel32", "Intel64"], | ||
) | ||
] | ||
|
||
def _gather_net_dev_link_info(self, net_device): | ||
mac_addr = net_device.get_mac_address() | ||
operational_state = net_device.get_operational_state() | ||
iface_name = net_device.get_device_name() | ||
mtu = net_device.mtu | ||
qdisc_name = net_device.get_qdisc_name() | ||
qlen = net_device.get_queue_length() | ||
try: | ||
net_ns_id = net_device.get_net_namespace_id() | ||
except AttributeError: | ||
net_ns_id = renderers.NotAvailableValue() | ||
|
||
# Format flags to string. Drop IFF_ to match iproute2 'ip link' output. | ||
# Also, note that iproute2 removes IFF_RUNNING, see print_link_flags() | ||
flags_list = [ | ||
flag.replace("IFF_", "") | ||
for flag in net_device.get_flag_names() | ||
if flag != "IFF_RUNNING" | ||
] | ||
flags_str = ",".join(flags_list) | ||
|
||
yield net_ns_id, iface_name, mac_addr, operational_state, mtu, qdisc_name, qlen, flags_str | ||
|
||
def _generator(self): | ||
vmlinux = self.context.modules[self.config["kernel"]] | ||
|
||
net_type_symname = vmlinux.symbol_table_name + constants.BANG + "net" | ||
net_device_symname = vmlinux.symbol_table_name + constants.BANG + "net_device" | ||
|
||
# 'net_namespace_list' exists from kernels >= 2.6.24 | ||
net_namespace_list = vmlinux.object_from_symbol("net_namespace_list") | ||
for net_ns in net_namespace_list.to_list(net_type_symname, "list"): | ||
for net_dev in net_ns.dev_base_head.to_list(net_device_symname, "dev_list"): | ||
for fields in self._gather_net_dev_link_info(net_dev): | ||
yield 0, fields | ||
|
||
def run(self): | ||
headers = [ | ||
("NS", int), | ||
("Interface", str), | ||
("MAC", str), | ||
("State", str), | ||
("MTU", int), | ||
("Qdisc", str), | ||
("Qlen", int), | ||
("Flags", str), | ||
] | ||
|
||
return renderers.TreeGrid(headers, self._generator()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also looks like it could be a python Enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm here changing this to an Enum makes the code a bit complicated... have a look at how it's used in
_get_flag_choices()
and_get_net_device_flag_value()
to support both kernels <3.15 and >=3.15.