Реальная задача имеет специфику, поэтому чтобы не вызывать путаницу, сформилирую ее на абстрактном примере.
Есть некие устройства, которые могут соединяться между собой. Для простоты можно считать эти устройства аналогами хабов/свитчей (или концентраторов/коммутаторов, кому какая терминология удобнее).
Устройства бывают разных типов, у каждого типа есть определенное количество портов.
Устройства соединяются между собой. Схема (топология) соединений может быть различной, но для простоты можно считать, что кольца отсутствуют и устройства соединяются звездой, либо лучами (каскадом).
Пример возможных соединений на рисунке (круглый элемент — корневое устройство, их может быть несколько):
Для каждого устройства можно узнать его уникальный идентификатор (если что, это MAC-адрес).
Для каждого устройства можно также с каждого порта получить список присутствующих идентификаторов, они будут показывать, какие устройства подключены на данный порт (или отсутствие каких-либо подключенных устройств).
Т.е. задача разбивается на три этапа.
1. Просканировать все устройства, для каждого устройства определить его тип и идентификатор.
2. Получить список идентификаторов на каждом порту каждого устройства.
3. На основании полученных данных построить схему подключения.
Первые два пункта можно считать решенными.
Третий пункт решается следующим образом.
3.1. Определить "восходящий" порт (uplink), по которому устройство подключено ко всей сети. Для этого достаточно определить, в каком порту присутствует идентификатор корневого устройства.
3.2. Определить "нисходящие" порты (downlinks), к которым подключены остальные устройства. Это будут все порты, в которых присутствуют идентификаторы, за исключением uplink-порта.
3.3. Данные из п.3.2 дадут информацию о том, какие устройства подключены на каждом порту, но не о том, в каком порядке они следуют. Для этого итеративно (сверху вниз) по каждому порту выполняем следующее:
3.3.1. Для начала определим множество A (все идентификаторы с порта, включая идентификатор текущего устройства). Текущее устройство будем считать родительским, подключенные к порту устройства будем считать опрашиваемыми.
3.3.2. Для каждого опрошенного устройства определим uplink и для uplink получим список идентификаторов, ограничив их множеством A. Те устройства, у которых в результате на uplink будет присутствовать только идентификатор родительского устройства, являются устройствами первого уровня в текущей ветке.
3.3.3. Получив список всех устройств первого уровня в текущей ветке, повторим процедуры начиная с п.3.2.
(под опросами в разделе 3.3 подразумевается не реальный опрос, а использование ранее полученных в п.2 данных)
Это пока не готовое решение, а рассуждения. Но я возможно что-то упустил и есть более эффективные и быстрые способы построения схемы соединений.