Posts on Linux

Interpreting the output of lspci


Posted by Diego Assencio on 2015.11.09 under Linux (Shell)

On Linux, the lspci command lists all PCI devices connected to a host (a computer). Modern computers and PCI devices communicate with each other via PCI Express buses instead of the older Conventional PCI and PCI-X buses since the former buses offer many advantages such as higher throughput rates, smaller physical footprint and native hot plugging functionality. The high performance of the PCI Express bus has also led it to take over the role of other buses such as AGP; it is also expected that SATA buses too will be replaced by PCI Express buses in the future as solid-state drives become faster and therefore demand higher throughputs from the bus they are attached to (see this article for more on this topic).

As a first step, open a terminal and run lspci without any flags (note: lspci may show more information if executed with root privileges):

lspci

This is the output I get on my laptop:

00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)
00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 0b)
00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 0b)
00:14.0 USB controller: Intel Corporation Lynx Point-LP USB xHCI HC (rev 04)
00:16.0 Communication controller: Intel Corporation Lynx Point-LP HECI #0 (rev 04)
00:1b.0 Audio device: Intel Corporation Lynx Point-LP HD Audio Controller (rev 04)
00:1d.0 USB controller: Intel Corporation Lynx Point-LP USB EHCI #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Lynx Point-LP LPC Controller (rev 04)
00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04)
00:1f.3 SMBus: Intel Corporation Lynx Point-LP SMBus Controller (rev 04)

Each line on the output above shows a PCI device. Each device is given a bus number, a device number and a function number. On Linux, PCI devices are also given domain numbers, but they are usually omitted by lspci since very often all devices have the same domain number (usually zero). These four numbers are assigned by Linux to each device either on boot or when a device is hot-plugged. Since the PCI specification permits a system to host up to 256 buses, nonzero domain numbers are only used to group PCI buses in very large systems. Each bus can host up to 32 devices, and a PCI device can have up to eight functions. In more technical terms, a device's location is specified by a 16-bit domain number, an 8-bit bus number, a 5-bit device number and a 3-bit function number; the last three numbers are commonly referred to as the device's BDF or B/D/F (for bus/device/function).

Let's analyze one of the output lines above. Take a look at the first one:

00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)

The highlighted portion of this line shows the device's BDF: it has bus number 00, device number 00 and function number 0. This device's class is "Host bridge", its vendor is "Intel Corporation", its name is "Haswell-ULT DRAM Controller" and its revision ("rev") is 11 (0b in hexadecimal). The revision number defines the device's chipset and firmware versions. This device is a PCI host bridge: it bridges between all PCI devices and buses on one side and the processor and main memory on the other side.

Consider now the second line from bottom to top:

00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04)

This line shows a device with bus number 00, device number 1f and function number 2. This device's class is "SATA controller", its vendor is "Intel Corporation" and its name is "Lynx Point-LP SATA Controller 1 [AHCI mode]". In other words, it is a SATA controller operating in AHCI mode. Notice that this SATA controller is seen as a function of a device which also contains an ISA bridge (more precisely, a PCI/ISA bridge) and an SMBus controller: they all have the same device and bus numbers but distinct function numbers.

A natural question at this point is: how does the operational system obtain the class, name and vendor from a PCI device? The answer is simple: every PCI device has a set of registers called the device's configuration space which, among other things, display the device ID (DID), the vendor ID (VID) and the device class to the operational system. These are just numeric codes which the operational system maps into human-readable names through a predefined table. Vendor IDs are assigned by a group of companies called the PCI Special Interest Group and device IDs are assigned by their respective vendors. To display these IDs with the lspci command, use the -nn flag. For instance, try running:

lspci -nn

The output now shows the class codes (first highlighted values in each row) and the vendor and device IDs in the form [vendor-id:device-id] right after the device names:

