terrible Posted April 15, 2011 Posted April 15, 2011 Использую FreeRADIUS как DHCP сервер. Хочу выдать клиенту статические маршруты через опцию 249 Пробовал по разному, но результат отрицательный: Sending DHCP-Ack of id 592183de from 172.16.3.1:67 to 172.16.28.1:67 DHCP-Opcode = Server-Message DHCP-Hardware-Type = Ethernet DHCP-Hardware-Address-Length = 6 DHCP-Hop-Count = 0 DHCP-Transaction-Id = 1495368670 DHCP-Number-of-Seconds = 0 DHCP-Flags = 0 DHCP-Client-IP-Address = 0.0.0.0 DHCP-Your-IP-Address = 192.168.28.161 DHCP-Server-IP-Address = 192.168.3.1 DHCP-Gateway-IP-Address = 172.16.28.1 DHCP-Client-Hardware-Address = 00:01:a3:12:e2:94 DHCP-Server-Host-Name = "" DHCP-Boot-Filename = "" DHCP-Router-Address = 192.168.28.1 DHCP-Subnet-Mask = 255.255.255.0 DHCP-Domain-Name-Server = 192.168.3.1 DHCP-Domain-Name-Server = 192.168.3.3 DHCP-NTP-Servers = 192.43.244.18 DHCP-Vendor = 0x61726b617465 DHCP-IP-Address-Lease-Time = 40 DHCP-DHCP-Server-Identifier = 192.168.3.1 DHCP-SMTP-Server-Address = 81.91.189.7 DHCP-WWW-Server-Address = 192.168.3.5 DHCP-MS-Static-Routes = "0x10c0a8c0a80607" Finished request 1. Опция отлично отправляется, но клиент расценивает этот пакет как невалидный и не принимает. Клиент сейчас в лице Windows 2003 Server. В случае, если опция пустая - клиент принимает пакет. В dictionary.dhcp указал её так: ATTRIBUTE DHCP-MS-Static-Routes 249 string Пробовал по разному называть опцию, и DHCP-MS-Classless-Static-Route и MS-Classless-Static-Route, и MS-Static-Route - результат одинаковый. Поиск в гугле дал странный результат - все по разному называют опцию. Как именно должна называться эта опция, чтобы клиент в лице винды её нормально воспринимал? Или может быть я с типом опции намудрил? Вставить ник Quote
vurd Posted April 17, 2011 Posted April 17, 2011 Как внутреннее название опции отражается в DHCP пакете? Правильно, никак. Ценной информацией было бы, если бы вы показали дамп пакета. К слову, есть еще же опции 33 и 121. Вставить ник Quote
Ivan_83 Posted April 18, 2011 Posted April 18, 2011 10c0a8c0a80607 10 = 16 c0a8 = 192.168 c0a80607 = 192.168.6.7 Тут вроде всё правильно. 192.168.28.161/255.255.255.0 Скорее всего дропает потому что шлюз не попадает в подсеть клиента. И "DHCP-Vendor = 0x61726b617465" - не хочу расшифровывать, там MSFT5.0 должно быть или вообще его не отдавать, оно вроде только для запросов серверу. "DHCP-Gateway-IP-Address = 172.16.28.1" - хрень какая то, клиент такое точно не запрашивал %) также как и ещё куча опций которыми вы в него кидаетесь. # http://cpansearch.perl.org/src/SARENNER/Net-IPAddress-1.10/IPAddress.pm #sub parseIPtoNumber { #return(unpack("N", pack("C4", split(/\./, $_[0])))); # C4 = CCCC #} # mask to bits # http://milanweb.net/uni/old/scripting.html sub subnetBits { my $m = unpack("N", pack("C4", split(/\./, $_[0]))); # parseIPtoNumber my $v = pack("L", $m); my $bcnt = 0; foreach (0..31) { if (vec($v, $_,1) == 1) { $bcnt++; } } return($bcnt); } # (121) Classless-Static-Route / (249) MSFT - Classless route # by Rozhuk Ivan 2011 # RFC 3442 # based on: # http://www.linuxconfig.net/index.php/linux-manual/network/203-transfer-of-static-routes-to-dhcp.html # http://www.linux.by/wiki/index.php/FAQ_DHCP_routes # Syntax: mk_classless_routes_bin_mask($net, $mask, $gw) # example: mk_classless_routes_bin_mask('192.168.1.0', '255.255.255.0', '192.168.0.254') sub mk_classless_routes_bin_mask { #my $net = $_[0]; #my $mask = $_[1]; #my $gw = $_[2]; return(mk_classless_routes_bin_prefixlen($_[0], subnetBits($_[1]), $_[2])); } # Syntax: mk_classless_routes_bin_prefixlen($net, $prefixlen, $gw) # example: mk_classless_routes_bin_prefixlen('192.168.1.0', 24, '192.168.0.254') sub mk_classless_routes_bin_prefixlen { #my $net = $_[0]; #my $prefixlen = $_[1]; #my $gw = $_[2]; my $str; $str = pack('C', $_[1]); if ($_[1] > 0) { my ($s1, $s2, $s3, $s4) = split(/\./, $_[0]); $str .= pack('C', $s1); $str .= pack('C', $s2) if ($_[1] > 8); $str .= pack('C', $s3) if ($_[1] > 16); $str .= pack('C', $s4) if ($_[1] > 24); } $str .= pack('CCCC', split(/\./, $_[2])); return($str); } Это в бинарку пакует, если вам в хэкс то CCCC по тексту в pack нужно заменить на что то :) Поиском по форуму можете найти пости Wingman с немного другой реализацией. Если хотите отдавать маршрутизацию - смотрите что спрашивает клиент, если запрашивает 121 опцию - то отдавайте всё в ней, только если её нет и есть 249 то в неё это же самое пихайте. 249 - это микрософт зачем то придумал на заре ХР, толи 121 тогда не было в РФК толи выпендрится хотели, но содержимое/формат у них один. Разница в том, что опции 224-254 это вендор специфик, и если по грамотному то в 249 маршруты отдавать нужно только если вендор MSFT, а армия мыльниц может идти лесом. И семёрка/2к8 запрашивают теперь 121 и 249. Вставить ник Quote
terrible Posted April 19, 2011 Author Posted April 19, 2011 Вроде разобрался: Возвращаю значение теперь вот так: $RAD_REPLY{'DHCP-MS-Static-Routes'} = mk_classless_routes_bin_prefixlen('192.168.6.0', 24, '192.168.28.2'); По функции, указанной вами выше. Однако это начало работать только тогда, когда в dictionary.dhcp указал её так: ATTRIBUTE DHCP-MS-Static-Routes 249 octets Т.е. аналогично 121 опции. DHCP-Gateway-IP-Address - это фрирадиус зачем-то указывает IP адрес DHCP-Relay в пакете, как отключить эту опцию - не нашёл. Вставить ник Quote
zevgen Posted June 14, 2011 Posted June 14, 2011 Может кто нибудь хорошо знающий перл разъяснить алгоритм в посте Ivan_83 Вставить ник Quote
Ivan_83 Posted June 14, 2011 Posted June 14, 2011 Что именно вы хотите узнать? записываем первый бат результата: длинна префикса в битах $str = pack('C', $_[1]); Если длинна префикса больше нуля то записываем байты из IP адреса сети, содержащие значащие биты if ($_[1] > 0) { разбиваем IP адрес сети на части, чтобы позже сконвертировать строковое представление в число my ($s1, $s2, $s3, $s4) = split(/\./, $_[0]); Первый байт всегда записываем, ибо мы тут потому что как минимум 1 значащий бит есть $str .= pack('C', $s1); Если значащих байт в IP адресе сети больше 1 байта (8 бит) то записываем второй байт... и аналогично до 4байта $str .= pack('C', $s2) if ($_[1] > 8); $str .= pack('C', $s3) if ($_[1] > 16); $str .= pack('C', $s4) if ($_[1] > 24); } разбиваем IP адрес шлюза на байты, и тут же конвертируем их в число и записываем $str .= pack('CCCC', split(/\./, $_[2])); Тут везде подразумевается что изначально оно строка "127" - три байта, а после конвертирования оно 127 - число, 1 байт Вставить ник Quote
SokolovS Posted August 10, 2011 Posted August 10, 2011 (edited) Перевел один из сегментов на DHCP на основе FreeRADIUS. Уже месяц у меня работает, старался реализовать полностью следуя RFC. Самое сложное было с динамикой. Даже удивительно что не падает и не тормозит :) Кстати тут писали, что бывает и клиенты и сервера забивают на список запрошенных параметров и сервера отвечают как хотят, а клиенты это кушают. У меня клиенты физики, ОС разные, но пока такой проблемы я не увидел. Еще по RFC в classless так же должен входить и дефолт! Столкнулся с этим на OpenSUSE 11.x. Виндам всем пофигу. Edited August 10, 2011 by SokolovS Вставить ник Quote
Ivan_83 Posted August 11, 2011 Posted August 11, 2011 В рфк делается упор на состояние данных клиента и его сохранение, на практике, особенно с фрирадиусом это не актуально и не реализуемо. Достаточно тупо лупить ответами с нужным адресом и режектить запросы с остальным, ещё я игнорил запросы от ррас. Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.