Skip to content

Commit 07ce53e

Browse files
committed
[IFMON] Implement the 'set dns' command
- Replace some magic values. - Improve some parameter checks in the 'set address' command.
1 parent 69474b3 commit 07ce53e

3 files changed

Lines changed: 305 additions & 31 deletions

File tree

dll/win32/ifmon/ip.c

Lines changed: 276 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,18 @@
2121
#define DISPLAY_ADRESSES 0x1
2222
#define DISPLAY_DNS 0x2
2323

24+
#define SOURCE_UNCHANGED 0
25+
#define SOURCE_STATIC 1
26+
#define SOURCE_DHCP 2
27+
28+
#define GATEWAY_NONE 1
29+
30+
#define REGISTER_NONE 1
31+
#define REGISTER_PRIMARY 2
32+
#define REGISTER_BOTH 3
33+
2434
static FN_HANDLE_CMD IpSetAddress;
35+
static FN_HANDLE_CMD IpSetDns;
2536
static FN_HANDLE_CMD IpShowAddresses;
2637
static FN_HANDLE_CMD IpShowConfig;
2738
static FN_HANDLE_CMD IpShowDns;
@@ -31,7 +42,8 @@ static
3142
CMD_ENTRY
3243
IpSetCommands[] =
3344
{
34-
{L"address", IpSetAddress, IDS_HLP_IP_SET_ADDRESS, IDS_HLP_IP_SET_ADDRESS_EX, 0}
45+
{L"address", IpSetAddress, IDS_HLP_IP_SET_ADDRESS, IDS_HLP_IP_SET_ADDRESS_EX, 0},
46+
{L"dns", IpSetDns, IDS_HLP_IP_SET_DNS, IDS_HLP_IP_SET_DNS_EX, 0}
3547
};
3648

3749

