чур сильно не критиковать, PERL и VBscript начал использовать только потому что это быстро пишиться, пока не было необходимости на С++ под DirectX океан програмирую

для души.
'---------------------------
' Записать конфиг коммутатора
'---------------------------
Код:
<script language=PerlScript runat=server>
sub Save_Config_On_Device
{
use SNMP_util;
use SNMP_Session;
my ($DevIP, $DevType) = @_;
my $community = "private";
my $router = "$community\@$DevIP";
if (($DevType == 'DES-3526') || ($DevType == 2) )
{
if (eval {my $StatusSave = snmpset($router, "1.3.6.1.4.1.171.12.1.2.6.0", "integer", 3);})
{
return 0;
}
}
return -1;
}
</script>
'---------------------------
' Получить состояние коммутатора
'---------------------------
Код:
<script language=PerlScript runat=server>
sub Get_Status_For_Device
{
use SNMP_util;
use SNMP_Session;
my ($DevIP, $DevType) = @_;
my $NewStatus = -1;
my $community = "public";
my $router = "$community\@$DevIP";
my $sCmd_Status = '';
if ( ($DevType == 'DXS-3326GSR') || ($DevType == 1) ||($DevType == 'DES-3526') || ($DevType == 2) )
{
$sCmd_Status = '1.3.6.1.4.1.171.12.1.1.4.0';
}
if ($sCmd_Status != '')
{
if (eval {$NewStatus = snmpget($router, $sCmd_Status);})
{
$WScript->Echo("Dev: " . $DevType ." IP : " . $DevIP . " Статус: " . $NewStatus);
}
else
{
return -1;
}
}
return $NewStatus;
}
</script>
'---------------------------
' Добавить MAC на Port для коммутатора
'---------------------------
Код:
<script language=PerlScript runat=server>
sub Add_MAC_For_Port
{
use strict;
use Net::SNMP;
my ($IPDev, $DevType, $nPort, $SourceMAC, $nDevOnPort, $bDeny) = @_;
printf("IP-MAC-Port For " . "[" . $SourceMAC . "] On " . $DevType . "[" . $IPDev . " Port:" . $nPort . "]\n");
my $iError = 1;
my $iProfile_Id = '';
my $iRule_Id_ForPort = '';
my $iAdd_Mac_Permint = 0;
my $sCmd_Add_MAC_Source = '';
my $sCmd_Add_MAC_Destination = '';
my $sCmd_Add_MAC_Permint = '';
my $sCmd_Add_MAC_Port = '';
my $sCmd_Add_MAC_Aplly = '';
if ($DevType == 'DES-3526')
{
$iProfile_Id = '5';
$iAdd_Mac_Permint = 2;
if ($bDeny)
{
$iProfile_Id = '6';
$iAdd_Mac_Permint = 1;
}
$iRule_Id_ForPort = (26 * ($nDevOnPort-1)) + $nPort;
$sCmd_Add_MAC_Source = '1.3.6.1.4.1.171.12.9.2.1.1.4.' . $iProfile_Id . '.' . $iRule_Id_ForPort;
$sCmd_Add_MAC_Destination = '1.3.6.1.4.1.171.12.9.2.1.1.5.' . $iProfile_Id . '.' . $iRule_Id_ForPort;
$sCmd_Add_MAC_Permint = '1.3.6.1.4.1.171.12.9.2.1.1.13.' . $iProfile_Id . '.' . $iRule_Id_ForPort;
$sCmd_Add_MAC_Port = '1.3.6.1.4.1.171.12.9.2.1.1.14.' . $iProfile_Id . '.' . $iRule_Id_ForPort;
$sCmd_Add_MAC_Aplly = '1.3.6.1.4.1.171.12.9.2.1.1.15.' . $iProfile_Id . '.' . $iRule_Id_ForPort;
if (Get_Status_For_Device($IPDev, $DevType) == 3)
{
$iError = 0;
}
};
if ($iError == 0)
{
# Получить HEX номер порта
my $nPortHex = Get_Port_For_Device($DevType, $nPort);
my ($session, $error) = Net::SNMP->session(
-hostname => $IPDev,
-version => 'snmpv2',
-community => 'private');
if (defined($session))
{
my $result;
$result = $session->set_request(-varbindlist => [$sCmd_Add_MAC_Source, OCTET_STRING, pack('H*', $SourceMAC), $sCmd_Add_MAC_Destination, OCTET_STRING, pack('H*', '000000000000'), $sCmd_Add_MAC_Permint, INTEGER32, $iAdd_Mac_Permint, $sCmd_Add_MAC_Port, OCTET_STRING, pack('H*', $nPortHex), $sCmd_Add_MAC_Aplly, INTEGER32, 4]);
if (!defined($result))
{
printf("ERROR: %s.\n", $session->error);
$iError = 1;
}
else
{
printf("Ok.\n");
}
$session->close;
}
else
{
printf("ERROR.\n");
$iError = 1;
}
}
return $iError;
}
</script>
'---------------------------
'----Поиск MAC на портах коммутатора в нужном VLAN'е исключая 25 и 26 порты----
'---------------------------
Код:
<script language=PerlScript runat=server>
sub Find_MAC_OnPort_By_IPSwith_FromVLanID ($$$$)
{
use BER;
use SNMP_util;
use SNMP_Session;
my $iError = 1;
my ($Dev_Id, $IPDev, $DevType, $VLanID) = @_;
$Conn = $WScript->CreateObject('ADODB.Connection');
$Conn->Open('ISP');
if($Conn->{State} == 1)
{
my $community = "private";
my $Router = "$community\@$IPDev";
my $DeviceCmd = "";
if($DevType == 2)
{
$DeviceCmd = "1.3.6.1.2.1.17.7.1.2.2.1.2." . $VLanID;
if (Get_Status_For_Device($IPDev, $DevType) == 3)
{
$iError = 0;
}
}
if ($iError == 0)
{
if($DeviceCmd != "")
{
@ret = &snmpwalk($Router, $DeviceCmd);
foreach $desc (@ret)
{
($oid, $desc) = split(':', $desc, 2);
if($desc != "25" & $desc != "26")
{
$Conn->Execute("Insert `monitoring`.`use_device` (`Clock`, `Dev_Id`, `Dev_Port`, `Find_MAC`) Values (Now(), " . $Dev_Id . ", " . $desc . ", '" . ConvertDecMacToHex($oid) . "');");
}
}
}
}
$Conn->Close();
}
undef($Conn);
return 0;
}
</script>
'---------------------------
'----конвертирует Dec MAC (c)DLink в всем привычный Hex ----
'---------------------------
Код:
<script language="vbscript" runat=server>
Function ConvertDecMacToHex(InMAC)
tStr = ""
OutMAC = ""
InMAC = InMAC & "."
Do While (Len(InMAC) > 0)
If Mid(InMAC, 1, 1) <> "." Then
tStr = tStr & Mid(InMAC, 1, 1)
Else
tStr = Hex(tStr)
If Len(tStr) < 2 Then
OutMAC = OutMAC & "0"
End If
OutMAC = OutMAC & tStr
tStr = ""
End If
InMAC = Mid(InMAC, 2, Len(InMAC))
Loop
ConvertDecMacToHex = OutMAC
End Function
</script>
'---------------------------
' Получить номер порта в двоичном виде
' (нагло спёрт с этого форума, спасибо автору)
'---------------------------
Код:
<script language=PerlScript runat=server>
sub Get_Port_For_Device
{
use strict;
my ($sDevType, $nPort) = @_;
my %ports;
$ports{$nPort} = 1;
my $bin_length = 0;
$bin_length = 56 if $sDevType eq 'DES-3550';
$bin_length = 32 if $sDevType eq 'DES-3526';
my $ports_bin;
for ( my $i=1; $i<=$bin_length; $i++ )
{
if (exists $ports{$i})
{
$ports_bin .= '1';
}
else
{
$ports_bin .= '0';
}
}
my $ports_hex;
while ($ports_bin =~ s/^(.{8})// )
{
$ports_hex .= sprintf("%02X",
unpack("N", pack("B32", substr("0"x32 . $1, -32))));
}
return $ports_hex;
}
</script>
у нас так, свич на ТО, клиентам прописали что нужно заново найти порт и затем назначить нужные ACL, к тому же у нас при подключении нового клиента все свободные порты находятся в специальном VLAN'е для "подключения" после заполнения специальной формы блинг переводит его в нужный VLAN.
дальше ещё проще, биллинг с завидной переодичностью ищит все маки на клиентских портах и заносит в соотв. таблицу, если у вас конечно на коммутаторах ТО не проводится и монтажники никогда не перепутают клиентам порты, вам проще.
на коммутаторе при заливке конфига были созданы два профиля:
# ACL Only One MAC для разрешения только "этого" MAC адреса
create access_profile ethernet source_mac FF-FF-FF-FF-FF-FF destination_mac 00-00-00-00-00-00 profile_id 5
# ACL Every MAC для запрещения всех остальных
create access_profile ethernet source_mac 00-00-00-00-00-00 destination_mac 00-00-00-00-00-00 profile_id 6
и так, знаем порт клиента, MAC клиента, поехали:
1. проверяем состояния коммутатора Get_Status_For_Device(DevIP, DevType), DevIP - адрес коммутатора, DevType - его тип например DES-3526 или 2 (но это по моей классофикации

)
2. если свободен (доступен и т.д.) то Add_MAC_For_Port(DevIP, DevType, nPort, sMAC, nDev, bACLType), первые два параметра теже что и в п.1, nPort - номер порта для присвоения MAC, sMAC - MAC клиента, nDev - самое сложное

у нас бывают пользователи с 1-4 устройствами, порты им жаль выдавать вот и сидят на одном, ID правила зависет от N устройсва и порта, bACLType - разрешающее или запрещающее правило если false - то в профиль 5 если true то в 6.
3. пункт 2 повторяем пока не закончатся все устройства на порту.
4. создаём правило запрещающее все остальные MAC на порту
Add_MAC_For_Port(DevIP, DevType, nPort,
sMAC(всё рано какой), nDev,
true)
5. когда все порты привязаны, сохраняем конфиг Save_Config_On_Device(DevIP, DevType)
собственно всё.
есть конечно еще масса других фишек, заливка прошивок, ребут всем по очереди, и сбор дынных о тек. состояниях портов выключение-включение порта, добавления ножного VLANа и т.д.
но это проще уже весь биллинг выложить, а мну жадный

шутка скромный
p.s.:
функции все писались на "вырост" тоесть добавляя тип и oid получаем работу с другими коммутаторами.
если в Find_MAC_OnPort_By_IPSwith_FromVLanID указать управляющий VLAN получим MAC коммутатора.