00:00.0 Host bridge [0600]: Intel Corporation Haswell-ULT DRAM Controller [8086:0a04] (rev 0b)
00:02.0 VGA compatible controller [0300]: Intel Corporation Haswell-ULT Integrated Graphics Controller [8086:0a16] (rev 0b)
00:03.0 Audio device [0403]: Intel Corporation Haswell-ULT HD Audio Controller [8086:0a0c] (rev 0b)
00:14.0 USB controller [0c03]: Intel Corporation Lynx Point-LP USB xHCI HC [8086:9c31] (rev 04)
00:16.0 Communication controller [0780]: Intel Corporation Lynx Point-LP HECI #0 [8086:9c3a] (rev 04)
00:1b.0 Audio device [0403]: Intel Corporation Lynx Point-LP HD Audio Controller [8086:9c20] (rev 04)
00:1d.0 USB controller [0c03]: Intel Corporation Lynx Point-LP USB EHCI #1 [8086:9c26] (rev 04)
00:1f.0 ISA bridge [0601]: Intel Corporation Lynx Point-LP LPC Controller [8086:9c43] (rev 04)
00:1f.2 SATA controller [0106]: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] [8086:9c03] (rev 04)
00:1f.3 SMBus [0c05]: Intel Corporation Lynx Point-LP SMBus Controller [8086:9c22] (rev 04)

As mentioned above, domain numbers are omitted since they are all equal to zero. To force lspci to display them, run it with the -D flag:

lspci -D

The domain numbers are highlighted in the output shown below. Domain numbers range from 0000 to ffff in hexadecimal notation (i.e., there are 65536 valid domain numbers), but below you can see that all devices are given the same domain number 0000:

0000:00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)
0000:00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 0b)
0000:00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 0b)
0000:00:14.0 USB controller: Intel Corporation Lynx Point-LP USB xHCI HC (rev 04)
0000:00:16.0 Communication controller: Intel Corporation Lynx Point-LP HECI #0 (rev 04)
0000:00:1b.0 Audio device: Intel Corporation Lynx Point-LP HD Audio Controller (rev 04)
0000:00:1d.0 USB controller: Intel Corporation Lynx Point-LP USB EHCI #1 (rev 04)
0000:00:1f.0 ISA bridge: Intel Corporation Lynx Point-LP LPC Controller (rev 04)
0000:00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04)
0000:00:1f.3 SMBus: Intel Corporation Lynx Point-LP SMBus Controller (rev 04)

The PCI devices can be displayed on a treelike structure which reflects the actual physical structure of the PCI buses. To see it, run:

lspci -tv

The -v flag is there just to have the device vendors and names displayed as well, but can be omitted if you do not need them. As the output below shows, all PCI devices on my laptop are connected to the same bus (00):

-[0000:00]-+-00.0  Intel Corporation Haswell-ULT DRAM Controller
           +-02.0  Intel Corporation Haswell-ULT Integrated Graphics Controller
           +-03.0  Intel Corporation Haswell-ULT HD Audio Controller
           +-14.0  Intel Corporation Lynx Point-LP USB xHCI HC
           +-16.0  Intel Corporation Lynx Point-LP HECI #0
           +-1b.0  Intel Corporation Lynx Point-LP HD Audio Controller
           +-1d.0  Intel Corporation Lynx Point-LP USB EHCI #1
           +-1f.0  Intel Corporation Lynx Point-LP LPC Controller
           +-1f.2  Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode]
           \-1f.3  Intel Corporation Lynx Point-LP SMBus Controller

Here is what the output of lspci -tv looks like on a bigger system such as a server (parts of the output were omitted for brevity; notice that all domain numbers are again zero, but the devices are no longer all under the same bus):

-+-[0000:3f]-+-00.0  Intel Corporation Xeon 5600 Series QuickPath Architecture Generic Non-core Registers
 |           +-00.1  Intel Corporation Xeon 5600 Series QuickPath Architecture System Address Decoder
 |           +-02.0  Intel Corporation Xeon 5600 Series QPI Link 0
...
 +-[0000:3e]-+-00.0  Intel Corporation Xeon 5600 Series QuickPath Architecture Generic Non-core Registers
 |           +-00.1  Intel Corporation Xeon 5600 Series QuickPath Architecture System Address Decoder
 |           +-02.0  Intel Corporation Xeon 5600 Series QPI Link 0
 ...
 \-[0000:00]-+-00.0  Intel Corporation 5520 I/O Hub to ESI Port
             +-01.0-[05]----00.0  Hewlett-Packard Company Smart Array G6 controllers
             +-02.0-[06]--
             +-03.0-[11-13]--
             +-04.0-[14]--
             +-05.0-[15-17]--
             +-06.0-[18-1a]--
             +-07.0-[0e-10]--
             +-08.0-[0b-0d]--
             +-09.0-[08-0a]----00.0  Hewlett-Packard Company Smart Array G6 controllers
             +-0a.0-[07]--