@@ -407,11 +419,12 @@ IpSetAddress(
407419
{L"mask", NS_REQ_ZERO, FALSE},
408420
{L"gateway", NS_REQ_ZERO, FALSE},
409421
{L"gwmetric", NS_REQ_ZERO, FALSE}};
410-
TOKEN_VALUE ptvSource[] = {{L"static", 1},
411-
{L"dhcp", 2}};
422+
TOKEN_VALUE ptvSource[] = {{L"static", SOURCE_STATIC},
423+
{L"dhcp", SOURCE_DHCP}};
424+
TOKEN_VALUE ptvGateway[] = {{L"none", GATEWAY_NONE}};
412425
GUID InterfaceGUID;
413426
PDWORD pdwTagType = NULL;
414-
DWORD i, dwSource = 0;
427+
DWORD i, dwSource = SOURCE_UNCHANGED, dwGateway = 0;
415428
BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE,
416429
bHaveMask = FALSE, bHaveGateway = FALSE, bHaveMetric = FALSE;
417430
IN_ADDR Address, Mask, Gateway;
@@ -545,23 +558,36 @@ IpSetAddress(
545558

546559
case 4: /* gateway */
547560
DPRINT("Tag: gateway (%S)\n", argv[i + dwCurrentIndex]);
548-
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
549-
TRUE,
550-
&Term,
551-
&Gateway);
552-
if (Status != 0 /*STATUS_SUCCESS*/)
561+
dwError = MatchEnumTag(hDllInstance,
562+
argv[i + dwCurrentIndex],
563+
ARRAYSIZE(ptvGateway),
564+
ptvGateway,
565+
&dwGateway);
566+
if (dwError == ERROR_SUCCESS)
553567
{
554-
DPRINT("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
555-
PrintMessageFromModule(hDllInstance,
556-
IDS_ERROR_BAD_VALUE,
557-
argv[i + dwCurrentIndex],
558-
pttTags[pdwTagType[i]].pwszTag);
559-
dwError = ERROR_SUPPRESS_OUTPUT;
560-
break;
568+
pszGateway = NULL;
569+
pszGwMetric = NULL;
570+
}
571+
else
572+
{
573+
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
574+
TRUE,
575+
&Term,
576+
&Gateway);
577+
if (Status != 0 /*STATUS_SUCCESS*/)
578+
{
579+
DPRINT("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
580+
PrintMessageFromModule(hDllInstance,
581+
IDS_ERROR_BAD_VALUE,
582+
argv[i + dwCurrentIndex],
583+
pttTags[pdwTagType[i]].pwszTag);
584+
dwError = ERROR_SUPPRESS_OUTPUT;
585+
break;
586+
}
587+
pszGateway = argv[i + dwCurrentIndex];
588+
DPRINT("Gateway: %u.%u.%u.%u\n",
589+
Gateway.S_un.S_un_b.s_b1, Gateway.S_un.S_un_b.s_b2, Gateway.S_un.S_un_b.s_b3, Gateway.S_un.S_un_b.s_b4);
561590
}
562-
pszGateway = argv[i + dwCurrentIndex];
563-
DPRINT("Gateway: %u.%u.%u.%u\n",
564-
Gateway.S_un.S_un_b.s_b1, Gateway.S_un.S_un_b.s_b2, Gateway.S_un.S_un_b.s_b3, Gateway.S_un.S_un_b.s_b4);
565591
bHaveGateway = TRUE;
566592
break;
567593

@@ -598,21 +624,24 @@ IpSetAddress(
598624
if (bHaveName == FALSE)
599625
return ERROR_INVALID_SYNTAX;
600626

601-
if (bHaveSource)
602-
{
603-
if ((dwSource == 1) &&
604-
(!bHaveAddress || !bHaveMask))
605-
return ERROR_INVALID_SYNTAX;
627+
/* We need address and mask, or none of them */
628+
if ((bHaveAddress && !bHaveMask) ||
629+
(!bHaveAddress && bHaveMask))
630+
return ERROR_INVALID_SYNTAX;
606631

607-
if ((dwSource == 2) &&
608-
(bHaveAddress || bHaveMask))
609-
return ERROR_INVALID_SYNTAX;
610-
}
632+
/* If we have an address, we need a source */
633+
if (bHaveAddress && !bHaveSource)
634+
return ERROR_INVALID_SYNTAX;
611635

636+
/* We need gateway and metric, or none of them */
612637
if ((bHaveGateway && !bHaveMetric) ||
613638
(!bHaveGateway && bHaveMetric))
614639
return ERROR_INVALID_SYNTAX;
615640

641+
/* If we have a static source, we need an address or a gateway */
642+
if ((dwSource == SOURCE_STATIC) && !bHaveAddress && !bHaveGateway)
643+
return ERROR_INVALID_SYNTAX;
644+
616645
hr = GetInterfaceProperties(&InterfaceGUID, &pProperties);
617646
if (FAILED(hr))
618647
{
@@ -629,7 +658,7 @@ IpSetAddress(
629658
goto done;
630659
}
631660

632-
if (dwSource == 1)
661+
if (dwSource == SOURCE_STATIC)
633662
{
634663
/* STATIC */
635664
NewProperties.dwDhcp = 0;
@@ -650,7 +679,7 @@ IpSetAddress(
650679
L"0.0.0.0", L"0");
651680
}
652681
}
653-
else if (dwSource == 2)
682+
else if (dwSource == SOURCE_DHCP)
654683
{
655684
/* DHCP */
656685
if (pProperties->dwDhcp)
@@ -684,6 +713,223 @@ IpSetAddress(
684713
return dwError;
685714
}
686715

716+
static
717+
DWORD
718+
WINAPI
719+
IpSetDns(
720+
LPCWSTR pwszMachine,
721+
LPWSTR *argv,
722+
DWORD dwCurrentIndex,
723+
DWORD dwArgCount,
724+
DWORD dwFlags,
725+
LPCVOID pvData,
726+
BOOL *pbDone)
727+
{
728+
TAG_TYPE pttTags[] = {{L"name", NS_REQ_ZERO, FALSE},
729+
{L"source", NS_REQ_ZERO, FALSE},
730+
{L"addr", NS_REQ_ZERO, FALSE},
731+
{L"register", NS_REQ_ZERO, FALSE}};
732+
TOKEN_VALUE ptvSource[] = {{L"static", SOURCE_STATIC},
733+
{L"dhcp", SOURCE_DHCP}};
734+
TOKEN_VALUE ptvRegister[] = {{L"none", REGISTER_NONE},
735+
{L"primary", REGISTER_PRIMARY},
736+
{L"both", REGISTER_BOTH}};
737+
GUID InterfaceGUID;
738+
PDWORD pdwTagType = NULL;
739+
DWORD i, dwSource = SOURCE_UNCHANGED;
740+
BOOL bHaveName = FALSE, bHaveSource = FALSE, bHaveAddress = FALSE /*,
741+
bHaveRegister = FALSE */;
742+
IN_ADDR Address;
743+
PWSTR pszName = NULL, pszAddress = NULL;
744+
PWSTR pszParameterBuffer = NULL;
745+
PCWSTR Term;
746+
DWORD dwRegister = REGISTER_NONE;
747+
PTCPIP_PROPERTIES pProperties = NULL;
748+
TCPIP_PROPERTIES NewProperties;
749+
HRESULT hr;
750+
NTSTATUS Status;
751+
DWORD dwError = ERROR_SUCCESS;
752+
753+
DPRINT("IpSetDns()\n");
754+
755+
pdwTagType = HeapAlloc(GetProcessHeap(),
756+
0,
757+
(dwArgCount - dwCurrentIndex) * sizeof(DWORD));
758+
if (pdwTagType == NULL)
759+
{
760+
return ERROR_NOT_ENOUGH_MEMORY;
761+
}
762+
763+
dwError = MatchTagsInCmdLine(hDllInstance,
764+
argv,
765+
dwCurrentIndex,
766+
dwArgCount,
767+
pttTags,
768+
ARRAYSIZE(pttTags),
769+
pdwTagType);
770+
if (dwError != ERROR_SUCCESS)
771+
{
772+
DPRINT1("MatchTagsInCmdLine() failed (Error %lu)\n", dwError);
773+
HeapFree(GetProcessHeap(), 0, pdwTagType);
774+
return dwError;
775+
}
776+
777+
for (i = 0; i < (dwArgCount - dwCurrentIndex); i++)
778+
{
779+
DPRINT("Tag %lu: %lu\n", i, pdwTagType[i]);
780+
781+
switch (pdwTagType[i])
782+
{
783+
case 0: /* name */
784+
DPRINT("Tag: name (%S)\n", argv[i + dwCurrentIndex]);
785+
dwError = NhGetGuidFromInterfaceName(argv[i + dwCurrentIndex],
786+
&InterfaceGUID,
787+
0, 0);
788+
if (dwError != ERROR_SUCCESS)
789+
{
790+
DPRINT("NhGetGuidFromInterfaceName() failed (Error %lu)\n", dwError);
791+
PrintMessageFromModule(hDllInstance,
792+
IDS_ERROR_INVALID_INTERFACE,
793+
argv[i + dwCurrentIndex]);
794+
dwError = ERROR_SUPPRESS_OUTPUT;
795+
break;
796+
}
797+
pszName = argv[i + dwCurrentIndex];
798+
DPRINT("Interface: {%08lx-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
799+
InterfaceGUID.Data1, InterfaceGUID.Data2, InterfaceGUID.Data3, InterfaceGUID.Data4[0], InterfaceGUID.Data4[1],
800+
InterfaceGUID.Data4[2], InterfaceGUID.Data4[3], InterfaceGUID.Data4[4], InterfaceGUID.Data4[5], InterfaceGUID.Data4[6], InterfaceGUID.Data4[7]);
801+
bHaveName = TRUE;
802+
break;
803+
804+
case 1: /* source */
805+
DPRINT("Tag: source (%S)\n", argv[i + dwCurrentIndex]);
806+
dwError = MatchEnumTag(hDllInstance,
807+
argv[i + dwCurrentIndex],
808+
ARRAYSIZE(ptvSource),
809+
ptvSource,
810+
&dwSource);
811+
if (dwError != ERROR_SUCCESS)
812+
{
813+
DPRINT("MatchEnumTag() failed (Error %lu)\n", dwError);
814+
PrintMessageFromModule(hDllInstance,
815+
IDS_ERROR_BAD_VALUE,
816+
argv[i + dwCurrentIndex],
817+
pttTags[pdwTagType[i]].pwszTag);
818+
dwError = ERROR_SUPPRESS_OUTPUT;
819+
break;
820+
}
821+
DPRINT("Source: %lu\n", dwSource);
822+
bHaveSource = TRUE;
823+
break;
824+
825+
case 2: /* addr */
826+
DPRINT("Tag: addr (%S)\n", argv[i + dwCurrentIndex]);
827+
Status = RtlIpv4StringToAddressW(argv[i + dwCurrentIndex],
828+
TRUE,
829+
&Term,
830+
&Address);
831+
if (Status != 0 /*STATUS_SUCCESS*/)
832+
{
833+
DPRINT("RtlIpv4StringToAddressW() failed (Status 0x%08lx)\n", Status);
834+
PrintMessageFromModule(hDllInstance,
835+
IDS_ERROR_BAD_VALUE,
836+
argv[i + dwCurrentIndex],
837+
pttTags[pdwTagType[i]].pwszTag);
838+
dwError = ERROR_SUPPRESS_OUTPUT;
839+
break;
840+
}
841+
DPRINT("IP Address: %u.%u.%u.%u\n",
842+
Address.S_un.S_un_b.s_b1, Address.S_un.S_un_b.s_b2, Address.S_un.S_un_b.s_b3, Address.S_un.S_un_b.s_b4);
843+
pszAddress = argv[i + dwCurrentIndex];
844+
DPRINT("IP Address: %S\n", pszAddress);
845+
bHaveAddress = TRUE;
846+
break;
847+
848+
case 3: /* register */
849+
DPRINT("Tag: register (%S)\n", argv[i + dwCurrentIndex]);
850+
dwError = MatchEnumTag(hDllInstance,
851+
argv[i + dwCurrentIndex],
852+
ARRAYSIZE(ptvRegister),
853+
ptvRegister,
854+
&dwRegister);
855+
if (dwError != ERROR_SUCCESS)
856+
{
857+
DPRINT("MatchEnumTag() failed (Error %lu)\n", dwError);
858+
PrintMessageFromModule(hDllInstance,
859+
IDS_ERROR_BAD_VALUE,
860+
argv[i + dwCurrentIndex],
861+
pttTags[pdwTagType[i]].pwszTag);
862+
dwError = ERROR_SUPPRESS_OUTPUT;
863+
break;
864+
}
865+
DPRINT("Register: %lu\n", dwRegister);
866+
// bHaveRegister = TRUE;
867+
break;
868+
869+
default:
870+
DPRINT1("Unknown tag type %lu\n", pdwTagType[i]);
871+
break;
872+
}
873+
}
874+
875+
if (pdwTagType)
876+
HeapFree(GetProcessHeap(), 0, pdwTagType);
877+
878+
if (dwError != ERROR_SUCCESS)
879+
return dwError;
880+
881+
/* Check parameters */
882+
883+
/* The name and source arguments are mandatory */
884+
if (!bHaveName || !bHaveSource)
885+
return ERROR_INVALID_SYNTAX;
886+
887+
/* If we have a static source, we need to have an address */
888+
if ((dwSource == SOURCE_STATIC) && (!bHaveAddress))
889+
return ERROR_INVALID_SYNTAX;
890+
891+
/* If we have a dhcp source, we must not have an address */
892+
if ((dwSource == SOURCE_DHCP) && (bHaveAddress))
893+
return ERROR_INVALID_SYNTAX;
894+
895+
hr = GetInterfaceProperties(&InterfaceGUID, &pProperties);
896+
if (FAILED(hr))
897+
{
898+
PrintMessageFromModule(hDllInstance,
899+
IDS_ERROR_GET_PROPERTIES,
900+
pszName);
901+
return ERROR_SUPPRESS_OUTPUT;
902+
}
903+
904+
pszParameterBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BUFFER_SIZE * sizeof(WCHAR));
905+
if (pszParameterBuffer == NULL)
906+
{
907+
dwError = ERROR_NOT_ENOUGH_MEMORY;
908+
goto done;
909+
}
910+
911+
StringCchPrintfW(pszParameterBuffer, BUFFER_SIZE,
912+
L"DNS=%s;DynamicUpdate=%s;NameRegistration=%s;",
913+
(pszAddress) ? pszAddress : L"",
914+
((dwRegister == REGISTER_BOTH) || (dwRegister == REGISTER_PRIMARY)) ? L"1" : L"0",
915+
(dwRegister == REGISTER_BOTH) ? L"1" : L"0");
916+
917+
NewProperties.dwDhcp = pProperties->dwDhcp;
918+
NewProperties.pszIpAddress = pProperties->pszIpAddress;
919+
NewProperties.pszSubnetMask = pProperties->pszSubnetMask;
920+
NewProperties.pszParameters = pszParameterBuffer;
921+
922+
SetInterfaceProperties(&InterfaceGUID, &NewProperties);
923+
924+
done:
925+
if (pszParameterBuffer)
926+
HeapFree(GetProcessHeap(), 0, pszParameterBuffer);
927+
928+
CoTaskMemFree(pProperties);
929+
pProperties = NULL;
930+
931+
return dwError;
932+
}
687933

688934
static
689935
DWORD

0 commit comments

Comments
 (0)