Простой сканер сети на Delphi.

05.09.2016

Целью этой статьи является ознакомление с возможностями работы приложений разработанных в среде Delphi с протоколами вычислительных сетей.
По сути — это небольшой сканер сети, позволяющий отследить в сети ли хост и получить его имя.
И так приступим:
Можно воспользоваться компонентами Indy. В моем случае это NM-компоненты (сути не меняет). В примере используется NMPing.
Раздел uses программы включает в себя winsock, StdCtrls, Psock, NMEcho, NMFngr, NMICMP;
Объявляем переменные:

var Form1: TForm1;
hostname,status:string;

Для выполнения целевой задачи , в секции implementation  опишем функцию, которую и будем вызывать.
Функция призвана получить имя хоста по IP-адресу. В ней же опишем и получаемые отклики.

Function GetNameFromIP(Const IP: string): string;
Const
ERR_INADDR = ' Адрес не существует.';
ERR_HOST = ' Имя не определено.';
RES_UNKNOWN = ' ошибка определения хоста';
ERR_WSA = 'Can not initialize WSA.';
WSA_Type = $101; //$202;
var 
WSA : TWSAData;
Host : PHostEnt;
Addr : Integer;
Err : Integer;
Begin
Result := RES_UNKNOWN;
Err := WSAStartup(WSA_Type, WSA);
If Err <> 0 Then
Begin
Exit;
End;
Addr := inet_addr(PChar(IP));
If Addr = INADDR_NONE Then
Begin
  Result := ERR_INADDR;
WSACleanup;
Exit;
End;
Host := gethostbyaddr(@Addr, SizeOf(Addr), PF_INET); If Assigned(Host) Then
Result := Host.h_name
Else
Result := ERR_HOST;
 WSACleanup;
End;
{$R *.DFM}

Далее описываем процедуры, обрабатывающие результат запроса функции :

// Функция вернула положительный результат</pre>
procedure TForm1.NMPing1Ping(Sender: TObject; Host: String; Size,
Time: Integer);
begin
status:='есть хост --  '+GetNameFromIP(NMPing1.Host);
NMPing1.Abort;
end;

// Функция вернула отрицательный результат по тайм-ауту
procedure TForm1.NMPing1TimeOut(Sender: TObject);
begin
status:='хост не отвечает --  '+GetNameFromIP(NMPing1.Host);
NMPing1.Abort;
end;

// Функция вернула отрицательный результат по хосту
procedure TForm1.NMPing1InvalidHost(Sender: TObject);
begin
status:='хост не отвечает или неверно задан хост --  '+GetNameFromIP(NMPing1.Host);
NMPing1.Abort;
end;

Теперь навешем на кнопку процедуру опроса заданного диапазона IP-адресов.
Здесь начальный и конечный адреса заданы в самом коде — при необходимости их легко вынести во внешний объект, -например в компонент Edit.
Данный код позволяет обходить все возможные IP-адреса в заданном диапазоне, т.е. при заданных нами условиях, в перечень сканируемых попадут адреса из сетей диапазонов 10.109.88.0;  10.109.89.0; 10.109.90.0; ……. 10.110.0.0; ….. 10.110.1.0; . и так до конечного адреса 10.110.89.151.
Результат работы программы выводится в компонент Memo.
Конечно же системами безопасности это будет расценено как сканирование сети или попытка вторжения. Ниже код.

procedure TForm1.Button2Click(Sender: TObject);
var
ip1,ip2:string;  // строковые переменные для хранения начального и конечного адресов сканируемого диапазона
i,x,y,z,x2,y2,z2,a,b,j:integer; // y,z,x2,y2,z2 - части IP-адреса IPV4, разделенные в адресе точками
StL,StL2 :TStringList; // временные объекты, - для парсинга адресов
hostname:string;
begin
ip1:='10.109.88.100'; //начальный адрес сканируемого диапазона
ip2:='10.110.89.151'; //конечный адрес сканируемого диапазона
StL:=TstringList.Create;
StL2:=TstringList.Create;
StL.Delimiter:='.';
StL2.Delimiter:='.';
StL.DelimitedText:=ip1;
StL2.DelimitedText:=ip2;
a:= strtoint(StL[0]);
b:=  strtoint(StL2[0]) ;
x:= strtoint(StL[1]);
y:=  strtoint(StL[2]) ;
z:=  strtoint(StL[3]) ;
x2:= strtoint(StL2[1]) ;
y2:= strtoint(StL2[2]) ;
z2:= strtoint(StL2[3]) ;

// ВЕСЬ КОД НИЖЕ - ВЫПОЛНЯЕТ ПРОХОД ПО ДИАПАЗOНУ АДРЕСОВ С ФОРМИРОВАНИЕМ ОТВЕТОВ

if (a=b) and (x=x2) and (y=y2) then begin
for i:=z to z2 do begin
NMPing1.Host:=inttostr(a)+'.'+inttostr(x)+'.'+inttostr(y)+'.'+inttostr(i);
NMPing1.Ping;
memo1.Lines.Add(inttostr(a)+'.'+inttostr(x)+'.'+inttostr(y)+'.'+inttostr(i)+' --  '+status);
end;
end;

if (a=b) and (x=x2) and (y<y2) then begin
for j:=y to y2 do begin
if (j<y2) and (j=y) then begin
for i:=z to 255 do begin
NMPing1.Host:=inttostr(a)+'.'+inttostr(x)+'.'+inttostr(j)+'.'+inttostr(i);
NMPing1.Ping;
memo1.Lines.Add(inttostr(a)+'.'+inttostr(x)+'.'+inttostr(j)+'.'+inttostr(i)+' -- '+status);
end;
end;
if (j<y2) and (j<>y) then begin
for i:=0 to 255 do begin
NMPing1.Host:=inttostr(a)+'.'+inttostr(x)+'.'+inttostr(j)+'.'+inttostr(i);
NMPing1.Ping;
memo1.Lines.Add(inttostr(a)+'.'+inttostr(x)+'.'+inttostr(j)+'.'+inttostr(i)+' -- '+status);
end;
end;
if j=y2 then begin
for i:=0 to z2 do begin
memo1.Lines.Add(inttostr(a)+'.'+inttostr(x)+'.'+inttostr(j)+'.'+inttostr(i));
end;
end;
end;
end;
StL.Free;
StL2.Free;
end;

 

Данная статья приведена в качестве учебного материала и не призывает выполнять сканирование сетей. Связанные с приведенным кодом противоправные действия — полностью под Вашу ответственность.

Оставить комментарий