...
             +-1c.0-[03]--+-00.0  Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
             |            \-00.1  Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
             +-1c.2-[04]--+-00.0  Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
             |            \-00.1  Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet
             +-1c.4-[02]--+-00.0  Hewlett-Packard Company Integrated Lights-Out Standard Slave Instrumentation & System Support
             |            +-00.2  Hewlett-Packard Company Integrated Lights-Out Standard Management Processor Support and Messaging
...
             +-1d.3  Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #6
             +-1d.7  Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #1
             +-1e.0-[01]----03.0  Advanced Micro Devices [AMD] nee ATI ES1000
             \-1f.0  Intel Corporation 82801JIB (ICH10) LPC Interface Controller

To display additional information about the PCI devices, run lspci with either -v, -vv or -vvv (more v's means more details, but you will hardly need more than -v since the additional information is not useful for most users):

lspci -v

The output is now significantly longer so only the lines for first three devices are displayed here. Notice that it now shows the drivers used by Linux to manage each device (except for the host bridge). Also, as a side note, you may have to run lspci with root privileges to have it display the capabilities of each device as well:

00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)
	Subsystem: Lenovo Device 3978
	Flags: bus master, fast devsel, latency 0
	Capabilities: [e0] Vendor Specific Information: Len=0c <?>

00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 0b) (prog-if 00 [VGA controller])
	Subsystem: Lenovo Device 3978
	Flags: bus master, fast devsel, latency 0, IRQ 58
	Memory at b0000000 (64-bit, non-prefetchable) [size=4M]
	Memory at a0000000 (64-bit, prefetchable) [size=256M]
	I/O ports at 4000 [size=64]
	Expansion ROM at <unassigned> [disabled]
	Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
	Capabilities: [d0] Power Management version 2
	Capabilities: [a4] PCI Advanced Features
	Kernel driver in use: i915

00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 0b)
	Subsystem: Lenovo Device 3978
	Flags: bus master, fast devsel, latency 0, IRQ 60
	Memory at b0510000 (64-bit, non-prefetchable) [size=16K]
	Capabilities: [50] Power Management version 2
	Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit-
	Capabilities: [70] Express Root Complex Integrated Endpoint, MSI 00
	Kernel driver in use: snd_hda_intel

Since the output of lspci -v might be too long, you can instruct lspci to display details for only a single device using the device's domain and BDF numbers. For example, to only show details for the SATA controller mentioned earlier, you would run:

lspci -v -s 00:1f.2

The domain number was omitted on the command above as it is not necessary to uniquely specify a PCI device. The output is now significantly shorter:

00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04) (prog-if 01 [AHCI 1.0])
	Subsystem: Lenovo Device 3978
	Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 57
	I/O ports at 4088 [size=8]
	I/O ports at 4094 [size=4]
	I/O ports at 4080 [size=8]
	I/O ports at 4090 [size=4]
	I/O ports at 4060 [size=32]
	Memory at b051b000 (32-bit, non-prefetchable) [size=2K]
	Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
	Capabilities: [70] Power Management version 3
	Capabilities: [a8] SATA HBA v1.0
	Kernel driver in use: ahci

Finally, you may pass the -mm flag to lspci if you wish to obtain output in machine-readable form (check the lspci documentation for more). In combination with the -v flag, the output can actually be comfortably read by humans. Run the command below:

lspci -vmm

The output is quite easy to interpret. This is what is looks like for the first three devices on my laptop:

Slot:	00:00.0
Class:	Host bridge
Vendor:	Intel Corporation
Device:	Haswell-ULT DRAM Controller
SVendor:	Lenovo
SDevice:	Device 3978
Rev:	0b

Slot:	00:02.0
Class:	VGA compatible controller
Vendor:	Intel Corporation
Device:	Haswell-ULT Integrated Graphics Controller
SVendor:	Lenovo
SDevice:	Device 3978
Rev:	0b

Slot:	00:03.0
Class:	Audio device
Vendor:	Intel Corporation
Device:	Haswell-ULT HD Audio Controller
SVendor:	Lenovo
SDevice:	Device 3978
Rev:	0b

