- •Пояснительная записка к лабораторной работе
- •Постановка задачи
- •Структура решения
- •Теория Типы адресов: физический (mac-адрес), сетевой (ip-адрес) и символьный (dns-имя)
- •Бесклассовая адресация (cidr)
- •Сетевые протоколы
- •Служба dns
- •Межсетевой экран
- •Обзор и анализ методов решения
- •Работа с параметрами стека tcp/ip
- •Настройка параметров tcp/ip
- •Просмотр параметров tcp/ip
- •Построение структуры кафедральной, факультетской и университетской сетей
- •Сбор первичной информации о сети
- •Анализ информации о сети
- •Построение структуры сети
- •Работа с межсетевым экраном
- •Обзор межсетевых экранов
- •Описание реализации применяемых методов
- •Описание tcp/ip параметров настройки компьютера
- •Построение структуры кафедральной, факультетской и университетской сетей
- •Сбор информации о сети с помощью специально написанного приложения
- •Руководство программиста
- •Руководство пользователя
- •Построение карты сети
- •Работа с межсетевым экраном
- •Установка
- •Настройка
- •Создание правил
Описание реализации применяемых методов
Описание tcp/ip параметров настройки компьютера
Результат выполнения команды ipconfig /all на собственном компьютере:
Собственный IP- адрес узла: 192.168.0.102
Маска подсети: 255.255.255.0
IP-адрес шлюза: 192.168.0.1
IP-адрес основного DNS-сервера: 192.168.0.1
IP-адрес вторичного DNS-сервера: 192.168.0.1
Построение структуры кафедральной, факультетской и университетской сетей
Сбор информации о сети с помощью специально написанного приложения
Ранее было принято решение, что приложение будет написано на языке C# 6.0 с использованием стандартных библиотек и фреймворка .NET 4.6.2.
Структуры данных и переменные
NumericUpDown nud1, nud2, nud3, nud4 – компоненты для ввода начального адреса
NumericUpDown nud5, nud6, nud7, nud8 – компоненты для ввода конечного адреса
byte[] begin_bytes, end_bytes – начальный и конечный адрес в виде массива из 4-х байт
uint begin, end – начальный и конечный адрес в виде 32-разрядного целого числа без знака
int N – количество адресов в диапазоне
uint ip_range[N] – список адресов из диапазона
string ping[N] – список со значениями состояния сети
string dns[N] – список с доменными именами
uint address – адрес сети
uint gateway – адрес шлюза
uint mask – маска сети
uint broadcast – широковещательный адрес
Ввод диапазона адресов
Ввод границ рассматриваемого диапазона осуществляется через компоненты выбора numericUpDown (текстовое поле с кнопками для увеличения и уменьшения значения). У компонент такого типа есть значения Maximum - максимальное значение. В рамках данной задачи оно равно 255, Minimum - минимальное значение. Минимальное значение равно 0 и Value - возвращает текущее значение в виде строки.
Для начального и конечного IP-адреса необходимо по 4 компонента numericUpDown, т.е. всего 8 компонент. Мы считываем IP-адрес в виде 4х октетов. Эти 4 октета можно представить в виде 32-разрядного целого числа без знака. По следующему принципу:
77.88.21.8 = 77 * 2563 + 88 * 2562 + 21 * 2561 + 8 * 256О = 1297618184
Такое представление IP-адреса будет очень удобным в нашей задаче, т.к. чтобы получить следующий IP-адрес из диапазона, нужно будет увеличить текущий на единицу.
В языке C# такое представление IP-адреса можно получить, используя метод ToUInt32 класса BitConverter:
BitConverter. Преобразует базовые типы данных в массив байтов, а массив байтов — в базовые типы данных. |
|
ToUInt32(Byte[], Int32) |
Возвращает 32-разрядное целое число без знака, преобразованное из четырех байтов с указанной позицией в массив байтов. |
Укрупненный алгоритм ввода диапазона адресов
Считать значения начального и конечного адреса с компонент выбора numericUpDown (свойство Value) в массивы begin и end.
Представить считанные адреса в виде целого числа (метод BitConverter.ToUInt32).
Получить диапазон адресов (цикл for начиная с начального адреса и заканчивая конечным).
Детализированный алгоритм ввода диапазона адресов
С каждой компоненты выбора numericUpDown для начального адреса считать значения в массив байтов begin_bytes:
begin_bytes [0] = (byte)nud1.Value;
begin_bytes [1] = (byte)nud2.Value;
begin_bytes [2] = (byte)nud3.Value;
begin_bytes [3] = (byte)nud4.Value;
С каждой компоненты выбора numericUpDown для конечного адреса считать массив байтов end_bytes:
end_bytes [0] = (byte)nud5.Value;
end_bytes [1] = (byte)nud6.Value;
end_bytes [2] = (byte)nud7.Value;
end_bytes [3] = (byte)nud8.Value;
Получить представления IP-адресов в виде целых чисел:
begin = Bit.Converter(begin_bytes, 0);
end = Bit.Converter(end_bytes, 0);
Диапазон адресов получить, используя цикл for:
for(uint ip=begin; ip < end; ip++)
ip_range.Add(ip);
Сбор информации о сети
Для получения статуса доступности узла, в обзоре и анализе методов решения, было решено использовать для этого асинхронный подход. Стандартный класс Ping как раз предоставляет такую возможность через асинхронный метод SendAsync.
Вызов SendAsync выполняется в отдельном потоке, который автоматически выделяется из пула потоков. При завершении асинхронной операции, он вызывает PingCompleted событие. Поэтому необходимо добавить PingCompletedEventHandler делегат для события PingCompleted, непосредственно перед вызовом метода SendAsync. Метод делегата получает объект класса PingCompletedEventArg, содержащий объект класса PingReply, который как раз описывает результат SendAsync вызова в поле Status.
Для определения DNS имени было принято решение использовать обычную многопоточность через класс Thread. Для получения символьного имени можно использовать метод GetHostEntry стандартного класса Dns. Для каждого IP-адреса из диапазона будем вызывать метод GetHostEntry в отдельном потоке.
Опишем все используемые классы, методы и т.п. технологии .NET 4.6.2, в таблице:
Ping – класс, который позволяет приложению определить, доступен ли удаленный компьютер по сети. Для отправки запроса используются методы Send и SendAsync. |
|
PingReply Ping.SendHYPERLINK "http://msdn.microsoft.com/ru-ru/library/yf697k33.aspx"(HYPERLINK "http://msdn.microsoft.com/ru-ru/library/yf697k33.aspx"IPAddress HYPERLINK "http://msdn.microsoft.com/ru-ru/library/yf697k33.aspx", int время ожидания) PingReply Ping.SendHYPERLINK "http://msdn.microsoft.com/ru-ru/library/yf697k33.aspx"(HYPERLINK http://msdn.microsoft.com/ru-ru/library/yf697k33.aspxstring адресИлиХостHYPERLINK "http://msdn.microsoft.com/ru-ru/library/yf697k33.aspx", int время ожидания)
IPAddress адрес – адрес узла, на который отправляется сообщение string адрес – адрес узла (в виде строки), на который отправляется сообщение, либо доменное имя узла. int время ожидания - указывает максимальное время (после отправки сообщения проверки связи) ожидания сообщения ответа проверки связи ICMP в миллисекундах. Если не указан непосредственно, то по умолчанию равен 5 секундам. |
Предпринимает попытку отправки сообщения запроса проверки связи ICMP с заданным буфером данных на удаленный компьютер с указанным IP-адресом и получения от него соответствующего сообщения ответа проверки связи ICMP. Этот метод позволяет указать тайм-аут операции. |
PingReply Ping.SendAsync(IPAddress адрес, object userToken, int время ожидания) PingReply Ping.SendAsync(string адресИлиХост, object userToken, int время ожидания)
IPAddress адрес, string адресИлиХост, int время ожидания – см. Send. object userToken – Объект, передаваемый в метод, который вызывается после завершении асинхронной операции. |
Предпринимает попытку асинхронной отправки сообщения запроса проверки связи ICMP на удаленный компьютер с указанным IP-адресом и получения от него соответствующего сообщения ответа проверки связи ICMP. Этот метод позволяет указать тайм-аут операции. По завершению запроса происходит событие PingComplited, которое вызывает делегат PingCompletedEventHandler. |
Ping.PingCompleted – событие. Происходит при завершении или отмене асинхронной операции отправки сообщения проверки связи ICMP и получения соответствующего сообщения ответа проверки связи ICMP. |
|
Делегат PingCompletedEventHandler(object sender, PingCompletedEventArgs e) sender - источник события PingCompleted. e - объект, содержащий данные события. |
Предоставляет метод обратного вызова, вызываемый при создании методом SendAsync события PingCompleted. |
PingCompletedEventArgs – класс. Предоставляет данные для события PingCompleted. Имеет параметры: PingReply Reply, object UserState. |
|
PingReply PingCompletedEventArgs.Reply |
Возвращает объект, который содержит данные, описывающие попытку отправки сообщения запроса проверки связи ICMP и получения соответствующего сообщения ответа проверки связи ICMP. |
object PingCompletedEventArgs.UserState |
Возвращает объект, переданный для асинхронной задачи |
IPAddress – предоставляет IP-адрес. |
|
PingReply – класс, который предоставляет сведения о состоянии и о данных, полученных в результате операций Ping.Send и Ping.SendAsync. Имеет параметры: IPStatus Status, IPAddress Address |
|
IPStatus PingReply.Status |
Значение IPStatus, показывающее результат запроса. |
IPAddress PingReply.Address |
Возвращает адрес узла |
IPStatus – перечисление. Сообщает о состоянии отправки сообщения проверки связи ICMP на компьютер. |
|
Dns – статический класс, который предоставляет простые функциональные возможности разрешения доменных имен. Для этого используются методы GetHostEntry, BeginGetHostEntry, EndGetHostEntry. |
|
IPHostEntry Dns.GetHostEntry(IPAddress адрес) IPHostEntry Dns.GetHostEntry(string адрес)
IPAddress адрес – адрес узла, на который отправляется сообщение string адрес – адрес узла (в виде строки), на который отправляется сообщение |
Разрешает имя узла или IP-адрес в экземпляр IPHostEntry. |
IPHostEntry – класс, который предоставляет контейнер для сведений об адресе веб-узла. |
|
string IPHostEntry.HostName |
Строка, содержащая главное имя узла сервера. |
Thread – класс создает и контролирует поток, задает приоритет и возвращает статус. |
|
bool Thread.IsBackground |
Возвращает или задает значение, показывающее, является ли поток фоновым. Когда все основные потоки, принадлежащие процессу, завершились, общеязыковая среда выполнения завершает процесс. Все оставшиеся фоновые потоки останавливаются, не закончив работу. |
ThreadState Thread.ThreadState |
Одно из значений ThreadState, показывающее состояние текущего потока. Начальное значение — Unstarted. |
Thread(ThreadStart start)
ThreadStart start - делегат, указывающий на методы, которые вызываются при запуске потока. |
Конструктор. Инициализирует новый экземпляр класса Thread. |
void Thread.Start(object parameter)
object parameter - объект, содержащий данные, используемые методом, который выполняется потоком. |
Заставляет операционную систему изменить состояние текущего экземпляра на ThreadState.Running, а также (необязательно) передает объект с данными, используемыми методом в потоке. |
ThreadState – Перечисление. Задает состояния выполнения объекта Thread. |
|
Background |
Поток выполняется как фоновый поток, в противоположность потокам переднего плана. |
Running |
Поток был запущен, он не заблокирован, и нет ожидающего исключения ThreadAbortException. |
Stopped |
Поток был остановлен. |
Unstarted |
Метод Thread.Start не был вызван для потока. |
Укрупненный алгоритм сбора информации о сети
Для каждого i-го адреса из диапазона адресов ip_range (цикл по всем адресам):
for (int i = 0; i < N; i++)
Запросить статус работоспобности узла:
Создать объект класса Ping.
Ping pingSender = new Ping();
Прикрепить Callback метод - PingCompletedCallback к объекту Ping
pingSender.PingCompleted += PingCompletedCallback;
Отправить асинхронный запрос работоспобности узла, указав в качестве параметров:
- ip_range[i] – текущий IP-адрес
- i – индекс текущего IP-адреса
pingSender.SendAsync(ip_range[i], i);
В Callback методе PingCompletedCallback(object sender, PingCompletedEventArgs e)
Извлечь информацию – узнать индекс адреса, для которого пришел ответ и соответствующий статус
int index = (int) ((object)e.UserState);
string status = e.UserState.Status;
Сохранить статус работоспобности в список по найденному индексу
ping[index] = status;
Для каждого i-го адреса из диапазона адресов ip_range (цикл по всем адресам):
for (int i = 0; i < N; i++)
Определить доменное имя узла:
Создать новый поток Thread, указав в качестве параметра делегат getName, у которого в свою очередь параметры:
-ip_range[i] – текущий IP-адрес
-i – индекс текущего IP-адреса
и затем запустить его, вызвав метод Start:
new Thread( () => GetName(ip_range[i], i) ).Start();
В методе делегате GetName(uint ip, int index)
Выполнить запрос на разрешение IP-адреса в доменное
IPHostEntry host = Dns.GetHostEntry(ip);
Попытаться сохранить информацию в список Dns имен по соответствующему индексу
dns[index] = host.HostName;
в случае ошибки присвоить название “Хост неизвестен”
dns[index] = “Хост неизвестен”;
Укрупненный алгоритм анализа полученной информации
Для начала введем функции:
uint GetMask(uint low, uint high) - получение маски сети,
-low – начальный адрес сети
-high – конечный адрес сети
uint GetAddress(uint ip, uint mask) - получение адреса сети,
uint GetBroadcast(uint ip, uint mask) - получение широковещательного адреса сети,
-ip - начальный адрес сети
-mask – маска сети
uint GetGateway(uint address) – получение шлюза сети,
-address – адрес сети.
Функция GetMask(uint low, uint high):
Обнулить маску
mask = 0;
Для каждого i-го бита от 31-го по 0-й
for (int i=31; i>= 0; --i)
Сравнить i-е биты low и high
if (((high >> i) & 1) == ((low >> i) & 1))
Если совпадают, увеличить маску на 2i
mask = mask + pow(2,i);
Иначе, выход из цикла
else break;
Вернуть маску
return mask;
Функция GetAddress(uint ip, uint mask):
Применить поразрядную конъюнкцию к ip и mask
address = ip & mask;
Вернуть результат
return address;
Функция GetBroadcast(uint ip, uint mask):
Применить поразрядную дизъюнкцию к ip и результату применения отрицания к mask
broadcast = ip | ~mask;
Вернуть результат
return broadcast;
Функция GetGateway(uint address):
Прибавить единицу к адресу сети
gateway = address + 1;
Вернуть результат
return gateway;
Детализированный алгоритм анализа полученной информации
Найти маску сети: mask = GetMask(begin, end)
Найти адрес сети: address = GetNetAddress(begin mask)
Найти шлюз сети: gateway = GetGateway(address)
Найти широковещательный адрес: broadcast = GetBroadcast(begin, mask)
