UPnP

Universal Plug and Play (UPnP) — набор сетевых протоколов. Цель UPnP — универсальная автоматическая настройка сетевых устройств, как дома, так и в корпоративной среде. Состоит из набора сопутствующих протоколов, построенных на открытых интернет-стандартах.


Описание UPnP[ | ]

UPnP (Universal Plug and Play) — это архитектура многоуровневых соединений между персональными компьютерами и интеллектуальными устройствами, установленными, например, дома. UPnP строится на основе стандартов и технологий интернета, таких как TCP/IP, HTTP и XML, и обеспечивает автоматическое подключение подобных устройств друг к другу и их совместную работу в сетевой среде, в результате чего сеть (например, домашняя) становится лёгкой для настройки большему числу пользователей.

UPnP Forum[ | ]

Universal Plug and Play Forum (Форум UPnP) — открытая ассоциация представителей отрасли, образованная в июне 1999 г. с целью выработки стандартов технологии UPnP, которые упростили бы объединение интеллектуальных устройств в рамках домашних и — со временем — корпоративных сетей. Участники форума создают и публикуют протоколы управления устройствами UPnP и протоколы управления службами.

В начале июня 2001 г. в состав Форума UPnP входило свыше 350 компаний. Руководство работой форума осуществляет Управляющий комитет по UPnP (UPnP Steering Committee), состоящий из 22 членов. Кроме того, имеются Технический комитет, Комитет по маркетингу и различные рабочие комитеты, занимающиеся конкретными категориями устройств. Списки участников форума, а также информация о порядке присоединения к нему доступны на веб-узле форума (EN).

Технические элементы[ | ]

Технология UPnP ориентирована на домашние сети, сети малых предприятий и прочие сети компактных размеров. Она обеспечивает обмен данными между любыми двумя устройствами, находящимися под контролем какого-либо управляющего устройства сети. Технология UPnP действует независимо от используемой операционной системы, физической среды передачи данных или языка программирования.

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

Технология UPnP опирается на весь опыт развития Интернета, в ней активно используются многие его компоненты, в том числе IP, TCP, UDP, HTTP и XML. Проект развития UPnP предусматривает многостороннее сотрудничество заинтересованных компаний в области создания стандартных протоколов управления устройствами (DCP). Как и в случае интернета, эти стандарты будут основываться на протоколах проводного доступа, имеющих декларативный характер, составленных на языке XML и поддерживающих связь через протокол HTTP.

Перенаправление портов[ | ]

UPnP позволяет программно перенаправлять порты. Этим пользуются такие приложения, как Skype, μTorrent. Ниже приведён пример использования объекта OLE для осуществления такого перенаправления ( написан на Delphi 7, поддерживается ОС Windows XP Service Pack 2 и выше).

uses
  ..., WinSock, ComObj, ActiveX....

//Для свежих версий Delphi вместо юнита "ComObj" добавляйте "OleAuto".

...

function GetLocalIP: String; //Получить локальный IP-адрес
const WSVer = $101;
var
  wsaData: TWSAData;
  P: PHostEnt;
  Buf: array [0..127] of Char;
begin
  Result := '';
  if WSAStartup(WSVer, wsaData) = 0 then begin
    if GetHostName(@Buf, 128) = 0 then begin
      P := GetHostByName(@Buf);
      if P <> nil then Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
    end;
    WSACleanup;
  end;
end;

procedure AddUPnPEntry(Port: Integer; const Name: ShortString; LAN_IP: string);
var
  Nat: Variant;
  Ports: Variant;
begin
  if NOT(LAN_IP = '127.0.0.1') then begin
    try
      Nat := CreateOleObject('HNetCfg.NATUPnP');
      Ports := Nat.StaticPortMappingCollection;

      if not VarIsClear(Ports) then begin
        //do something
        //ShowMessage(IntToStr(Ports.Count));
        Ports.Add(Port, 'TCP', Port, LAN_IP, True, name);
      end;
    except on e:Exception do
      ShowMessage('An Error occured with adding UPnP Ports. '+e.Message);
    end;
  end;
end;

procedure RemoveUPnPEntry(Port: Integer);
var
  Nat: Variant;
  Ports: Variant;
begin
  try
    Nat := CreateOleObject('HNetCfg.NATUPnP');
    Ports := Nat.StaticPortMappingCollection;
    Ports.Remove(Port, 'TCP');
  except
    ShowMessage('An Error occured with removing UPnP Ports. ' +
      'Please check to see if your router supports UPnP and ' +
      'has it enabled or disable UPnP.');
  end;
end;

procedure ListUPnPEntry;
var
  Nat: Variant;
  Ports: Variant;
  Enum : IEnumVARIANT;
  MyPort : OLEVariant;
  IntPort, ExtPort : Integer;
  Desc, Protocol, IntClient, ExtIP : WideString;
  Enabled: Boolean;
  iValue: LongWord;
begin
  try
    Nat := CreateOleObject('HNetCfg.NATUPnP');
    Ports := Nat.StaticPortMappingCollection;

    if not VarIsClear(Ports) then begin
      Enum := IUnknown(Ports._NewEnum) as IEnumVARIANT;
      while Enum.Next(1, MyPort, iValue) = S_OK do begin
        Desc := MyPort.Description;
        Enabled := MyPort.Enabled;
        ExtIP := MyPort.ExternalIPAddress;
        ExtPort := MyPort.ExternalPort;
        IntClient := MyPort.InternalClient;
        IntPort := MyPort.InternalPort;
        Protocol := MyPort.Protocol;
        Form1.Memo1.Lines.Add(Desc + ^I + ^I + IntToStr(ExtPort) + ^I + Protocol + ^I + IntToStr(IntPort) + ^I + IntClient);
      end;
    end;

  except
    ShowMessage('An Error occured with listing UPnP Ports.Please check to see if your router supports UPnP and has UPnP enabled.');
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AddUPnPEntry(8090, 'MyProgram', GetLocalIP); //Добавить порт
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  RemoveUPnPEntry(8090); //Удалить порт
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  ListUPnPEntry; //Обновить
end;

В данном примере имя службы задавалось как 'MyProgram'. Имя службы содержит описание программы для перенаправления порта.

См. также[ | ]

Внешние ссылки[ | ]