Предназначен для выдачи IP-адресов по протоколу DHCP с опцией 82. Опцию в запрос должен подставить коммутатор, пропускающий запрос, далее запрос обязательно должен переслать DHCP-Relay. Идентификация сервисов осуществляется на основании полей и , но также могут быть настроены любые другие поля, определяющие порт коммутатора клиента.
Загружает список устройств-коммутаторов, начиная с корневого узла. Типы устройств-коммутаторов определяются в переменной конфигурации корневого узла через запятую. Также загружаются привязанные к коммутаторам сервисы договоров.
Когда приходит DHCP-запрос, из него извлекается поле . Осуществляется поиск устройства-релея сначала по совпадению этого поля с адресом устройства в биллинге. Затем, если поиск был отрицательным - осуществляется поиск по совпадению IP-адреса, с которого пришёл DHCP-запрос с IP-адресом устройства.
Если по каким-то причинам клиентские устройства (например, NetGear JWNR2000) в DHCP-REQUEST посылают xid, отличный от DHCP-DISCOVER, можно убрать привязку к xid-запросам, прописав в конфигурации устройства-коммутратора/типа устройства/конфигурации модуля:
# Привязка к xid DHCP-запросов # 0 - выкл., 1 (по умолчанию) - вкл. dhcp.xid=1
Далее алгоритм работы определяется переменными конфигурации найденного устройства-релея. Следующие параметры определяют, какие опции извлекаются для идентификации устройства-коммутатора клиента и непосредственно клиента по порту или VLAN.
# Удаление заголовка, при необходимости, 0 - не удалять, 2 - 2 удалить байта (тип+длина) из значения DHCP-опции. # При удалении поля position для agentRemoteId, vlanId, interfaceId нужно уменьшить на тоже кол-во байт #dhcp.option82.removeHeader=0 dhcp.option82.removeHeader=2 # Параметры для извлечения из пакета agentRemoteId # вид значения в опции agentRemoteId: 0 (по умолчанию) - байты, 1 - строка #dhcp.option82.agentRemoteId.type=0 # код субопции 82, содержащей идентификатор коммутатора клиента, позиция и длина последовательности идентификатора dhcp.option82.agentRemoteId.code=2 dhcp.option82.agentRemoteId.position=0 dhcp.option82.agentRemoteId.length=6 # код субопции 82, содержащей VLAN, позиция и длина в субопции dhcp.option82.vlanId.code=1 dhcp.option82.vlanId.position=0 dhcp.option82.vlanId.length=2 # код субопции 82, содержащей интерфейс, позиция и длина в субопции dhcp.option82.interfaceId.code=1 dhcp.option82.interfaceId.position=3 dhcp.option82.interfaceId.length=1
Параметры, описанные выше подойдут для обработки такого пакета:
Message type: BOOT_REQUEST
Dhcp message type: DHCP Discover{1}
htype: 1, hlen: 6, hops: 1
xid: 1067065417, secs: 0, flags: 0
Client IP: 0.0.0.0
Your IP: 0.0.0.0
Server IP: 0.0.0.0
Relay IP: 109.233.170.1
Client MAC: {00804840A46F}
Host name{12}={support-desktop}
Parameter request list{55}={1, 28, 2, 3, 15, 6, 119, 12, 44, 47, 26, 121, 42}
Agent information{82}=
sub{1}={000403420101}
sub{2}={00060012CF539F5E}В данном случае будет проигнорирован заголовок: sub{1}={03420101}, sub{2}={0012CF539F5E} и извлечены значения agentRemoteId=0012CF539F5E (MAC-адрес в виде набора байтов), VLAN=0x0342, interfaceId=0x01.
От некоторых коммутаторов значения могут приходить в строковом виде, например: sub{2}={3137322E31362E39392E33363A313031} (на самом деле, это обычная строка в шестнадцетиричном представлении), для обработки этой опции нужен такой конфиг:
# Удаление заголовка, при необходимости, 0 - не удалять, 2 - 2 удалить байта (тип+длина) из значения DHCP-опции. # При удалении поля position для agentRemoteId, vlanId, interfaceId нужно уменьшить на тоже кол-во байт dhcp.option82.removeHeader=0 # Параметры для извлечения из пакета agentRemoteId # вид значения в опции agentRemoteId: 0 (по умолчанию) - байты, 1 - строка #dhcp.option82.agentRemoteId.type=1 # код субопции 82, содержащей идентификатор коммутатора клиента, позиция и длина последовательности идентификатора dhcp.option82.agentRemoteId.code=2 dhcp.option82.agentRemoteId.position=0 dhcp.option82.agentRemoteId.length=0 # Извлечение vlanId и interfaceId из строкового представления не поддерживается, данную процедуру нужно будет провести в # обработчике процессора протокола, как описано ниже. # код субопции 82, содержащей VLAN, позиция и длина в субопции #dhcp.option82.vlanId.code=1 #dhcp.option82.vlanId.position=0 #dhcp.option82.vlanId.length=2 # код субопции 82, содержащей интерфейс, позиция и длина в субопции #dhcp.option82.interfaceId.code=1 #dhcp.option82.interfaceId.position=3 #dhcp.option82.interfaceId.length=1
При необходимости, данные параметры можно установить вручную в обработчике процессора протокола, в методе (аналогично InetRadiusProcessor).
final DhcpOption agentRemoteId = request.getSubOption( option82RemoteIdCode );
if( agentRemoteId != null )
{
byte[] value = new byte[option82RemoteIdLength];
System.arraycopy( agentRemoteId.value, option82RemoteIdPosition, value, 0, option82RemoteIdLength );
request.setOption( InetDhcpProcessor.AGENT_REMOTE_ID, value );
}
final DhcpOption vlanId = request.getSubOption( option82VlanIdCode );
if( vlanId != null )
{
int vlan = InetUtils.parseInt( vlanId.value, option82VlanIdPosition, option82VlanIdLength );
request.setOption( InetDhcpProcessor.VLAN_ID, vlan );
}Пример обработки для строкового представления (извлечение agentRemoteId не обязательно, если указано dhcp.option82.agentRemoteId.type=1):
@Override
public void preprocessDhcpRequest( DhcpPacket request, DhcpPacket response )
throws Exception
{
DhcpOption circuitId = request.getSubOption( (byte)1 );
DhcpOption remoteId = request.getSubOption( (byte)2 );
request.setOption( InetDhcpProcessor.AGENT_REMOTE_ID, new String( remoteId.value, "UTF-8" ) );
request.setOption( InetDhcpProcessor.INTERFACE_ID, new String( circuitId.value, "UTF-8" ) );
}По описанным выше значениям AGENT_REMOTE_ID, INTERFACE_ID и VLAN, которые будут извлечены из пакета, происходит поиск устройства и сервиса. Конфигурация поиска устройства и сервиса на устройстве:
dhcp.deviceSearchMode=<deviceSearchMode> dhcp.servSearchMode=<servSearchMode> #dhcp.servSearchMode=<servSearchMode>-<subServSearchMode>
Идентификация коммутатора, расположенного под релеем и сервиса на коммутаторе, может производится в нескольких режимах. Режимы определяется переменными конфигурации устройства-релея.
может принимать значения:
| - по giaddr или IP-адресу источника идет поиск устройства, далее у этого устройства вызывается предобработка preprocessDhcpRequest (где можно при необходимости извлечь и установить AGENT_REMOTE_ID, а также INTERFACE_ID или VLAN_ID), далее по установленному AGENT_REMOTE_ID или, если AGENT_REMOTE_ID не установлен - по конфигурации dhcp.option82.agentRemoteId.x agentRemoteId извлекается из пакета и идет поиск агентского устройства, далее у агентского устройства, если таковое найдено вызывается preprocessDhcpRequest (где можно при необходимости извлечь и установить INTERFACE_ID или VLAN_ID). Здесь запоминаются оба устройства, как deviceId и agentDeviceId; |
| - по giaddr или IP-адресу источника идет поиск устройства, по его конфигурации идет извлечение agentRemoteId, далее по agentRemoteId идет поиск агентского устройства. Здесь запоминается последнее найденное устройство как deviceId, agentDeviceId для биллинга будет 0; |
| - по giaddr или IP-адресу источника идет поиск устройства, найденное устройство будет запомнено как deviceId, agentDeviceId для биллинга будет 0. |
Поиск сервиса происходит на агентском устройстве (agentDeviceId), если оно найдено, иначе на устройстве (deviceId).
может принимать значения:
| - поиск по интерфейсу на (найденном) устройстве; |
| - поиск по VLAN'у на устройстве; |
| - поиск на устройстве по интерфейсу и MAC-адресу; |
| - поиск по VLAN'у на устройстве и его дочерних устройствах; |
| - поиск по MAC-адресу на устройстве; |
| - поиск по MAC-адресу на устройстве и дочерних устройствах. |
После поиска сервиса можно дополнительно использовать поиск дочернего устройства (как элемент дополнительной авторизации).
может принимать значения:
| или отсутсвует - нет поиска дочернего сервиса |
| - поиск дочернего сервиса по MAC-адресу, если такого дочернего сервиса нет - ошибка авторизации; |
| - поиск дочернего сервиса по MAC-адресу, если такого дочернего сервиса нет - сессия будет привязана к родительскому сервису. |
Процесс DHCP-авторизации состоит из двух запросов: DISCOVER и REQUEST. В первом запросе клиент запрашивает IP-адреса, какие ему могут предложить DHCP сервера. Во втором просит закрепить за ним конкретный IP-адрес. На DHCP-сервер биллинга попадают запросы с опцией 82, которая позволяет идентифицировать клиента. После идентификации клиента ему выдаётся IP-адрес. Идентификатором сессии при DHCP.82 авторизации выступает MAC-адрес клиента. Допускается одновременная инициализация нескольких сессий за одним портом коммутатора.
Адрес сессии выделяется либо из диапазона, указанного в самом сервисе, либо, если он исчерпан - из пула, определённого в конфигурации устройства. Пул адресов устройства определяется параметром конфигурации , где - id коды категорий ресурсов IP адресов через запятую. Например:
dhcp.ipCategories=4
При превышении числа одновременных сессий сервиса над установленным в свойстве сервиса генерируется ошибка авторизации. В этом случае штатно DISCOVER-запросы будут игнорироваться, а на все REQUEST-запросы будет высылаться ответ DHCP_NAK. Для предотвращения нагрузки на DHCP-сервер постоянной обработкой запросов возможно определение пула фиктивных адресов, выдаваемых при ошибках авторизации. Пул определяется переменной конфигурации устройства , где - id коды категорий ресурсов IP адресов через запятую. Например:
dhcp.disable.ipCategories=3,4
При превышении количества сессий сервиса над ограничением в его свойствах при включенном pool.error выдаются несколько адресов из этого пула, после чего DHCP-запросы игнорируются. Это сделано для невозможности исчерпания пула фиктивных адресов отправкой большого количества DHCP-запросов с разными MAC-адресами. Количество сессий сверх ограничения, для которых могут быть выданы фиктивные адреса задаётся переменной конфигурации .
При смене абонентом устройства идет новый запрос DHCP-Discover, но может быть ситуация, когда старая сессия еще не закрыта по таймауту (пример - только что было продление адреса и абонент сменил устройство). В этом случае будет считаться что у абонента уже есть одна сессия и что IP-адрес этой сессии еще занят. Для того, чтобы на DHCP-Discover происходило закрытие активных сессий на сервисе, нужно указать .
Помимо IP-адреса в ответе DHCP-запроса могут передаваться различные опции. Они определяются из , из которого выдан адрес, а также с помощью переменных конфигурации и , где:
| - сеть, для которой выдаётся параметр; |
| - маска сети; |
| - название опции; |
| - значение опции. |
Первый параметр устанавливает опции безусловно, второй - в зависимости от выданного IP-адреса. Возможные значения названий опций и их значений перечислены в таблице.
Таблица 17.1. Опции
| Название опции | Значение в виде | В DHCP пакете |
| leaseTime | Число в секундах. | Опция 51, срок аренды IP-адреса |
| timeOffset | Число в секундах. | Опция 2. |
| gate | Строка с IP-адресом в виде NNN.NNN.NNN.NNN. | Опция 3, маршрутизатор |
| serverIdentifier | Строка с IP-адресом в виде NNN.NNN.NNN.NNN. | Опция 54, идентификатор DHCP-сервера |
| dns | Строка с одним или несколькими адресами вида NNN.NNN.NNN.NNN, разделённых запятой. | Опция 6, DNS-сервера |
| domainName | Строка. | Опция 15, домен |
| subnetMask | Строка с IP-адресом в виде NNN.NNN.NNN.NNN. | Опция 1, маска подсети |
| renewalTime | Число в секундах. | Опция 58, время, после которого DHCP-клиент должен перейти в RENEW |
| rebindingTime | Число в секундах. | Опция 59, время, после которого DHCP-клиент должен перейти в REBIND |
Для поддержки прямых RENEW запросов (т.е. когда RENEW запрос идет напрямую от абонента, не проходя через relay), в конфигурации нужно указать . При этом для таких запросов можно указать специфичный набор опций, как .
Пример конфигурации:
dhcp.option.serverIdentifier=0.0.0.0 dhcp.option.leaseTime=60 # #dhcp.option.renewalTime= #dhcp.option.rebindingTime= #dhcp.inetOption.1.leaseTime=120 # dhcp.net.option.193.106.88.0:255.255.255.0.gate=193.106.88.1 dhcp.net.option.193.106.88.0:255.255.255.0.dns=194.165.18.6 # dhcp.net.option.172.16.24.0:255.255.255.0.gate=172.16.24.1 dhcp.net.option.172.16.24.0:255.255.255.0.dns=194.165.18.6