Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Pour qu’une application reçoive le trafic Teredo, l’application doit être autorisée à recevoir le trafic IPv6 dans le pare-feu hôte et l’application doit définir l’option de socket IPV6_PROTECTION_LEVEL sur « PROTECTION_LEVEL_UNRESTRICTED ». Pour activer ce type de scénario, les exceptions de pare-feu détaillées dans ce document doivent être implémentées.
Les configurations de pare-feu suivantes sont requises pour garantir l’interopérabilité fluide entre un pare-feu et Teredo :
Le pare-feu client doit autoriser la résolution de teredo.ipv6.microsoft.com.
Le port UDP 3544 doit être ouvert pour s’assurer que les clients Teredo peuvent communiquer avec le serveur Teredo.
Le pare-feu doit récupérer les ports UDP dynamiques utilisés par le service Teredo sur l’ordinateur local en appelant la fonction FwpmSystemPortsGet0 ; les ports pertinents sont de type FWPM_SYSTEM_PORT_TEREDO. La fonction FwpmSystemPortsGet0 doit être implémentée à la place des fonctions GetTeredoPort ou NotifyTeredoPortChange.
Le pare-feu permet au système d’envoyer et de recevoir des paquets UDP/IPv4 vers le port UDP 1900 sur le sous-réseau local, car cela permet au trafic de découverte UPnP de circuler et d’améliorer les taux de connectivité.
Note
Si cette condition n’est pas remplie, les scénarios susceptibles de rencontrer des problèmes de compatibilité impliquant la communication entre certains types NAT sont introduits ; spécifiquement entre les naTs symétriques et les naTs restreints. Alors que les NAT symétriques sont populaires dans les zones réactives et les NATs restreints sont populaires dans les maisons, la communication entre les deux a le potentiel d’erreur sur le côté du NAT restreint.
Les exceptions ICMPv6 entrantes et sortantes « Demande d’écho » et « Echo Reply » doivent être activées. Ces exceptions sont nécessaires pour s’assurer qu’un client Teredo peut agir en tant que relais spécifique à l’hôte Teredo. Un relais spécifique à l’hôte Teredo peut être identifié par l’adresse IPv6 native supplémentaire ou une adresse 6to4 fournie avec l’adresse Teredo.
Les pare-feu clients doivent prendre en charge les messages d’erreur ICMPv6 suivants et les fonctions de découverte par RFC 4443 :
| Code | Description |
|---|---|
| 135/136 | Sollicitation et publicité des voisins ICMPV6 |
| 133/134 | Sollicitation et publicité du routeur |
| 128/129 | Demande et réponse D’écho ICMPV6 |
| 1 | Destination inaccessible |
| 2 | Paquet trop volumineux |
| 3 | Dépassement du temps |
| 4 | Paramètre non valide |
Si ces messages ne peuvent pas être spécifiquement autorisés, l’exemption de tous les messages ICMPv6 doit être activée sur le pare-feu. En outre, le pare-feu hôte peut remarquer que les paquets classés par les codes 135/136 ou 133/134 proviennent, ou sont ciblés, le service en mode utilisateur iphlpsvc et non à partir de la pile. Ces paquets ne doivent pas être supprimés par le pare-feu hôte. Le service Teredo est implémenté principalement dans le service d’assistance IP « mode utilisateur ».
À l’aide de la INetFwPolicy2 API de pare-feu Windows pour énumérer toutes les règles avec l’indicateur Edge Traversal défini, toutes les applications qui souhaitent écouter le trafic non sollicité sont énumérées pour l’exception de pare-feu. Des informations spécifiques sur l’utilisation de l’option Edge Traversal sont détaillées dans Réception d’un trafic non sollicité sur Teredo.
Les rappels ne sont pas associés à l’exemple de code d’énumération suivant ; Il est fortement recommandé que les pare-feu tiers effectuent régulièrement l’énumération, ou chaque fois que le pare-feu détecte une nouvelle application qui tente de passer par le pare-feu.
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include <atlcomcli.h>
#include <strsafe.h>
#include <netfw.h>
#define NET_FW_IP_PROTOCOL_TCP_NAME L"TCP"
#define NET_FW_IP_PROTOCOL_UDP_NAME L"UDP"
#define NET_FW_RULE_DIR_IN_NAME L"In"
#define NET_FW_RULE_DIR_OUT_NAME L"Out"
#define NET_FW_RULE_ACTION_BLOCK_NAME L"Block"
#define NET_FW_RULE_ACTION_ALLOW_NAME L"Allow"
#define NET_FW_RULE_ENABLE_IN_NAME L"TRUE"
#define NET_FW_RULE_DISABLE_IN_NAME L"FALSE"
#import "netfw.tlb"
void DumpFWRulesInCollection(long Allprofiletypes, NetFwPublicTypeLib::INetFwRulePtr FwRule)
{
variant_t InterfaceArray;
variant_t InterfaceString;
if(FwRule->Profiles == Allprofiletypes)
{
wprintf(L"---------------------------------------------\n");
wprintf(L"Name: %s\n", (BSTR)FwRule->Name);
wprintf(L"Description: %s\n", (BSTR)FwRule->Description);
wprintf(L"Application Name: %s\n", (BSTR)FwRule->ApplicationName);
wprintf(L"Service Name: %s\n", (BSTR)FwRule->serviceName);
switch(FwRule->Protocol)
{
case NET_FW_IP_PROTOCOL_TCP: wprintf(L"IP Protocol: %s\n", NET_FW_IP_PROTOCOL_TCP_NAME);
break;
case NET_FW_IP_PROTOCOL_UDP: wprintf(L"IP Protocol: %s\n", NET_FW_IP_PROTOCOL_UDP_NAME);
break;
default:
break;
}
if(FwRule->Protocol != NET_FW_IP_VERSION_V4 && FwRule->Protocol != NET_FW_IP_VERSION_V6)
{
wprintf(L"Local Ports: %s\n", (BSTR)FwRule->LocalPorts);
wprintf(L"Remote Ports: %s\n", (BSTR)FwRule->RemotePorts);
}
wprintf(L"LocalAddresses: %s\n", (BSTR)FwRule->LocalAddresses);
wprintf(L"RemoteAddresses: %s\n", (BSTR)FwRule->RemoteAddresses);
wprintf(L"Profile: %d\n", Allprofiletypes);
if(FwRule->Protocol == NET_FW_IP_VERSION_V4 || FwRule->Protocol == NET_FW_IP_VERSION_V6)
{
wprintf(L"ICMP TypeCode: %s\n", (BSTR)FwRule->IcmpTypesAndCodes);
}
switch(FwRule->Direction)
{
case NET_FW_RULE_DIR_IN:
wprintf(L"Direction: %s\n", NET_FW_RULE_DIR_IN_NAME);
break;
case NET_FW_RULE_DIR_OUT:
wprintf(L"Direction: %s\n", NET_FW_RULE_DIR_OUT_NAME);
break;
default:
break;
}
switch(FwRule->Action)
{
case NET_FW_ACTION_BLOCK:
wprintf(L"Action: %s\n", NET_FW_RULE_ACTION_BLOCK_NAME);
break;
case NET_FW_ACTION_ALLOW:
wprintf(L"Action: %s\n", NET_FW_RULE_ACTION_ALLOW_NAME);
break;
default:
break;
}
InterfaceArray = FwRule->Interfaces;
if(InterfaceArray.vt != VT_EMPTY)
{
SAFEARRAY *pSa = NULL;
long index = 0;
pSa = InterfaceArray.parray;
for(long index= pSa->rgsabound->lLbound; index < (long)pSa->rgsabound->cElements; index++)
{
SafeArrayGetElement(pSa, &index, &InterfaceString);
wprintf(L"Interfaces: %s\n", (BSTR)InterfaceString.bstrVal);
}
}
wprintf(L"Interface Types: %s\n", (BSTR)FwRule->InterfaceTypes);
if(FwRule->Enabled)
{
wprintf(L"Enabled: %s\n", NET_FW_RULE_ENABLE_IN_NAME);
}
else
{
wprintf(L"Enabled: %s\n", NET_FW_RULE_DISABLE_IN_NAME);
}
wprintf(L"Grouping: %s\n", (BSTR)FwRule->Grouping);
wprintf(L"Edge: %s\n", (BSTR)FwRule->EdgeTraversal);
}
}
int __cdecl main()
{
HRESULT hr;
BOOL fComInitialized = FALSE;
ULONG cFetched = 0;
CComVariant var;
long Allprofiletypes = 0;
try
{
IUnknownPtr pEnumerator = NULL;
IEnumVARIANT* pVariant = NULL;
NetFwPublicTypeLib::INetFwPolicy2Ptr sipFwPolicy2;
//
// Initialize the COM library on the current thread.
//
hr = CoInitialize(NULL);
if (FAILED(hr))
{
_com_issue_error(hr);
}
fComInitialized = TRUE;
hr = sipFwPolicy2.CreateInstance("HNetCfg.FwPolicy2");
if (FAILED(hr))
{
_com_issue_error(hr);
}
Allprofiletypes = NET_FW_PROFILE2_ALL; // 0x7FFFFFFF
printf("The number of rules in the Windows Firewall are %d\n", sipFwPolicy2->Rules->Count);
pEnumerator = sipFwPolicy2->Rules->Get_NewEnum();
if(pEnumerator)
{
hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
}
while(SUCCEEDED(hr) && hr != S_FALSE)
{
NetFwPublicTypeLib::INetFwRulePtr sipFwRule;
var.Clear();
hr = pVariant->Next(1, &var, &cFetched);
if (S_FALSE != hr)
{
if (SUCCEEDED(hr))
{
hr = var.ChangeType(VT_DISPATCH);
}
if (SUCCEEDED(hr))
{
hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&sipFwRule));
}
if (SUCCEEDED(hr))
{
DumpFWRulesInCollection(Allprofiletypes, sipFwRule);
}
}
}
}
catch(_com_error& e)
{
printf ("Error. HRESULT message is: %s (0x%08lx)\n", e.ErrorMessage(), e.Error());
if (e.ErrorInfo())
{
printf ("Description: %s\n", (char *)e.Description());
}
}
if (fComInitialized)
{
CoUninitialize();
}
return 0;
}