The SVendor and SDevice values are determined by registers in the configuration space which are called the subsystem vendor ID (SVID) and the subsystem ID (SSID) respectively. While the vendor ID specifies the chipset manufacturer, the subsystem vendor ID specifies the card manufacturer. The subsystem ID is a number assigned by the subsystem vendor from the same number space as the device ID. These numbers are also displayed next to SVendor and SDevice if the -nn flag is passed as well.

Appendix: PCI configuration space

For the curious reader, lspci is also capable of displaying the configuration space of each PCI device in hexadecimal format. To see this, run lspci with either -x, -xx or -xxx (more x's means more bytes of the configuration space will be displayed). To better see where the device ID, the vendor ID and the class codes are located, I recommend you run lspci with the -nn flag as well:

lspci -xnn

The relevant areas are highlighted on the output shown below (in order: vendor ID, device ID and class code; all values have their bytes "inverted" because Intel processors use little-endian). Once again, only the first three devices are displayed for brevity:

00:00.0 Host bridge [0600]: Intel Corporation Haswell-ULT DRAM Controller [8086:0a04] (rev 0b)
00: 86 80 04 0a 06 00 90 20 0b 00 00 06 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 aa 17 78 39
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00

00:02.0 VGA compatible controller [0300]: Intel Corporation Haswell-ULT Integrated Graphics Controller [8086:0a16] (rev 0b)
00: 86 80 16 0a 07 04 90 00 0b 00 00 03 00 00 00 00
10: 04 00 00 b0 00 00 00 00 0c 00 00 a0 00 00 00 00
20: 01 40 00 00 00 00 00 00 00 00 00 00 aa 17 78 39
30: 00 00 00 00 90 00 00 00 00 00 00 00 00 01 00 00

00:03.0 Audio device [0403]: Intel Corporation Haswell-ULT HD Audio Controller [8086:0a0c] (rev 0b)
00: 86 80 0c 0a 06 04 10 00 0b 00 03 04 10 00 00 00
10: 04 00 51 b0 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 aa 17 78 39
30: 00 00 00 00 50 00 00 00 00 00 00 00 00 01 00 00
Comments (14) Direct link

Changing volume on PulseAudio via command line


Posted by Diego Assencio on 2015.10.15 under Linux (Audio)

If you are using a Linux distribution which manages sound using PulseAudio, you can still use amixer to change the master volume or to mute/unmute your speakers via command line.

As an example, to decrease the master volume by 5%, run:

amixer -D pulse sset Master 5%-

Similarly, to increase the master volume by 5%, run:

amixer -D pulse sset Master 5%+

To mute your speakers, run (you may also use unmute):

amixer -D pulse sset Master mute

Finally, you may toggle the "muted" state of your speakers with this command:

amixer -D pulse sset Master toggle
Comments (0) Direct link

Extracting a host's network traffic from a pcap file


Posted by Diego Assencio on 2015.07.24 under Linux (Networking)

If you have a pcap file from which you would like to extract all the network traffic associated with a given IP address, i.e., all packets sent to/from this IP address, you can use tcpdump to do the job:

tcpdump -r <in-file.pcap> -w <out-file.pcap> host <ip-address>

This command will read a pcap file called in-file.pcap as a packet stream and write all packets sent to/from the given IP address to an output pcap file out-file.pcap.

If all you want to do is visualize the host traffic on a terminal, just omit the -w <out-file.pcap> part. In this case, tcpdump will automatically convert IP addresses, port numbers, etc. to more human-readable values such as hostnames, "ssh" instead of 22 for the port number etc. You can disable this by adding -n to the end of the command.

As a side note, tcpdump will automatically determine a mapping between IP addresses and MAC addresses, so even traffic associated with the given host which is not IP traffic (e.g. ARP and other layer 2 protocols) may be extracted as well since tcpdump will be able to determine that those packets were sent/received by this host. If you really wish to have only IP traffic on the output, then use the following command:

tcpdump ip -r <in-file.pcap> -w <out-file.pcap> host <ip-address>

to extract only IPv4 traffic, and:

tcpdump ip6 -r <in-file.pcap> -w <out-file.pcap> host <ip-address>

to extract only IPv6 traffic.

Comments (0) Direct link