Дипломная работа: Создание сетевой программы DHCP server

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

DHCPRELEASE -- Такое широковещательное сообщение отправляется клиентом если он прекращает использования сетевого адреса.

DHCPNAK -- Этот ответ будет отправлен клиенту в случае, если невозможно удовлетворить параметры DHCPREQUEST.

DHCPDECLINE -- Широковещательный ответ серверу в том случае, когда клиент обнаруживает, что присвоенный ему IP-адрес уже используется.

DHCPINFORM -- Сообщение серверу в том случае, если у клиента DHCP прописан статический IP-адрес и он не нуждается в динамическом распределении.

Сообщения протокола DCHP имеют следующие поля:

Поле

Длина (байты)

Описание

op

1

Тип сообщения

htype

1

Тип адреса аппаратной части

hlen

1

Длина адреса аппаратной части

hops

1

Используемое количество агентов ретрансляции. Клиенты устанавливают значение на 0.

xid

4

ID (уникальный идентификационный номер) транзакции используемой клиентом и серверов во время сессии

secs

2

Прошедшее время (в секундах) с момента запроса клиентом начала процесса

flags

2

Значение флагов

ciaddr

4

IP-адрес клиента (если имелся ранее).

yiaddr

4

IP-адрес, предложенный сервером клиенту

siaddr

4

IP-адрес сервера

giaddr

4

IP-адрес relay-агента (агента ретрансляции)

chaddr

16

Адрес аппаратной части клиента (в основном MAC).

sname

64

Имя сервера.

file

128

Название загрузочного файла.

options

изменяемая

Дополнительные опции

Как включить DHCP на сетевом адаптере

В операционной системе Windows 10 DHCP-клиент включен по умолчанию как служба, а на сетевом адаптере необходимо выставить автоматическое получение IP. Для этого нажимаем комбинацию клавиш Win+R чтобы открыть окно «Выполнить» и вводим команду ncpa.cpl.

Нажимаем на кнопку «ОК». Появится окно с сетевыми подключениями Виндовс 10.

На том адаптере, где хотим включить DHCP, кликаем правой кнопкой чтобы появилось контекстное меню. В меню -- выбираем пункт «Свойства».

В следующем окне надо выбрать строчку «IP версии 4(TCP/IPv4)» и нажимаем на кнопку «Свойства» чтобы открыть параметры протокола:

Здесь необходимо поставить галочки на автоматическое получение адресов и нажать на кнопку «ОК».

В операционных системах семейства Linux все настройки прописаны в конфигурационных файлах. Например, в популярной Ubuntu это /etc/network/interfaces. Вот пример конфига, который позволяет включить DHCP на сетевом адаптере eth0:

Здесь:

auto eth0 -- автоматическое включение сетевой карты eth0 при загрузке системы.

iface eth0 inet static -- этой строчкой мы указываем системе, что интерфейс сетевой карты eth0 находится в диапазоне адресов с динамическим получением ip.

Если в системе работает менеджер соединение Network Manager, то можно включить DHCP на сетевом адаптере и в графическом интерфейсе:

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

DHCP назначит новые IP-адреса в каждом местоположении, когда устройства будут перемещены с места на место, что означает, что сетевым администраторам не нужно вручную сначала настраивать каждое устройство с допустимым IP-адресом или перенастраивать устройство с новым IP-адресом, если он перемещается на новое место в сети. Версии DHCP доступны для использования в интернет-протоколе версии 4 (IPv4) и в Internet Protocol версии 6 (IPv6).

Как работает DHCP

DHCP работает на прикладном уровне стека протокола протокола управления передачей / протокола IP (TCP / IP) для динамического назначения IP-адресов DHCP-клиентам и для распределения данных конфигурации TCP / IP клиентам DHCP. Сюда входит информация о маске подсети, IP-адреса шлюза по умолчанию и адреса системы доменных имен (DNS).

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

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

DHCP-сервер управляет записью всех IP-адресов, которые он назначает сетевым узлам. Если узел перемещается в сети, сервер идентифицирует его, используя его адрес управления доступом к среде передачи (MAC), что предотвращает случайную настройку нескольких устройств с одним и тем же IP-адресом.

