Руководство по совместному использованию подключения к Интернету (выпуск за ноябрь 2015 г.)
В этом документе описаны действия по включению общего доступа к подключению к Интернету (ICS) на устройстве под управлением Windows 10 IoT Базовая выпуске за ноябрь 2015 г. Целью является совместное подключение к Интернету между точкой доступа программного обеспечения Wi-Fi (SoftAP) и адаптером Ethernet. Если вы используете юбилейный выпуск Windows 10 IoT Базовая, ознакомьтесь с руководством по совместному использованию подключений к Интернету.
Предварительные требования
- Устройство под управлением Windows 10 IoT Базовая выпуске за ноябрь 2015 г.
- Wi-Fi USB-устройство, которое может запускать SoftAP. Сведения о поддерживаемых Wi-Fi USB-устройствах см. в списке совместимости оборудования .
- Ethernet-подключение с доступом к Интернету.
Настройка
Шаг 1. Сбор сведений о сети
Загрузите устройство с подключенным аппаратным ключом Wi-Fi, подключенным кабелем Ethernet.
Запустите SoftAP с устройства IoT Core.
По умолчанию предоставленные корпорацией Майкрософт образы запускают приложение для подключения Интернета вещей, которое настраивает SoftAP, если Wi-Fi радио поддерживается и профиль WLAN не добавлен. Чтобы запустить SoftAP, приложения UWP могут использовать API Windows.Devices.WiFiDirect.WiFiDirectAdvertisementPublisher. Исходный код приложения для подключения Интернета вещей может находиться в GitHub IoTOnboarding.
Запишите SSID сети SoftAP. Он понадобится позже для подключения к устройству IoT Core через Wi-Fi. Для приложения для подключения Интернета вещей SSID будет начинаться с "AJ_SoftAPSsid_" и может быть изменен в файле конфигурации приложения.
Удаленно подключитесь к устройству IoT Core по протоколу SSH.
Сбор сведений о сетях устройств путем поиска индексов и описаний сетевых устройств. Это необходимо для объявления сетей для моста.
На устройстве запустите печать маршрута и соберите следующие данные:
- Запишите индекс сети общедоступного интерфейса для Ethernet.
- Запишите индекс сети интерфейса PRIVATE для SoftAP (например, Microsoft Wi-Fi Direct Virtual Adapter #2).
Например, SoftAP предоставляется через индекс интерфейса 5, описание адаптера Microsoft Wi-Fi Direct Virtual Adapter #2.
На устройстве выполните команду ipconfig /all и соберите следующие данные:
- Запись имени сетевого адаптера интерфейса PRIVATE для SoftAP
Например, при выполнении команды ipconfig /all выполняется поиск определенного адаптера с именем Local Area Connection* 3 с описанием Microsoft Wi-Fi Direct Virtual Adapter #2. Используйте этот метод, чтобы вручную найти имя адаптера из описания, возвращаемого при печати маршрута.
Шаг 2. Создание скриптов триггера общего доступа к подключению к Интернету
Чтобы начать совместное использование подключений к Интернету между двумя сетями, необходимо выполнить следующие действия.
- Настройте разделы реестра, чтобы настроить частные сетевые интерфейсы (SoftAP) и общедоступные сетевые интерфейсы (Ethernet) для моста.
- Задайте соответствующие правила брандмауэра.
- Отключает DHCP для частного интерфейса.
- Задает статический IP-адрес в частном интерфейсе.
- Запускает службу SharedAccess.
- Отправляет код команды "129" в службу SharedAccess.
Создание скрипта для автоматизации параметров ICS
Ниже приведен пример скриптов и кода для автоматизации перечисленных выше шагов, которые можно интегрировать в последовательность запуска устройства. Создайте файл скрипта (например , ConfigureICS.cmd) со следующим содержимым:
echo off
set START_OR_STOP=%1
set PUBLIC_INDEX=%2
set PRIVATE_INDEX=%3
set PRIVATE_INTERFACE_NAME=%4
if not defined PRIVATE_INTERFACE_NAME (
goto usage
)
if "%START_OR_STOP%"=="start" (
REM Set the public and private interface registry keys
reg add HKEY_LOCAL_MACHINE\System\SA /f /v private /t REG_DWORD /d %PRIVATE_INDEX%
reg add HKEY_LOCAL_MACHINE\System\SA /f /v public /t REG_DWORD /d %PUBLIC_INDEX%
REM Set the firewall rules to allow DHCP to work
netsh advfirewall firewall add rule name=\"AllowPort67In\" protocol=UDP dir=in localport=67 action=allow
netsh advfirewall firewall add rule name=\"AllowPort68In\" protocol=UDP dir=in localport=68 action=allow
netsh advfirewall firewall add rule name=\"AllowPort67Out\" protocol=UDP dir=out localport=67 action=allow
netsh advfirewall firewall add rule name=\"AllowPort68Out\" protocol=UDP dir=out localport=68 action=allow
netsh advfirewall firewall add rule name=\"AllowPort53Out\" protocol=UDP dir=out localport=53 action=allow
netsh advfirewall firewall add rule name=\"AllowPort53In\" protocol=UDP dir=in localport=53 action=allow
REM Turn off DHCP and set static IP for private interface
netsh interface ip set address %4 static 192.168.137.1
REM Start sharing
call SharedAccessUtility.exe start
) else if "%START_OR_STOP%"=="stop" (
REM Stop sharing
call SharedAccessUtility.exe stop
REM Set the public and private interface registry keys
reg add HKEY_LOCAL_MACHINE\System\SA /f /v private /t REG_DWORD /d 0
reg add HKEY_LOCAL_MACHINE\System\SA /f /v public /t REG_DWORD /d 0
REM Clear the firewall rules
netsh advfirewall firewall delete rule name="AllowPort67In"
netsh advfirewall firewall delete rule name="AllowPort68In"
netsh advfirewall firewall delete rule name="AllowPort67Out"
netsh advfirewall firewall delete rule name="AllowPort68Out"
netsh advfirewall firewall delete rule name="AllowPort53Out"
netsh advfirewall firewall delete rule name="AllowPort53In"
REM Reenable DHCP for private interface
netsh interface ip set address %4 dhcp
) else (
goto usage
)
goto eof
:usage
ECHO USAGE: %0 [start ^| stop] [public interface index] [private interface index] [private interface name]
ECHO e.g. %0 start 1 2 "Ethernet"
:eof
Этот скрипт выполняет все действия, кроме запуска или остановки службы SharedAccess, и не отправляет команду службы. Для этих задач он вызывает SharedAccessUtility.exe, который необходимо создать.
Создание приложения SharedAccessUtility
В Visual Studio с установленными расширениями шаблонов проектов Windows IoT Core создайте проект Visual C++ "Пустое консольное приложение Windows IoT Core" с именем SharedAccessUtility.
Замените содержимое ConsoleApplication.cpp следующим кодом:
#include "pch.h"
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <stdio.h>
#define SHARED_ACCESS_NAME L"SharedAccess"
#define START_SHARING_CONTROL 129
DWORD StartSharedAccessService(SC_HANDLE *phScm, SC_HANDLE *phSvc)
{
DWORD dwError = ERROR_SUCCESS;
SERVICE_STATUS svcStatus = { 0 };
// open a handle to SCM
*phScm = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (*phScm == NULL)
{
dwError = GetLastError();
printf("\nOpenSCManager failed; error = %d", dwError);
}
else
{
// open a handle to the service
*phSvc = OpenService(*phScm, SHARED_ACCESS_NAME, SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
if (*phSvc == NULL)
{
dwError = GetLastError();
printf("\nOpenService failed; error = %d", dwError);
}
else
{
if (!StartService(*phSvc, 0, NULL))
{
dwError = GetLastError();
if (dwError != ERROR_SERVICE_ALREADY_RUNNING)
{
printf("\nStartService failed; error = %d", dwError);
}
else
{
dwError = ERROR_SUCCESS;
printf("\nService already running.");
}
}
if (dwError == ERROR_SUCCESS)
{
if (QueryServiceStatus(*phSvc, &svcStatus) && svcStatus.dwCurrentState != SERVICE_RUNNING)
{
for (int i = 0; i < 10; i++)
{
printf("\nWaiting 1 second for service to start.");
Sleep(1000);
if (QueryServiceStatus(*phSvc, &svcStatus))
{
if (svcStatus.dwCurrentState == SERVICE_RUNNING)
{
printf("\nService is running.");
// it is, so break out
dwError = ERROR_SUCCESS;
break;
}
else
{
if (svcStatus.dwCurrentState == SERVICE_STOPPED)
{
printf("\nService could not run.");
// it is, so break out
dwError = ERROR_SERVICE_NOT_ACTIVE;
break;
}
}
}
else
{
printf("\nWaiting more time.");
}
}
}
}
}
}
if (dwError == ERROR_SUCCESS) //service is running
{
if (!ControlService(*phSvc, START_SHARING_CONTROL, &svcStatus))
{
dwError = GetLastError();
printf("\nControl service for start sharing failure, %d", dwError);
}
else
{
printf("\nSharing started");
}
}
// Service cleanup done at the main.
return dwError;
}
DWORD StopSharedAccessService(SC_HANDLE *phSvc)
{
DWORD dwError = ERROR_SUCCESS;
SERVICE_STATUS svcStatus = { 0 };
if (!QueryServiceStatus(*phSvc, &svcStatus))
{
dwError = GetLastError();
printf("\nFailed to query sharedaccess, %d", dwError);
}
else
{
if (svcStatus.dwCurrentState != SERVICE_STOPPED)
{
if (ControlService(*phSvc, SERVICE_CONTROL_STOP, &svcStatus))
{
if (QueryServiceStatus(*phSvc, &svcStatus) && svcStatus.dwCurrentState != SERVICE_STOPPED)
{
for (int i = 0; i < 10; i++)
{
printf("\nWaiting 1 second for service to stop.");
Sleep(1000);
if (QueryServiceStatus(*phSvc, &svcStatus))
{
if (svcStatus.dwCurrentState == SERVICE_STOPPED)
{
printf("\nService stopped.");
// it is, so break out
dwError = ERROR_SUCCESS;
break;
}
else
{
printf("\nWaiting more time.");
}
}
}
}
}
}
}
return dwError;
}
void ShowUsage()
{
printf("Usage: SharedAccessUtility.exe start | stop\n"
"Setup: Make sure the public and private interfaces are up and running and that the SharedAccess registry keys are set.");
}
int __cdecl
main(
__in int argc,
__in_ecount(argc) LPSTR argv[]
)
{
SC_HANDLE hScm = NULL;
SC_HANDLE hSvc = NULL;
DWORD dwError = NO_ERROR;
bool startSharing = true;
if (argc < 2)
{
ShowUsage();
return -1;
}
else
{
if (strcmp(argv[1], "start") == 0 || strcmp(argv[1], "/start") == 0)
{
startSharing = true;
}
else if (strcmp(argv[1], "stop") == 0 || strcmp(argv[1], "/stop") == 0)
{
startSharing = false;
}
else
{
ShowUsage();
return -1;
}
}
dwError = startSharing ? StartSharedAccessService(&hScm, &hSvc) : StopSharedAccessService(&hSvc);
// Cleanup
if (hSvc != NULL)
{
CloseServiceHandle(hSvc);
hSvc = NULL;
}
if (hScm != NULL)
{
CloseServiceHandle(hScm);
hScm = NULL;
}
return 0;
}
Выполните сборку для целевой архитектуры, например выпуск x86, и найдите выходные SharedAccessUtility.exe
Шаг 3. Запуск общего доступа к подключению к Интернету
- Скопируйте скрипт ConfigICS.cmd , созданный на шаге 2, на устройство в определенном расположении, например в
C:\test\
- Скопируйте SharedAccessUtility.exe , созданные на шаге 2, на устройство в том же расположении, например
C:\test
\ - На устройстве выполните команду C:\test\ConfigureICS.cmd start [общедоступный индекс] [частный индекс] [имя частного адаптера] В этом примере это будет означать C:\test\ConfigureICS.cmd start 4 5 "Local Area Connection 3"*
На этом этапе устройство включило общий доступ к подключению к Интернету для любого клиента, подключенного к объявленной SSID устройства.