Тестирование и применение эмуляторов Cisco для моделирования гетерогенной IP сети

Устройство сети эмулятора UNetLab. Поддержка дополнительного оборудования Cisco и других производителей. Принцип генерации и захвата трафика. Функция поиска свободной сети. Описание способов передачи данных: интервального и последовательного режимов.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 05.09.2016
Размер файла 873,0 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru//

Размещено на http://www.allbest.ru//

Введение

В современных компьютерных сетях часто приходится сталкиваться с необходимостью настройки и проверки работоспособности сети, например, изучении времени прохода пакета, выпадения сети, а также проверка потери пакетов различными клиент-серверными приложениями. Однако, в большинстве случаев сеть уже используется, и если через нее пролегают маршруты других сетей, то придется либо выполнять тесты поверх работающей сети, либо прокладывать альтернативные маршруты, изолируя необходимый участок.

Для решения этой задачи существуют эмуляторы, которые позволяют построить сеть с использованием аутентичных образов используемых устройств и имитировать случайные процессы, проходящие в реальных сетях.К некоторым из них также представляется возможным подключить устройство генерирующее трафик.

Однако, создавать вручную 20 и более устройств, подключать их друг к другу, и импортировать конфигурацию каждого - довольно трудоемкая задача, на решение которой может уйти не мало времени. Здесь на помощь может прийти протокол SNMP, на котором построены большинство программ, позволяющих представить в графическом виде структуру сети. С его помощью программа извлекает необходимую информацию из MIBустройства, и позволяет создать на основе этого образ устройства в эмуляторе.

Данная программа призвана облегчить создание сетей в эмуляторе, путем копирования реальной сети в искусственную. Прежде всего она рассчитана на тестирование протоколов маршрутизации, например, прохождение пакета, рассылку сгенерированных и суммированных маршрутов в протоколе BGP. Также изучим генерацию и захват трафика в среде эмулятора.

Описание эмуляторов и постановка задач

Сравнение эмуляторов

Общеизвестно, что сети несовершенны, неважно частные или публичные. В них случаются задержки и ошибки. Они падают, теряют пакеты. Основная цель эмуляторов - создание среды, где пользователи смогут соединить свои устройства, приложения и сервисы, оценить их производительность, стабильность, функциональность и поведение, как если бы они работали в реальной сети. Как только они были протестированы в управляемой среде, пользователи могут предсказать как поведет себя их продукт в реальном мире.

Сетевая эмуляция - это техника, позволяющая тестировать производительность реальных приложений в виртуальной сети. Целью эмуляции является оценка работы сети, проверка влияния изменений или улучшение ее структуры.

И так, перед нами стоит задача переноса реальной сети в эмулятор, установка программного обеспечения, генерирующего пакеты, а также настройка и установка сервера с захватывающим и анализирующим трафик ПО.

Для начала разберем, какой из эмуляторов стоит использовать для поставленной задачи, учитывая его текущее состояние и перспективы развития в будущем.Следует также пояснить значение слова эмулятор в данном контексте. Существуют симуляторы сети, которые позволяют создать виртуальную сеть и воссоздать происходящие в ней случайные процессы с помощью математических формул. Чтобы лучше пониматьразберем как работает симуляция задержек в сети. Множество факторов могут влиять на ее появление, но одни из основных являются длина линии связи, состояние промежуточных узлов и количество джиттера (фазового или частотного отклонения передаваемого сигнала).Допустим, мы используем оптико-волоконную линию передачи данных,в данном случае величина задержек будет рассчитываться как, где Delay-задержка в секундах, Distance-длина в метрах, c-скорость света. В свою очередь эмуляторы сети вводят узлы и приложения в тестируемую сеть, изменяя поток трафика таким образом, чтобы он проходил через симулятор подвергаясь воздействиям, установленных в симуляторе. Узлы же в свою очередь управляются другим эмулирующим ПО.

В данной работе под словом «эмуляторы» рассматривается ПО, которое предоставляет сетевой симулятор без возможности вводить физические процессы (помехи, длина кабеля и т.д.) в совокупности с возможностью добавлять и конфигурировать узлы сети. В настоящее время бесспорными лидерами такого ПО являются GNS3, VIRL и UNetLab.

Чтобы лучше понимать какой из них нам стоит использовать, для начала разберем их основу - эмуляторы узлов сети.

В наше время у подавляющего большинства устройств, работающих на уровне выше физического существует свое ПО, и в большинстве случаев этим ПО является собственная операционная система. Существует три основных подхода к эмулированию устройств сети: Dynamips, QEMU и IOU.Разберем основные принципы их работы:

Dynamips был написан специально для Cisco маршрутизаторов. Он может эмулировать серии 1700, 2600, 3600, 3700 и 7200. GNS3 создавался как графический интерфейс к нему и некоторым его дополнениям (например Dynagen). Так как он эмулирует процессор маршрутизатора исполняя инструкцию за инструкцией, то он является довольно затратным. Эмуляцию коммутаторов, очевидно, он не поддерживает.

QEMU имеет ограничение на количество интерфейсов: 4 портг руппы по 4 интерфейса, всего 16. Однако несмотря на это имеет наибольшее количество образов по сравнению со своими конкурентами, и в отличии от них, образы не ограничиваются Cisco устройствами.

IOUиногда встречается под названием IOL. Сам по себе не имеет графического интерфейса, поэтому мало использовался вне Cisco до прихода iou-web, проекта, переросшего в UNetLab. Однако несмотря на это имеет полноценную поддержку L2 и L3, и используется при сдаче лабораторных экзаменов Cisco. В отличии от Dynamips использует меньше ресурсов процессора, и в отличии от QEMU не имеет ограничений по интерфейсам и сетевым платам.

Теперь, поговорим о графическом выборе эмуляторов, где они используются, о преимуществе и недостатках каждого.

Поддержка интерфейсов:

У VIRL нету прямой поддержки последовательных (serial, COM) интерфейсов, это конечно планируется исправить в будущем, но разработчики не могут назвать точного времени, у остальных 2х поддержка присутствует. Тем не менееUNetLab имеет всего 2 типа интерфейсов: serial и Ethernet.

GNS3

VIRL

Unetlab

serial

+

+

Поддержка дополнительного оборудования Cisco и других производителей

Хотя VIRLи предлагает легальные образы, его поддержка Cisco оборудования ограничивается классическими IOS,IOS-XR, IOS-XE и NX-OS. В GNS3 к этому добавляется возможность использованияXRv и ASAv с помощью интеграции с QEMU, однако она ограничивает используемый RAMвсего до2GB, что в свою очередь не дает запустить роутеры серии CSR1000v, который хоть и требует 3GB для запуска, предоставляет огромное количество функций. ТакжеQEMU ограничивает количество интерфейсов до 16. UNetLabже предоставляет огромный выбор как Cisco, так и других производителей (1), среди которых Alcatel 7750, JunipervMX иvSRX, HPvr и другие.VIRL, хоть и не оглашаетинтеграцию с кем либо, кроме Cisco, имеет поддержку похожего списка устройств. В GNS возможна интеграция, но IOL/IOUтребует отдельной виртуальной машины.

GNS3

VIRL

Unetlab

serial

+

+

devices

+

+

Простота в управлении, удаленный доступ, многопользовательский режим, доступность ПО.

VIRLи UNetLab поддерживают OOB(удаленный доступ)к интерфейсу командной строки, однако UNetLab позволяет подключится с удаленного компьютераиспользуя любой telnetили ssh клиент, и в отличии от GNS не требует установленного клиента, используя web-интерфейс. Также UNetLab поддерживает многопользовательский режим, что очень удобно если требуется раздельное хранилище работ. Годовая подписка на VIRL стоит порядка 200$, что является не очень приятным фактором, и даже с учетом подписки все равно остается ограничение на 15 устройств. GNS и UNL поставляются совершенно бесплатно.

GNS3

VIRL

Unetlab

serial

+

+

devices

+

+

management

+

Проведя сравнение, остается дополнить, что UNetLab- проект, перешедший из iou-web и, как развивающийся проект имеет большие перспективы в дальнейшем развитии и возможностях. Он предоставляет гибкий интерфейс, позволяющий добавлять новое оборудование, и с каждым обновлением предоставляет все больше функций. Так как интерфейс написан под браузер, то не составляет труда отыскать нужную функцию и понять принцип ее действия. Все его файлы поставляются с открытым кодом и описанием каждого из них.Дальнейшая работа будет происходить именно в нем.

Устройство сети эмулятора UNetLab

Простейшая сеть без картинок подписей и фигур состоит из узлов и сетей, связывающих эти узлы. Образы ОС узлов загружаются в директорию /opt/unetlab/addons/EMULATOR_NAME, где EMULATOR_NAME - имя используемого эмулятора: dynamips, iol или qemu. Каждый из этих образов должен иметь определенно название, допустим имя образа QEMUvIOS должно соответствовать шаблону /^vios-*/. Список всех шаблонов можно посмотреть в /opt/unetlab/html/includes/init.php. Текстовая конфигурация проекта находится в директории/opt/unetlab/labs/*.unl. и представляет собой файл xml формата. Файл имеет несколько основных элементов:

Корневойэлемент<labnameidversionsctripttimeout></lab>Содержит имя лабы, уникальный id, который генерируется несколькими функциями rand(), версию и таймаут.

<topology></topology>Означает начало структуры сети.

Топология состоит из структур узлов <nodes></nodes> и сетей<networks></networks>;

Каждый узел задается как <nodeidnametypetemplateimageEthernetnvramramserialdelayiconlefttop></node> и имеет ID узла (порядковый номер), его имя, тип эмулятора, шаблон названия, образ используемой ОС, количество портгрупп Ethernetи Serial, выделенное количество NVRAMи RAM, задержку до запуска узла при его старте, картинку, которая будет использоваться на его месте, и позициюотносительно верхнего левого угла экрана.

Сеть задается как <networkid typenamelef ttop/>. Где id- порядковый номер сети, name - имя сети, type- тип сети, если это Ethernet, то используется bridge, если сеть облачная, то используется название интерфейса, к которому она подключается, при использовании VMWareон будет выглядеть как pnetX.В версиях до 1.0 графический интерфейс был реализован по-другому, и неподключенные сети отображались на экране.

Именно для этого существовали параметры leftи top, однако сейчас они используются только для совместимости с прошлыми версиями и вполне вероятно скоро исчезнут. Также стоит отметить, что сети используются только для Ethernet и Cloud соединений, Serial не использует сети.

Каждый узел имеет список интерфейсов. Ethernet задается как

<interfaceidnametypenetwork_id/>, id рассчитываетсякак«номер портгруппы + номер интерфейса * 16», например, если интерфейс e1/3, то его id= 1 + 16 * 3 = 4. Имя интерфейса -- это его сокращенное название, каждый эмулятор использует свои названия интерфейсов, например, qemu использует Gigabit EthernetX/Y, что сокращается до GiX/Y. IOL использует просто EthernetX/Yили SerialX/Y, и сокращает их до eX/Y иsX/Y соответственно. network_idэто idсети, которая подключена к этому интерфейсу.

Serialинтерфейсызадаются<interfaceidtypenameremote_idremote_if/>, первые 3 параметры уже знакомы, remote_id отвечает за id узла, подключенного к другому концу Serial кабеля, а remote_if соответственно указывает на id интерфейса с другой стороны.

Также могут использоваться элементы вроде картинок, текста и фигур, но для генерации сети нам это не нужно, поэтому мы их рассматривать не будем.

Данные по узлу хранятся в /opt/unetlab/tmp/0/LAB_ID/NODE_ID. Где LAB_ID - это уникальный uuid, который был случайно сгенерирован, а NODE_ID - порядковый номер узла. Каждый эмулятор по-своему представляет хранимую информацию, допустим для эмулятора IOU нужны файлы NETMAP и символическая ссылка на файл iourc. В файле NETMAP создаются соединения между устройствами, а iourc предоставляет номер лицензии IOS. Стартовую конфигурацию он хранит в отдельном файле называющимся nvram_X, где X - пятизначный номер узла (если это 1, то X = 00001). QEMU хранит только 1 файл - файл настройки виртуальной машины, конфигурация хранится в нем же. Единственное общее что они имеют - файл wrapper.txt, хранящий логи о действиях и ошибках, происходящих в проекте.

Принцип генерации и захвата трафика

Обычно при тестировании создается узел генерирующий трафик под управлением пользователя, пакеты с него отправляются на виртуальный интерфейс сервера эмулятора, пройдя по его сети они подвергаются различным воздействиям: возможность потери, ошибки, задержки, джиттер. Каждый из таких пакетов нумеруется, и в конечном счете отлавливается и статистика передается на анализ пользователю. Но как уже говорилось, нам не нужно проверять физический уровень модели OSI, поэтому мы генерируем пакеты чтобы найти уязвимости и недоработки в настройке сети.

Для генерации трафика нам нужно виртуальное устройство в эмулируемой сети. Таковым может являться узел Unix с предустановленным на нем ПО, генерирующем трафик. Так как обычно live-cdобразы поставляются без предустановленных программ, то это не является оптимальным вариантом. На данный момент и UNetLab, и GNS3 поддерживают только дрон Ostinat oтрафик генератора, им мы и будем пользоваться. Дрон имеет 2 интерфейса - управляющий (management), на который приходят настройки трафика, необходимого сгенерировать и интерфейс подключенный к сети. Управляется дрон с ПК подключенного к управляющему интерфейсу. Настройки с этого компьютера задаются с помощью графического приложения Ostinato.

Так как в эмуляторе используются устройства компании Cisco, а в будущем и Juniper, то в качестве трафик анализатора будет выступать NetFlow. Что это такое? NetFlow позволяет собрать статистику прохода траффика на маршрутизируемых устройствах. Он не нуждается в установке каких-либо соединений межу роутером и другим устройством, как не нуждается и в изменениях в траффике или пакетах. Также он полностью прозрачен для сети, включая конечные устройства, по и сетевые устройства наподобие LAN коммутаторов. Его настройка выполняется на одном выбранном маршрутизаторе, то есть не нужно устанавливать его на всех устройствах данной сети.

Обычно NetFlow состоит из трех компонентов: сенсор, он же экспортер - захватывает траффик, и выделяет из проходящего трафика потоки, характеризуемые следующими параметрами:

Адрес источника;

Сетевой интерфейс источника

Адрес назначения;

Сетевой интерфейс назначения

Порт источника для UDP и TCP;

Порт назначения для UDP и TCP;

Тип и код сообщения для ICMP;

Номер протокола IP;

Флаги

Если сенсор настроен на экспорт, то он отсылает их следующему компоненту - коллектору. Как следует из названия, он предназначен для хранения записей. Если используется генератор и нужно отследить несколько потоков, то сенсор вполне может служить коллектором информации. Для анализа полученной информации используется третий компонент - анализатор, это приложение, которое позволяет наблюдать за пропускной способностью, изучать трафик для изолирования лишних пакетов, созданных приложениями, изучать узкие места сети, получать сообщения о внезапных всплесках трафика и многое другое.

Типичный вывод NetFlow выглядит так:

Protocol Total Flows Packets Bytes Packets Active(Sec) Idle(Sec)

-------- Flows /Sec /Flow /Pkt /Sec /Flow /Flow

TCP-BGP 71 0.0 1 49 0.0 2.5 15.8

UDP-other 17 0.0 1 328 0.0 0.0 15.7

ICMP 18966 6.7 10 28 72.9 0.1 22.9

Total: 19054 6.7 10 28 72.9 0.1 22.9

SrcIf SrcIPaddress DstIf DstIPaddress Pr TOS Flgs Pkts

Port Msk AS Port Msk AS NextHop B/Pk Active

Et1/1 52.52.52.1 Fd4/0 42.42.42.1 01 55 10 3748

0000 /8 50 0000 /8 40 202.120.130.2 28 17.8

Et1/2 52.52.52.1 Fd4/0 42.42.42.1 01 CC 10 3568

0000 /8 50 0000 /8 40 202.120.130.2 28 17.8

Возможно это и удобно для маленького числа сессий, но при большом количество их прочтение становится невозможным. Для этого большинство анализаторов имеют графическое представление траффика. Наиболее известные из них обладают огромными возможностями настройки анализа траффика и выполняют роль коллекторов в то же время - например Network Mapperот Solar Winds и Net Flow Analyzerот Cisco. Однако они являются платными, но существует и множество бесплатных ПО, как выполняющих роль только коллектора, так и только анализатора, например,FlowScan, вот пример его визуализации:

Здесь хорошо видно, что большая часть трафика черная и подписана как Other, разберемся почему это так? Как видно трафик делится по протоколам, а протокол определяется по порту, который использует приложение, сгенерировавшее этот трафик. Однако не все используют стандартные порты, и из-за этого получается черный трафик. Для устранения этого, Cisco разработало механизм NBAR (Network Based Application Recognition)-распознавание сетевых приложений. Он проводит глубокий анализ для первого пакета в потоке, и определяет к какой категории принадлежит данный трафик.

Выбор среды разработки

Теперь стоит определиться, как же перенести реальную сеть в эмулируемую? Почти все программы создающие карты сети имеет в своей основе 3 подхода: основанный на SNMP, активное зондирование (activeprobing) и анализ маршрутов.

Активное зондирование полагается на утилиты типа traceroute. Он проходит по адресам IP и возвращает пути к источнику. Объединяя данные этих путей можно представить себе карту маршрутизаторов. Анализ маршрутов предполагает изучение таблицы маршрутизации, и составление карты также, как это делает предыдущий метод.

Подход основанный на протоколе SNMP считывает данные с маршрутизаторов и коммутаторов через их MIB. Эти базы данных представляют собой иерархическую (древовидную) структуру, где каждое значение имеет свой идентификатор объекта (OID). Если не вдаваться в подробности, то структура запросов SNMP выглядит так:

Почти все современные маршрутизаторов имеют установленный протокол LLDP, который, работая на канальном уровне позволяет узнать какое устройство находится на обратной стороне канала, если, конечно это устройства использует такой же протокол. LLDPсам по себе не зависим от производителя, однако Cisco, Microsoft и некоторые другие (Nortel, Dell, Netgearetc.) имеют собственные протоколы, которые не всегда сочетаются между собой.

Мы будем использовать SNMP для отображения информации из MIB о LLDP, однако тут следует учитывать уровни, на которых эти протоколы работают: как уже говорилось LLDP работает на канальном уровне, это понятно, ведь чтобы узнать кто на обратной стороне канала достаточно послать фрейм, нет необходимости знать IPадрес. Но SNMP оперирует на прикладном уровне, соответственно нам нужен IP адрес чтобы подключаться к устройствам. Как известно, хорошо спроектированная сеть имеет три уровня: ядро, уровень распределения, уровень доступа.

И далеко не для всех коммутаторов уровня доступа устанавливается управляющий IP (managementIP), соответственно отсутствует возможность подключится к таковым.

LLDP протокол собирает информацию, которую затем хранит в MIB, она включает:

Имя системы и ее описание

Имя портов и их описание

VLAN

Адрес управляющегоIP (IP management address)

Уровни OSI на которых действует это устройство

Информацию о MAC/PHY

MDI (media dependent interface)

Агрегация каналов

Следует также сказать, что SNMP управляемая сеть состоит из трех ключевых компонентов: Менеджер, устройство, посылающее запросы Агенту -ПО запущенному на управляемом устройстве и trap приемнику. Trap - асинхронное уведомление о каком-то событие, посылаемое от агента к менеджеру. И приложение запущенному на менеджере -NMS (система сетевого управления). В данном случае мы будем использовать только агент и менеджер.

Для использования и развертывания протокола SNMP был написан набор ПО под названием Net-SNMP. Он поддерживает IPv4 и v6. Содержит библиотеку, набор приложений для командной строки, SNMP агента с возможностью расширения, а также модули на языках perlи python.

Далее будет рассматривать модуль для языка perl. Важно не спутать Net-SNMPи Net::SNMP. Последний предоставляет объектно-ориентированный интерфейс к протоколу SNMP. Приложения на perl могут также отображать или загружать информацию при помощи этого модуля. Оба они выполняют примерно одинаковые функции, но имеют совершенно разный синтаксис. Определяющим фактором было наличие модуля SNMP::Info написанного на основании Net-SNMP. Как уже говорилось, данные в удаленных устройствах представлены в виде OID. Если не вдаваться в подробности, то OID представляет собой лист дерева, и чтобы узнать какой-то идентификатор нужно пройти весь путь, начиная от корня. При это получается что-то вроде такого: {iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) system(1) sysName(5)}

Или в представлении номером 1.3.6.1.2.1.1.5. Это имя хоста, оно не является зависимым от производителя, однако не все значения будут такими. Допустим, как уже говорилось CDP является протоколом только для Ciscoи поддерживается еще HP. А LLDP используется Junior. Для каждого из них OID интерфейсов будут разными. Что же делает SNMP::Info? Он также использует ОО интерфейс к протоколу SNMP, при этом он нацелен на предоставление общего интерфейса для полученных данных, оставляя специфичные для производителей OIDв подклассах.

Для его использования необходимо иметь нужные MIB, базы данных которые хранят в себе OID. Каждый подкласс требует свои MIB, допустим для использования SNMP::Info::CDP нужны MIB отличающиеся от SNMP::Info::LLDP. Функции для извлечения информации о соседях тоже будут отличаться между различными протоколами обнаружения.

Настройка и сбор информации оборудования

Подготовка оборудования

Теперь, зная поверхностные теоретические основы протокола SNMP, подготовим устройства в сети. Недостаточно просто запустить процесс SNMP менеджера на устройстве, к которому нужно подключится, необходимо еще указать своего рода ключ. Данным ключом будет являться строкасообщества (communitystring). В ней указывается доступность сообществаи доступ к нему (чтение или чтение-запись). Обычно ключом является ACL (список доступа, пропускающий трафик только с определенного IPадреса).Внутри сети вполне можно установить открытое сообщество с доступом на чтение.

Router(config)#snmp-server manager

Router(config)#community public RO

На компьютере, если уже не установлен необходимо установить SNMP. Затем установить Net-SNMP и скачать необходимые MIB. Тут могут возникнуть некоторые проблемы, потому что для SNMP::Info::CDP необходимы только OLD-CISCO-MIB, но на деле только их оказывается мало, и приходится догружать еще несколько небольших модулей. Проверить работоспособность оборудования можно введя команду snmpwalk -vVERSION -cCOMMUNITYIP, где VERSIONэто используемая версия SNMP (1, 2, 2c, 3), COMMUNITY- сообщество, например, public или private, и IPэто ipадрес машины к которой мы подключаемся. Если не произошло таймаута и начали отображаться OID с устройства, значит все работает правильно.

Как мы уже говорили SNMP работает на 7ом уровне модели OSI, поэтому необходим IP адрес для подключения к устройству. Соответственно надо не забыть прописать маршруты до нужных нам сетей на компьютере, с которого будет запускаться программа. Также, нам не нужны устройства без стартовой конфигурации, поэтому ее нужно экспортировать. Обычно это и так делается в управляемых сетях, и ее достаточно скопировать с сервера на компьютер.

Сбор информации о сети

Вкратце опишем алгоритм работы составления сети программой:

Разберем каждый из блоков более подробно с описанием возможных затруднений, связанных либо с синтаксисам языка, либо с модулем SNMP::Info, которые могут возникнуть при написании программы.

Сначала мы вводим начальные настройки: предлагаем пользователю ввести путь где находятся конфигурации к устройствам, если путь не введен или введен, но не существует, то устанавливаем путь как текущую директорию. После пути предлагается ввести IP адрес устройства, к которому будет выполнено подключение. Если он не удовлетворяет шаблону IPадреса, то просим ввести еще раз и т.д.

Генерация id лабы - функция генерирующая уникальный идентификатор на основании 8 функций рандома. Каждая из них генерирует по 16 бит в шестнадцатеричной системе счисления и записывает их в строку вида '%04x%04x-%04x-%04x-%04x-%04x%04x%04x'. В самом эмуляторе каждая из этих частей используется для определения либо времени, узла и других переменных, в нашем же случае мы используем эту строку целиком. Запомним ее как uuid, она еще встретится.

Попытаемся открыть директорию, заданную пользователем и считать из нее все существующие файлы, не начинающиеся с символа '.'.

Откроем на чтение файл нашей лабы, так он сможет создаться, если еще не создан или очиститься, если уже существует. Так как спрашивать много параметров у пользователя на старте будет плохим тоном, то назовем ее lab_<first4bytesuuid>, где <first4bytesuuid> - первые 4 байта в строке id нашего проекта. Этот файл должен иметь расширение. unl и в него будет записываться топология устройств и сетей. Запишем в него стандартную информацию о версии XML, id проекта и общие элементы структуры, такие как <topology>, <networks>, <nodes>.

Создадим директорию, где будут храниться данные по лабе. При создании стоит учитывать из-под кого мы запускаем эту программу. Если создать директорию под пользователем 'root', то ее права на запись для обычных пользователей будут закрыты, а UNetLabбудет записывать как раз со стороны пользователя. Поэтому необходимо прописать команду chmod 0775 <path>, если мы находимся под root'ом, то добавим права на запись для пользователей, а если не имеем привилегий, значит мы и так создали директорию с правами записи для обычных пользователей, а chmod не сможет выполнится.

Далее зададим общие начальные параметры узла, которые по тем или иным причинам не могут быть использованы или изъяты с устройств: например, количество памяти,выделяемой на узел или его позиция на экране.

Запустим функцию анализа узла, передав в нее IP адрес, введённый пользователем. Чтобы получить информацию о различных OID устройства, необходимо создать структуру главного объекта:

my $info = new SNMP::Info(

AutoSpecify=> 1,

Debug=> 0,

LoopDetect=> 1,

DestHost=> $_[0],

Community=> $community_group,

Version=> 2

) orreturn 2;

Разберем каждый из аргументов:

AutoSpecify

Возвращает объект более специфичного класса (по умолчанию 0 -т.е. выключен)

Debug

Печатает много сообщений обработки. Если передать 2, то будет печатать еще подробнее

LoopDetect

Определяет зацикливание при проходе колонок таблицы get next, сравнивая IID для каждой колонки. Зацикливание устанавливается, если IID встретился больше 1 раза, в таком случае проход прекращается. По умолчанию 1.

Community и DestHost означают соответственно сообщество и хост или IP адрес устройства. Следует отметить что $_[0] - первый аргумент в списке переданных, то есть в нашем случае это IP адрес.

После подключения к хосту мы можем считать его информацию, в частности больше всего нас интересует его имя (hostname), уровни OSI на которых данное устройство функционирует и массивы, связанные с соседними устройствами, обнаруженными CDP. Так как мы уже подключились к устройству и получили его имя, то мы можем проверить - существует ли стартовая конфигурация к этому устройству. Если таковая имеется, то создадим папку узла в директории /opt/unetlab/tmp/0/$uuid/ , папку надо назвать порядковым номером узла. После скопируем в нее необходимую информацию - нашу конфигурацию, создадим файл NETMAPдля записи в него соединений и создадим символическую ссылку на iourc.

Изучая уровни на которых функционирует данное устройство, можно с небольшой погрешностью сказать каким устройством оно является. Например, коммутатор работает на 2ом уровне, коммутатор 3 уровне на 2 и 3, маршрутизатор на 2, 3, 4 и 7. На основании этих данных запишем название картинки, которая будет использоваться при отображении устройства(Switch.pngRouter.pngetc.).

Получаем список интерфейсов данного устройства, однако стоит упомянуть, что этот массив идет в обратном порядке, т.е. первый интерфейс будет стоять на последнем месте, из-за их заполнения на подобии стека. Поэтому надо переместить все элементы снизу-вверх.

Теперь проходя по интерфейсам, мы сможем получить нужного нам соседа, и извлечь его информацию:

my $port = $ifaces->{$ifid};

my $neighbor_ip = $c_ip->{$iface};

my $neighbor_port = $c_port->{$iface};

my $neigh_hostname = $c_id->{$iface};

Также стоит не забывать, что границы исследования задаются наличием конфигурационного файла, т.е. если в директории отсутствует файл с именем как у соседа, то рассматривать его при создании Ethernet интерфейсов не нужно.

Получив от соседа нужную информацию, мы преобразуем ее в нужный нам формат, допустим из порта с названием Ethernet1/2 мы извлекаем тип порта понижая регистр слова Ethernet, которое получилось путем функции splitпо регулярному выражению /\d/, которое означает, что мы разделяем по цифрам. Похожим образом преобразуем имя интерфейса в нужное нам, в данном случае в e1/2. Из него получаем идентификатор, который, как уже обсуждалось будет 33. Остался один параметр - network_id. Прежде чем рассказать, как его получить, неплохо представить себе, что по сути является network'ом в данном контексте.

Лучше всего представить себе простой кабель. У него есть 2 конца, оба из которых не могут находится в одном устройстве одновременно. Поэтому если у нас есть интерфейс и к нему требуется найти сеть, то проще провести аналогию с поиском кабеля для подключения двух узлов:

Функция поиска свободной сети принимает в себя аргументами 2 имени устройств. Ищет линию в файле соответствующую регулярному выражению /<network .* name="$hn1-$hn2/, или где имена расположены наоборот, так как неизвестно с какого узла создастся сеть /<network .* name="$hn2-$hn1/. После нахождения соответствия она вычленяет из строкиID данной сети и передает его в функцию isnetfree, которая принимает в себя параметром имя устройства и IDсети которое данное устройство хочет использовать. Сеть является свободной если у данного устройства ни один интерфейс не использует эту сеть.

При создании сети имя вводится как <имя текущего узла>-<имя соседнего узла>_<количество существующих сетей между ними + 1>. Это позволяет назвать уникальную сеть, имя которой говорит само за себя.

Последовательный интерфейс не требует сети, в свою очередь в нем нужно указать имя удаленного узла. По этой причине его возможно создать только после того как данные обоих узлов были созданы и имеются оба идентификатора узлов.

После создания интерфейсов следует изменить установленные по умолчанию количества портгрупп в serial и ethernet полях узла.Для этого мы проходим в файле .unl по строкам и записываем максимальную встретившуюся портгруппу, затем изменяем количество портгрупп в данном узле: для ethernet интерфейсов добавляя +1, потому что они начинаются с 0, а для serial оставляя, потому что они идут после ethernet и начинаются минимум с единицы. В конце закрываем файлы и директории, которые открывали во время исполнения и проверяем вернула ли нам ошибку одна из функций исследования узла. Если да - удаляем директорию и файл проекта.

Теперь сеть скопирована в эмулятор. Далее нужно вставить узел дрона генератора и подключить сеть к компьютеру с которого запускалась программа. Узел дрона - это образ Ostinato действующий под управлением эмулятора qemu. В поле ethernet подразумевается не количество групп портов, а количество одиночных интерфейсов. У дрона один интерфейс управляемый, обычно это самый первый - e0/0, к которому будет подключен менеджер Ostinato, а второй интерфейс подключен к сети. Чтобы соединить его с виртуальной сетью нужно создать network, и типом указать интерфейс на компьютере куда будет подключен узел. Эти виртуальные интерфейсы имеют название pnetX. В эмуляторе подключение к внешней сети отображается как облако.

Упрощение представления сети

Хотя сеть и была успешно перенесена в эмулятор, однако, если сейчас мы зайдем на web-интерфейс и взглянем на ее структуру расположения узлов, то заметим, что они все расположены крайне неудобно, и разобраться в такой сети не представляется возможным. Оно и понятно, ведь при добавлении узлов, нельзя разобраться где он должен находится чтобы не мешать своей позицией другим.

Существует множество способов упрощения представления графов, в данном случае рассматривается один из самых простых. И так авайте представим сеть, которая по сути является графом в виде системы, где узлы заменены стальными кольцами, а связи между ними - пружинами, формируя механическую систему. Сейчас такая система находится в неустойчивом состоянии. Но как только такую систему отпустят, она будет стремиться к минимальному энергетическому состоянию. Следует учитывать два примечания: используется логарифмирование по силе пружин, то есть сила, оказываемая пружиной будетГде dэто длина пружины, c1и c2-константы.Если не рассматривать возможность деформации пружины, то закон Гука имеет прямую зависимость силы от длины растяжения. То есть, если мы сильно растянем ее, она начнет сокращаться в обратном направлении настолько быстро, что перейдет через точку спокойствия. Это совершенно ненужное для данной задачи действие, поэтому здесь используется логарифмирование, чтобы избежать перехода через точку спокойствия.Заметим, что пружины не оказывают никакой силы при d=c2.

К этой системе по желанию можно добавить увеличенную силу отталкивания масс. При этом сила будетГде c3 это константа, а d - дистанция между точкам. Таким образом алгоритм можно представить, как:

Для большинства графов достаточными значениями будут:

c1= 2;

c2 = 1;

c3= 1;

c4= 0.1

а количество выполнений цикла около 100, т.е. M = 100;

Генерация трафика

Для генерации трафика необходимо установить на устройство, подключенное к виртуальной сети приложение Ostinato. У него существует множество настроек генерации трафика, но в общем они сводятся к следующим:

Выбирается порт с которого будет происходить генерация трафика. В данном случае это будет интерфейс дрона, подключённый непосредственно к компьютеру с Ostinato. эмулятор сеть тестирование

В списке потоков создается и настраивается новый поток

В нижней панели можно увидеть статистику сгенерированных пакетов с данного порта

Существует 2 способа передачи данных: интервальный и последовательный режимы:

1. При последовательном режиме потоки посылаются один за другим, как последовательности. Все пакеты одного потока посылаются до начала следующего. Например, у нас есть 2 потока: TCP и UDP. TCP настроен на посылку 100 пакетов частотой 10 пакетов/сек, а UDP настроен на 500 пакетов частотой 5 пакетов/сек. В режиме последовательной передачи 100 пакетов TCP отправятся первыми, а за ними пойдут 500 пакетов UDP.

2. Потоки посылаются интервальными промежутками на основании частоты всплесков (burstrate) или передачи пакетов. Это продолжительный режим, нельзя настроить количество пакетов на отправку, только их частоту. Возьмем те же 2 потока с частотой 10 пакетов/сек для TCPи 5 пакетов/сек для UDP. В интервальном режиме в секунду будет послано 15 пакетов, 10 из которых будут TCP и 5 UDP, порядок неизвестен.

Потоки можно настраивать, указывая протоколы, их содержание, флаги, настраивать поля переменной длины. Даже возможно составлять свой стек протоколов (например, IP overIP).

Захват трафика

Есть несколько разных путей настройки NetFlow. И хоть они во многом похожи, команды настройки отличаются. В данном случае рассмотрим новый FlexibleNetFlow.

Нужно создать и сконфигурировать три объекта: flow-record, flow-exporter и flow-monitor. Первый отвечает за представление записей и поля, которые они будут содержать. Второй отвечает за экспорт. Монитор соотносит рекордер с интерфейсом и далее в настройках интерфейса указываем какой монитор стоит использовать. Стоит помнить, что NetFlow настраивается на каждом интерфейсе отдельно.

Нам нужно создать рекордер и назвать его. В данном случае назовем его VRecord. В его настройках указываем инструкции для записей -какие поля нас интересуют.

Router(config)#flow recordVRecord

Router(config-flow-record)# match ipv4 protocol

Router(config-flow-record)# match transport source-port

Router(config-flow-record)# match transport destination-port

Router(config-flow-record)# match ipv4 tos

Router(config-flow-record)# match interface input

Router(config-flow-record)# collect interface output

Router(config-flow-record)# collect counter packets

Теперь укажем сервер экспорта интерфейс, который будет записывать в интерфейс источника записей и порт, на котором работает коллектор

Router(config)#flow exporter VExport

Router(config-flow-export)# destination X.X.X.X

Router(config-flow-export)# source Ethernet0/1

Router(config-flow-export)# transport udp X

Где X.X.X.X - IP адрес устройства с коллектором, а udpX - udp порт, который он прослушивает.

Создадим монитор, укажем в его настройках какой рекордер и экспортер мы хотим использовать, а также таймауты сессий передачи.

Router(config)#flow monitor VMonitor

Router(config-flow-monitor)#record VRecord

Router(config-flow-monitor)# exporter VExport

Router(config-flow-monitor)# cache timeout active 60

Router(config-flow-monitor)# cache timeout inactive 15

И наконец в настройках интерфейса укажем монитор, и направление трафика, который он будет прослушивать.

Router(config)#interface Ethernet0/1

Router(config-if)# ip flow monitor VMonitor input

.

Вывод

На сегодняшний день отсутствует система автоматического наблюдения и исправления неисправностей в сетях. Данная работа может рассматриваться как звено в автоматизировании управления, путем генерации трафика в эмулируемых сетях.

Благодаря динамическому отображению реальной сети в среду графического эмулятора остается возможным проводить тестирование узлов, при этом не опасаясь причинения ущерба производительности сетевой инфраструктуры. Тестирование может быть произведено при помощи генератора трафика, а сбор и анализ информации легко реализуется благодаря протоколу NetFlow. Кроме небольшой предварительной настройки, которая уже произведена на большинстве устройств, работающих в сети, ничего не требуется, коллектор и анализатор трафика устанавливается на тот же ПК, который используется для сбора информации.Также из-за гибкости программы не представляет особых усилий добавление нового устройства, поддерживающего взаимодействие с протоколом CDP.

К сожалению, достичь полной автоматизации настроек в настоящий момент не позволяет отсутствие модуля редактора стартовой конфигурации на языке perl.

В будущем предстоит автоматизировать генерацию и анализ трафика на основании входящих данных соседнего блока системы управления.Генерация может быть автоматизирована с помощью модуля python-ostinato.

Хотя данная программа и создавалась как часть системы управления гетерогенными IP сетями, она может найти обособленное применение в Ciscoсетях, со средним количеством узлов, экономя время администратору.

Список сокращений

VIRL - Virtual Internet Routing Lab

UNL - UNetLab / UnifiedNetworkingLab

GNS - Graphical Network Simulator

SNMP - Simple Network Management Protocol

QEMU - quick emulator

IOU - Internet working OSonUnix

L2, L3 - уровни модели OSI, канальный и сетевой соответственно

UDP - user data gramprotocol, транспортный протокол без гарантированной доставки

TCP - transmission control protocol транспортный протокол с гарантированной доставкой.

TOS - type of service число, указывающее устройствам как относится к данному IPпакету

LLDP - link layer discovery protocol протокол нахождения соседних устройств по канальному уровню

CDP -CiscoLLDP

Список используемой литературы

Горячев А. М. Тестирование и применение эмуляторов Cisco для моделирования гетерогенной IPсети / А.М. Горячев // Гагаринские чтения - 2016: XLII Международная молодежная научная коференция: Сборник тезисов докладов Т.ё. Московский авиационный институт (национальный исследовательский университет). - 2016. - стр.277-278

AndreDainese, UNetLab: Список поддерживаемых образов [Электронный ресурс] Режим доступа: http://www.unetlab.com/documentation/supported-images/index.html

Razvan Beuran, Intorduction to network emulation - Taylor & Francis Group, 2012. -389стр.

Introduction to Cisco IOS Netflow - A Technical Overview -2012 [Электронныйресурс] Режимдоступа: http://www.cisco.com/c/en/us/products/collateral/ios-nx-os-software/ios-netflow/prod_white_paper0900aecd80406232.html

CiscoIOSFlexibleNetFlow [Электронныйресурс] Режим доступа: http://www.cisco.com/c/en/us/td/docs/ios-xml/ios/fnetflow/configuration/15-mt/fnf-15-mt-book/fnf-fnetflow.html

InstallingNet-SnmponUbuntu - Пособие по установке [Электронный ресурс] http://net-snmp.sourceforge.net/wiki/index.php/Net-Snmp_on_Ubuntu

Stephen G. Kobourov Force-Directed Drawing Algorithms // Handbook of Graph Drawing and Visualization, - CRC Press- 2013. 383-408стр.

Ostinato dron image - [Электронныйресурс]http://www.bernhard-ehlers.de/projects/ostinato4gns3/index.html

Приложение

use SNMP;

use SNMP::Info;

use Cwd;

use File::Copy;

use Text::Tabs; #expand

use File::Path;

$tabstop = 3;

my $default_ip = "192.168.1.147";

print "Enter path to configs (default - cwd): ";

$dapth = <STDIN>;

if (not -d $dpath) {

$dpath = getcwd;

}

print "Path: $dpath\n";

while(1){

print "Enter <IP> to which pc would be connected (default - $default_ip): ";

my $conn_point = <STDIN>;

my @octets = split /\./, $conn_point;

if (@octets[3] eq "") {

$conn_point = $default_ip;

last;

}

if (@octets[0] le 255 and @octets[1] le 255 and

@octets[2] le 255 and @octets[3] le 255 and @octets[3] ne "")

{last;}

print "@octets";

}

$uuid = genuuid();

opendir my $dir, $dpath or die "Can't open directory: $!";

@files = grep(!m/^\./ && -f, readdir $dir);

open my $createfileh, '>', '/opt/unetlab/labs/lab_'.substr($uuid, 0, 8).'.unl' or die $!;

close $createfileh;

open $fh, '+<', '/opt/unetlab/labs/lab_'.substr($uuid, 0, 8).'.unl' or die $!;

#Create lab dir

if (not -d "/opt/unetlab/tmp/0/$uuid"){

mkdir "/opt/unetlab/tmp/0/$uuid";

chmod 0775, "/opt/unetlab/tmp/0/$uuid";

print $fh "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";

print $fh "<lab name=\"lab_".substr($uuid, 0, 8)."\" id=\"$uuid\" version=\"1\">\n";

print $fh expand "\t<topology>\n\t\t<nodes>\n\t\t</nodes>\n\t\t<networks>\n\t\t</networks>\n\t</topology>\n";

print $fh "</lab>";

print "Created lab dir\n";

}

$community_group = 'public';

$node_id = 1;

$network_id = 1;

$nvram_am = 1024;

$pos_left = 100;

$pos_top = 100;

my $err = examine_node($default_ip);

adjust_portgroups();

close $fh;

closedir $dir;

if ($err ne 0){

unlink ( '/opt/unetlab/labs/lab_'.substr($uuid, 0, 8).'.unl' );

rmtree "/opt/unetlab/tmp/0/$uuid";

}

if ($err eq 0){

print "\nLab $uuid was successfully created!\n";

}

#---------------------------------------------------------------------

sub examine_node { #ip_addr

my $info = new SNMP::Info(

AutoSpecify => 1,

Debug => 0,

DestHost => $_[0],

Community => $community_group,

Version => 2

) or return 2;

print "\n";

my $class = $info->class();

my $hostname = $info->name();

my $osilayers = $info->layers();

print "Connected to $hostname : $osilayers\n";

#Get neighbors info

my $c_id = $info->c_id();

my $c_ip = $info->c_ip();

my $c_if = $info->c_if();

my $c_port = $info->c_port();

#Remove config from file list

my $fileidx = 0;

while (@files[$fileidx] ne "$hostname"){

$fileidx++;

if ($fileidx > scalar @files) {

print "No config, maybe you entered wrong ip?\n";

return -1;

}

}

splice @files, $fileidx, 1;

#Create node dir, move cfg, link iourc

mkdir "/opt/unetlab/tmp/0/$uuid/$node_id";

chmod 0775, "/opt/unetlab/tmp/0/$uuid/$node_id";

symlink "/opt/unetlab/addons/iol/bin/iourc", "/opt/unetlab/tmp/0/$uuid/$node_id/iourc";

my $nvnum = 0;

if ($node_id < 10){

$nvnum = "0000".$node_id;

}

elsif ($node_id >= 10 and $node_id < 100){

$nvnum = "000".$node_id;

}

move "$dpath/$hostname", "/opt/unetlab/tmp/0/$uuid/$node_id/nvram_".$nvnum;

#Write current node to .unl

my $devicon = 'Router.png';

if (substr($osilayers, 4, 3) eq '011'){

$devicon = 'Switch L3.png';

}elsif (substr($osilayers, 4, 3) eq '001'){

$devicon = 'Switch.png';

}

my $osimage = "";

if ($devicon eq 'Switch.png' or $devicon eq 'Switch L3.png'){

$osimage = 'i86bi-linux-l2-ipbasek9-15.1a.bin';

}elsif ($devicon eq 'Router.png'){

$osimage = 'i86bi-linux-l3-adventerprisek3-15.4.1T.bin';

}

my $node_str = "\t\t\t<node id=\"$node_id\" name=\"$hostname\" type=\"iol\" template=\"iol\" image=\"$osimage\" ethernet=\"1\" nvram=\"$nvram_am\" ram=\"256\" serial=\"1\" delay=\"0\" icon=\"$devicon\" config=\"0\" left=\"$pos_left\" top =\"$pos_top\">\n\t\t\t</node>\n";

ins_str_before("</nodes>", $node_str);

#Go through interaces, create networks, add interfaces

my $ifaces = $info->interfaces();

my %rev_ifmap = reverse %$c_if;

foreach my $ifid (keys %$ifaces){

my $iface = $rev_ifmap{$ifid};

unless (defined $iface){

next;

}

#Get neighbor info on other side of current if

my $port = $ifaces->{$ifid};

my $neighbor_ip = $c_ip->{$iface};

my $neighbor_port = $c_port->{$iface};

my $neigh_hostname = $c_id->{$iface};

print "$port: connected to $neighbor_ip / $neighbor_port / $neigh_id\n" ;

#do i need to work with remote device? (does config exist?)

my $friend = 0;

foreach my $tmpconf (@files){

if ($neigh_hostname eq $tmpconf) {

$friend = 1;

last;

}

}

my $if_type = getporttype($port);

my $if_name = getportname($port);

my $if_idstr = getportid($port);

my $if_net_id = getfreenetid($hostname, $neigh_hostname);

if ($if_type eq 'ethernet') { #networks exist only with ethernet

my $net_name = "$hostname-$neigh_hostname";

# print "Net id betwen $net_name is $if_net_id\n";

if ($friend eq 1){

#if no free networks -> add

if ($if_net_id eq 0) {

my $comp_net_count = getnetamount($hostname, $neigh_hostname);

if ($comp_net_count ne 0) {

$net_name = $net_name.'_'.($comp_net_count + 1);

}

$net_str = "\t\t\t<network id=\"$network_id\" type=\"bridge\" name=\"$net_name\" left=\"$pos_left\" top=\"$pos_top\"/>\n";

ins_str_before("</networks>", $net_str);

print "Created net: $network_id between $net_name\n";

$if_net_id = $network_id;

$network_id++;

}

}

#if exists free network (it will because we either created it or it already did) -> add ether if

if ($if_net_id ne 0) {

my $if_str = "\t\t\t\t<interface id=\"$if_idstr\" name=\"$if_name\" type=\"$if_type\" network_id=\"$if_net_id\"/>\n";

ins_str_after("<node .* name=\"$hostname\"", $if_str);

print "Added $if_name for $hostname\n";

}

}

#if == serial and rem node already created -> add serial

my $rem_node_id = getnodeid($neigh_hostname);

if ($rem_node_id ne 0 and $if_type eq 'serial') {

print "Got match for $neigh_hostname on $hostname : $port\n";

my $rem_if_idstr = getportid($neighbor_port);

my $rem_if_type = getporttype($neighbor_port);

my $rem_if_name = getportname($neighbor_port);

#serial for me

my $if_string = "\t\t\t\t<interface id=\"$if_idstr\" type=\"$if_type\" name=\"$if_name\" remote_id=\"$rem_node_id\" remote_if=\"$rem_if_idstr\"/>\n";

ins_str_after("<node .* name=\"$hostname\"", $if_string);

print "Added $if_name for $hostname\n";

#serial for neighbor

my $remote_if_str = "\t\t\t\t<interface id=\"$rem_if_idstr\" type=\"$rem_if_type\" name=\"$rem_if_name\" remote_id=\"$node_id\" remote_if=\"$if_idstr\"/>\n";

ins_str_after("<node .* name=\"$neigh_hostname\"", $remote_if_str);

print "Added $rem_if_name for $neigh_hostname\n";

}

}

#Go through interfaces, move to next node

foreach my $ifid (keys %$ifaces){

my $iface = $rev_ifmap{$ifid};

unless (defined $iface) {

next;

}

my $neighbor_ip = $c_ip->{$iface};

my $neigh_hostname = $c_id->{$iface};

foreach my $tmpconf (@files){

if ($neigh_hostname eq $tmpconf){

#prepare to change node

if ($pos_left < 994){

$pos_left += 200;

}else{

$pos_top += 200;

$pos_left = 100;

}

$node_id++;

print "Connecting to $neigh_hostname : $neighbor_ip\n";

examine_node($neighbor_ip);

last;

}

}

}

return 0;

}

#---------------------------------------------------------------------

sub adjust_portgroups {

my $node_str_idx = 0;

my $serial_groups = 1;

my $ether_groups = 1;

seek $fh, 0, SEEK_SET;

my @lines = <$fh>;

my $idx = 0;

do {

if (@lines[$idx] =~ /<node/){

$node_str_idx = $idx;

}

if (@lines[$idx] =~ /<interface .* type="ethernet/){

my @words = split /name="e/, @lines[$idx];

my @pg = split /\//, @words[1];

if ($ether_groups < (@pg[0] + 1)){

$ether_groups = @pg[0] + 1;

}

}

if (@lines[$idx] =~ /<interface .* type="serial/){

my @words = split /name="s/, @lines[$idx];

my @pg = split /\//, @words[1];

if ($serial_groups < (@pg[0])){

$serial_groups = @pg[0];

}

}

if (@lines[$idx] =~ /<\/node>/){

my $ser_pos = index @lines[$node_str_idx], "serial=";

substr @lines[$node_str_idx], $ser_pos + length "serial=\"", 1, $serial_groups;

my $ether_pos = index @lines[$node_str_idx], "ethernet=";

substr @lines[$node_str_idx], $ether_pos + length "ethernet=\"", 1, $ether_groups;

$node_str_idx = 0;

$ether_groups = 1;

$serial_groups = 1;

}

$idx++;

}until($idx >= @lines);

seek $fh, 0, SEEK_SET;

print $fh expand @lines;

}

#---------------------------------------------------------------------

sub getfreenetid { #myhostname1 hostname2

my $hn1 = $_[0];

my $hn2 = $_[1];

my $pos;

seek $fh, 0, SEEK_SET;

while (my $line = <$fh>) {

if ($line =~ /<network .* name="$hn1-$hn2/ or $line =~ /<network .* name="$hn2-$hn1/) {

my @words = split /network id="/, $line;

my @res = split /\"/, @words[1];

$pos = tell($fh);

my $idfree = isnetfree($hn1, @res[0]);

seek $fh, $pos, SEEK_SET;

if ($idfree eq 1){

return @res[0];

}

}

}

return 0;

}

#---------------------------------------------------------------------

sub isnetfree { #hostname netid

my $hn = $_[0];

my $net_id = $_[1];

my $inmynode = 0;

seek $fh, 0, SEEK_SET;

while (my $line = <$fh>) {

if ($inmynode eq 1 and $line =~ /<interface .* network_id="$net_id"/) {

return 0;

}

if ($line =~ /<node .* name="$hn"/){

$inmynode = 1;

}

if ($line =~ /<\/node>/ & $inmynode eq 1) {

$inmynode = 0;

last;

}

}

return 1;

}

#---------------------------------------------------------------------

sub getnetamount { #hostname1 hostname2

my $hn1 = $_[0];

my $hn2 = $_[1];

my $count = 0;

seek $fh, 0, SEEK_SET;

while (my $line = <$fh>) {

if ($line =~ /<network .* name="$hn1-$hn2/ or $line =~ /<network .* name="$hn2-$hn1/ ) {

$count++;

}

}

return $count;

}

#---------------------------------------------------------------------

sub ins_str_before { #pattern, string to insert

my $pattern = $_[0];

my $string = $_[1];

seek $fh, 0, SEEK_SET;

my @lines = <$fh>;

my $idx = 0;

do{

if (@lines[$idx] =~ m/$pattern/){

splice @lines, $idx, 0, $string;

$idx++;

}

$idx++;

}until($idx >= @lines);

seek $fh, 0, SEEK_SET;

print $fh expand @lines;

}

#---------------------------------------------------------------------

sub ins_str_after { #pattern, string to insert


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.