DHCP не является маршрутизируемым протоколом и не является безопасным. DHCP ограничен конкретной локальной сетью (LAN), что означает, что один DHCP-сервер для каждой локальной сети является достаточным или два сервера для использования в случае отказа. Более крупные сети могут иметь глобальную сеть (WAN), содержащую несколько отдельных мест. В зависимости от соединений между этими точками и количеством клиентов в каждом месте можно настроить несколько DHCP-серверов для обработки адресов. Если сетевые администраторы хотят, чтобы DHCP-сервер предоставлял адресацию нескольким подсетям в данной сети, они должны настроить службы ретрансляции DHCP, расположенные на соединительных маршрутизаторах, что запросы DHCP должны пересекаться. Эти агенты ретранслируют сообщения между клиентами DHCP и серверами, расположенными в разных подсетях.

DHCP не имеет встроенного механизма, позволяющего клиентам и серверам аутентифицировать друг друга. Оба уязвимы для обмана (один компьютер притворяется другим) и атаковать, когда клиенты-изгои могут исчерпать пул IP-адресов DHCP-сервера.

Статические и динамические аренды DHCP

При динамическом DHCP клиент не имеет назначенного ему IP-адреса, а вместо этого «арендует» его в течение определенного периода времени. При каждом включении устройства с динамическим IP-адресом он должен связываться с сервером DHCP для аренды другого IP-адреса. Беспроводные устройства - это примеры клиентов, которым назначены динамические IP-адреса при их подключении к сети.

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

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

Типичный динамический цикл аренды DHCP выглядит следующим образом:

Клиент получает аренду IP-адреса через процесс распределения запроса с сервера DHCP.

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

Как только аренда активна, клиент, как говорят, связан с арендой и адресом.

По истечении срока аренды клиент свяжется с сервером, который изначально предоставил наименьшее количество обновлений, чтобы он мог продолжать использовать свой IP-адрес.

Если клиент перемещается в другую сеть, его динамический IP-адрес будет прекращен и он запросит новый IP-адрес с DHCP-сервера новой сети.

package net.floodlightcontroller.dhcpserver;

import net.floodlightcontroller.core.*;

import net.floodlightcontroller.core.internal.IOFSwitchService;

import net.floodlightcontroller.core.module.FloodlightModuleContext;

import net.floodlightcontroller.core.module.FloodlightModuleException;

import net.floodlightcontroller.core.module.IFloodlightModule;

import net.floodlightcontroller.core.module.IFloodlightService;

import net.floodlightcontroller.core.types.NodePortTuple;

import net.floodlightcontroller.dhcpserver.web.DHCPServerWebRoutable;

import net.floodlightcontroller.packet.DHCP;

import net.floodlightcontroller.packet.Ethernet;

import net.floodlightcontroller.packet.IPv4;

import net.floodlightcontroller.restserver.IRestApiService;

import net.floodlightcontroller.staticentry.IStaticEntryPusherService;

import net.floodlightcontroller.core.IOFSwitchListener;

import net.floodlightcontroller.topology.ITopologyService;

import net.floodlightcontroller.util.OFMessageUtils;

import org.projectfloodlight.openflow.protocol.*;

import org.projectfloodlight.openflow.types.*;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.util.*;

import java.util.concurrent.ScheduledThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

/**

* SDN DHCP Server

* @author Ryan Izard, rizard@g.clemson.edu, ryan.izard@bigswitch.com

* @edited Qing Wang, qw@g.clemson.edu on 1/3/2018

*

* This module implementing a DHCP DHCPServer. The module can be configured with the REST API.

*

*/

