Obtaining MACs on a Layer 3 port via SNMP? - snmp

I'm working on a script to map servers that are connected into our switches and routers. I have it working to map layer two ports, using the algorithm listed at http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a00801c9199.shtml to pull out the MAC addresses.
Layer 3 ports are another matter. These are ports that don't show up in the 'sh vlan' command on a router/layer 3 switch. Ideally, I'd like to use the MAC addresses present in these ports, underlying the layer 3 connection, as that's a bit more 'permanent' than the IP address - these do show up in the MAC-address table on the device. However, the fact that these ports don't have an associated VLAN, and that the MAC retrieval via SNMP is VLAN-indexed, makes it quite difficult.
I've been banging my head against this for about a week or so, but nothing I try/find seems to allow me to get the non-VLAN MAC addresses. Is it possible to map the layer three ports this way, or will I need to use layer 3 (IP address) mapping?

If you are connected via layer 2 to the device, you could just use a ping on the layer 3 address to generate an arp lookup and then look in the arp cache for the mac... This would work for any layer 3 port, even logical ports like the layer 3 version of Portchannels.
This is probably the easiest way.
If you want to be 100% in the realm of SNMP:
To get the interface table for that device, walk the below oid. It will return
the list of all interfaces on that device. This should work on any device (even a server) runnning a SNMP agent:
.1.3.6.1.2.1.2.2.1.2
This will give you a list of interface numbers (last digit in OID), and the interface descriptions. It works for SVI and physical interfaces, not sure about logical types other than SVI.
Then for each interface, to get it's mac (where x is the value in the interface table):
.1.3.6.1.2.1.2.2.1.6.x
This gives you the mac. (Leading 0's can be truncated on some devices.)
However, you will need atleast 1 layer 3 address on each device to do the snmpwalk and get.
If you just want all the macs, then walk this oid:
.1.3.6.1.2.1.2.2.1.6
I use this approach to do something similar on a large network.

Related

How to identify a HID after it's moved to a different port on Windows

I'm on Windows and am trying to store calibration data for game controllers connected via USB and am trying to find a value which uniquely identifies them in a port independent way.
There is the HidD_GetSerialNumberString function but i've read here that it's uncommon for devices to have serial numbers and indeed when i try to read one f.e. from a PS4 controller HidD_GetSerialNumberString returns FALSE and GetLastError returns ERROR_INVALID_PARAMETER.
Is there any other data available which can be accessed to achieve this?
You can try to use instance ID for your HID device (call CM_Get_Device_Interface_Property with device interface path and DEVPKEY_Device_InstanceId property and use string after last & char). It should be unique and persistent per system restarts. But it is not guaranteed if serial number is not provided (in this case instance ID will be different if device is plugged into different usb port)...
More info on this here: https://stackoverflow.com/a/56885175/1795050

A driver has enumerated two child PDO's that returned identical Device ID's

I have a kmdf bus driver PCI\VEN_XXXX&DEV_XXXX that creates two statically enumerated PDOs with serial numbers: 217 and 218; one for each Ethernet port. The PDO hardware id is ROOT\MY_NIC_PORT so I can install a NDIS Miniport driver on them.
The bus driver passes SDV and Verifier; but, on reboot two more PDOs get enumerated. On the next reboot I get a duplicate pdo crash.
The toaster example used the device class guid as part of the hardware id. When I tried that my NIC ports no longer showed up in device manager.
Any debug suggestion or work around idea would be appreciated?
pnpCaps.LockSupported = WdfFalse;
pnpCaps.EjectSupported = WdfTrue;
pnpCaps.Removable = WdfTrue;
pnpCaps.DockDevice = WdfFalse;
pnpCaps.UniqueID = WdfTrue;
pnpCaps.SilentInstall = WdfTrue;
pnpCaps.SurpriseRemovalOK = WdfTrue;
pnpCaps.HardwareDisabled = WdfFalse;
pnpCaps.NoDisplayInUI = WdfFalse;
pnpCaps.Address = SerialNo;
pnpCaps.UINumber = SerialNo;
************************************************************
Driver Verifier detected violation:
A driver has enumerated two child PDO's that returned identical Device
ID's.
CulpritAddress = FFFFF8025ED309C4, DeviceObject1 = FFFFE3882FB2F300,
DeviceObject2 = FFFFE3882EBF88D0.
************************************************************
There are a few versions of the toaster bus sample -- assuming you started with this one, then note that it saves its list of child PDOs in the registry. My guess is that your driver is both loading PDOs from the registry, and trying to dynamically create some too.
Set a breakpoint on your driver's version of Bus_PlugInDevice, and see how often it's getting called. Make sure it's never getting called 2x with the same Instance ID.
To clear up a bit of the naming thing: a device setup class is a GUID that is totally unrelated to its hardware ID. For NICs that want to interoperate with the OS's networking stack, you must use the NET setup class, {4d36e972-e325-11ce-bfc1-08002be10318}. You can put anything you want into your hardware ID. I don't really encourage you to put "ROOT\" in there, since that could be confused with a root-enumerated device (which your devices are not). Instead, you can use "yourcompany_yourdevice\port1" as a hardware ID.
While you're thinking about naming things, there are a few things to note about hardware IDs:
Once you assign a HWID, it's rather difficult to change it in a future driver update, without breaking customers who had already installed your device. So get it right the first time.
Once you assign an Instance ID, don't change or reuse it for the lifetime of the device. Otherwise you'll cause this bugcheck, or cause IP addresses to bounce around / get reset. The OS ultimately uses the Instance ID to figure out which NIC port to bind an IP address to.
Think about what happens if someone plugs 2 of your device into a system. Make sure your Instance ID is unique across all ports. You can do this by encoding into the Instance ID the PCI device serial number (if it has one) or by falling back to the PCI bus:device:function.
Don't lump together different types of hardware under the same hardware ID. For example, if the deluxe version of your device supports checksum offload, but the regular version does not -- you should use 2 different hardware IDs for these two different devices. Otherwise it gets difficult to write a single INF that has keywords for both.

Why does SCSI standard allow a device to have both multiple "ports" and multiple "logical units"?

I'm trying to understand the low-level details of SCSI. The SCSI standards (such as the SAM-5 SCSI Architecture document) state that a single SCSI device can have multiple "target ports", and also multiple "logical units". When an initiator sends a request to read/write data to a target, it needs to specify both the desired target port and the logical unit number.
It seems that either just a port number or just a logical unit number would be enough to perform the needed multiplexing, so a single SCSI interface can provide access to multiple data sources/sinks.
Do SCSI devices in the real world actually provide multiple target ports and multiple logical units?
If you can provide an example of a device which has multiple target ports, and one which has multiple logical units, giving an idea of what ports/LUNs are used for in practice, that would be very helpful.
Any SAN device provides multiple ports (multiple FC ports and/or multiple iSCSI ports) and also provides multiple LUNs over each of these ports. The exposed LUNs may differ from port to port and the mapping of LUN ID to a volume may differ between the ports so LUN 1 may be volume 23 on port FC1 and LUN 3 on port iSCSI 2.
The port is the physical connection to the world.
The LUN is a logical identifier for a volume on a port.
The volume is the logical entity that is exposed to the world through the LUN and port mappings.

How to identify PC (motherboard) in win32 api? [duplicate]

How to uniquely identify computer (mainboard) using C#(.Net/Mono, local application)?
Edition. We can identify mainboard in .Net using something like this (see Get Unique System Identifiers in C#):
using System.Management;
...
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_MotherboardDevice");
...
But unfortunately Mono does not support System.Management. How to do it under Mono for Linux? - I don't know :(
Write a function that takes a few unique hardware parameters as input and generates a hash out of them.
For example, Windows activation looks at the following hardware characteristics:
Display Adapter
SCSI Adapter
IDE Adapter (effectively the motherboard)
Network Adapter (NIC) and its MAC Address
RAM Amount Range (i.e., 0-64mb, 64-128mb, etc.)
Processor Type
Processor Serial Number
Hard Drive Device
Hard Drive Volume Serial Number (VSN)
CD-ROM / CD-RW / DVD-ROM
You can pick up a few of them to generate your unique computer identifier.
Please see: Get Unique System Identifiers in C#
You realistically have MotherboardID, CPUID, Disk Serial and MAC address, from experience none of them are 100%.
Our stats show
Disk serial Is missing 0.1 %
MAC Is missing 1.3 %
Motherboard ID Is missing 30 %
CPUID Is missing 99 %
0.04% of machines tested yielded no information, we couldn't even read the computer name. It maybe that these were some kind of virtual PC, HyperV or VMWare instance, or maybe just very locked down? In any case your design has to be able to cope with these cases.
Disk serial is the most reliable, but easy to change, mac can be changed and depending on the filtering applied when reading it can change if device drivers are added (hyperv, wireshark etc).
Motherboard and CPUID sometimes return values that are invalid "NONE", "AAAA..", "XXXX..." etc.
You should also note that these functions can be very slow to call (they may take a few seconds even on a fast PC), so it may be worth kicking them off on a background thread as early as possible, you ideally don't want to be blocking on them.
Try this:
http://carso-owen.blogspot.com/2007/02/how-to-get-my-motherboard-serial-number.html
Personally though, I'd go with hard drive serial number. If a mainboard dies and is replaced, that PC isn't valid any more. If the HDD drive is replaced, it doesn't matter too much because the software was on it.
Of course, on the other hand, if the HDD is just moved elsewhere, the information goes with it, so you might want to look at a combination of serial numbers, depending what you want it for.
How about the MAC address of the network card?

SNMP - get complete Mac table in one call

For my project I need to download mac table from switch and do it as fast as possible. Official solution is kind of slow. It requires to get list of all Vlan's, and for each one trigger separate call of snmpwalk with OID=.1.3.6.1.2.1.17.4.3.1.1 and community string indexed with vlan number. It can take significant amount of time, since number of vlan's on our switches ranges in tens.
Is there a way to get all mac addresses from mac table at once(some special community index representing all available vlan indexes)?
Thanks in advance..
I think BRIDGE-MIB::dot1dTpFdbTable (1.3.6.1.2.1.17.4.3) will do the job. One can simply retrieve dot1dTpFdbPort (1.3.6.1.2.1.17.4.3.1.2) to retrieve learned MAC -> PORT table. For my DLINK DGS-1216T I can get mac-to-port table from my Linux box by this command:
$ snmpwalk -O0sUX -v2c -Cc -c public 192.168.0.1 BRIDGE-MIB::dot1dTpFdbPort
Additionally I found extra (17th) port number for maintenance MAC.
Do you try to retreive the ipNetToMediaTable ({iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) ip(4) ipNetToMediaTable(22)} or 1.3.6.1.2.1.4.22) from your switch management address. It represents the IP Address Translation table used for mapping from IP addresses to physical addresses.
----EDIT----
If you want to Use SNMP to Find a Port Number from a MAC Address on a Catalyst Switch with a minimum of frames you can us a Get-Bulk PDU, it assume that you switch is SNMP V2c.

Resources