public class DHCPServer implements IOFMessageListener, IOFSwitchListener, IFloodlightModule, IDHCPService {

protected static final Logger log = LoggerFactory.getLogger(DHCPServer.class);

protected IFloodlightProviderService floodlightProviderService;

protected IOFSwitchService switchService;

protected IRestApiService restApiService;

protected ITopologyService topologyService;

protected IStaticEntryPusherService staticEntryPusherService;

private static Map<String, DHCPInstance> dhcpInstanceMap;

private static volatile boolean enableDHCPService = false;

private static volatile boolean enableDHCPDynamicService = false;

private static ScheduledThreadPoolExecutor leasePoliceDispatcher;

private static long DHCP_SERVER_CHECK_EXPIRED_LEASE_PERIOD_SECONDS = 10; // 10 secs as default

@Override

public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {

Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);

OFPort inPort = OFMessageUtils.getInPort((OFPacketIn) msg);

if (!isDHCPEnabled()) return Command.CONTINUE;

if (!DHCPServerUtils.isDHCPPacketIn(eth)) return Command.CONTINUE;

NodePortTuple npt = DHCPServerUtils.getNodePortTuple(sw, inPort);

VlanVid vid = DHCPServerUtils.getVlanVid((OFPacketIn) msg, eth);

if (!getInstance(npt).isPresent() && !getInstance(sw.getId()).isPresent() && !getInstance(vid).isPresent()) {

log.warn("Could not locate DHCP instance for DPID {}, port {} or VLAN {}", new Object[] {sw.getId(), inPort, vid});

return Command.CONTINUE;

}

DHCPInstance instance = null;

if (getInstance(sw.getId()).isPresent()) {

instance = getInstance(sw.getId()).get();

}

else if (getInstance(npt).isPresent()) {

instance = getInstance(npt).get();

}

else {

instance = getInstance(vid).get();

}

synchronized (instance.getDHCPPool()) {

if (!instance.getDHCPPool().isPoolAvailable()) {

log.info("DHCP Pool is full, trying to allocate more space");

return Command.CONTINUE;

}

}

DHCP dhcPayload = DHCPServerUtils.getDHCPayload(eth);

IPv4Address srcAddr = ((IPv4) eth.getPayload()).getSourceAddress();

IPv4Address dstAddr = ((IPv4) eth.getPayload()).getDestinationAddress();

MacAddress srcMac = eth.getSourceMACAddress();

switch (DHCPServerUtils.getOpcodeType(dhcPayload)) {

case REQUEST:

processDhcpRequest(dhcPayload, sw, inPort, instance, srcAddr, dstAddr, srcMac);

return Command.STOP;

default:

break;

}

return Command.CONTINUE;

}

private void processDhcpRequest(DHCP dhcpPayload, IOFSwitch sw, OFPort inPort, DHCPInstance instance,

IPv4Address srcAddr, IPv4Address dstAddr, MacAddress srcMac) {

DHCPMessageHandler handler = new DHCPMessageHandler();

switch (DHCPServerUtils.getMessageType(dhcpPayload)) {

case DISCOVER:

OFPacketOut dhcpOffer = handler.handleDHCPDiscover(sw, inPort, instance, srcAddr, dhcpPayload, enableDHCPDynamicService);

log.info("DHCP DISCOVER message received from switch {} for client interface {}, handled by dhcp instance {} ... ",

new Object[]{sw.getId().toString(), srcMac.toString(), instance.getName()});

sw.write(dhcpOffer);

break;

case REQUEST:

OFPacketOut dhcpReply = handler.handleDHCPRequest(sw, inPort, instance, dstAddr, dhcpPayload);

log.info("DHCP REQUEST message received from switch {} for client interface {}, handled by dhcp instance {} ... ",

new Object[]{sw.getId().toString(), srcMac.toString(), instance.getName()});

sw.write(dhcpReply); // either ACK or NAK

break;

case RELEASE: // clear client IP (e.g. client shut down, etc)

log.debug("DHCP RELEASE message received from switch {}, start handling... ", sw.getId().toString());

handler.handleDHCPRelease(instance, dhcpPayload.getClientHardwareAddress());

break;

case DECLINE: // client found assigned IP invalid

log.debug("DHCP DECLINE message received from switch {}, start handling... ", sw.getId().toString());

handler.handleDHCPDecline(instance, dhcpPayload.getClientHardwareAddress());

break;

case INFORM: // client request some information

log.debug("DHCP INFORM message received from switch {}, start handling... ", sw.getId().toString());

OFPacketOut dhcpAck = handler.handleDHCPInform(sw, inPort, instance, dstAddr, dhcpPayload);

sw.write(dhcpAck);

break;

default:

break;

}

}

@Override

public String getName() {

return "dhcpserver";

}

@Override

public boolean isCallbackOrderingPrereq(OFType type, String name) {

return false;

}

@Override

public boolean isCallbackOrderingPostreq(OFType type, String name) {

return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));

}

@Override

public Collection<Class<? extends IFloodlightService>> getModuleServices() {

Collection<Class<? extends IFloodlightService>> s =

new HashSet<Class<? extends IFloodlightService>>();

s.add(IDHCPService.class);

return s;

}

@Override

public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {

Map<Class<? extends IFloodlightService>, IFloodlightService> m =

new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();

m.put(IDHCPService.class, this);

return m;

}

@Override

public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {