diff --git a/examples/drivers/windows/include/otLwfIoctl.h b/examples/drivers/windows/include/otLwfIoctl.h index de00cae2c..ae2a18769 100644 --- a/examples/drivers/windows/include/otLwfIoctl.h +++ b/examples/drivers/windows/include/otLwfIoctl.h @@ -733,8 +733,16 @@ typedef struct otCommissionConfig // GUID - InterfaceGuid // otMleCounters - aCounters +#define IOCTL_OTLWF_OT_LINK_LOCAL_ADDRESS \ + OTLWF_CTL_CODE(204, METHOD_BUFFERED, FILE_READ_DATA) + // GUID - InterfaceGuid + +#define IOCTL_OTLWF_OT_RLOC \ + OTLWF_CTL_CODE(205, METHOD_BUFFERED, FILE_READ_DATA) + // GUID - InterfaceGuid + // OpenThread function IOCTL codes #define MIN_OTLWF_IOCTL_FUNC_CODE 100 -#define MAX_OTLWF_IOCTL_FUNC_CODE 203 +#define MAX_OTLWF_IOCTL_FUNC_CODE 205 #endif //__OTLWFIOCTL_H__ diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index 85d2ba962..be161a9ae 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -1664,6 +1664,38 @@ otThreadSetPSKc( return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PSKC, aPSKc)); } +OTAPI +const otIp6Address * +OTCALL +otThreadGetLinkLocalIp6Address( + _In_ otInstance *aInstance + ) +{ + otIp6Address *Result = (otIp6Address*)malloc(sizeof(otIp6Address)); + if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_LINK_LOCAL_ADDRESS, Result) != ERROR_SUCCESS) + { + free(Result); + Result = nullptr; + } + return Result; +} + +OTAPI +const otIp6Address * +OTCALL +otThreadGetRloc( + _In_ otInstance *aInstance + ) +{ + otIp6Address *Result = (otIp6Address*)malloc(sizeof(otIp6Address)); + if (Result && QueryIOCTL(aInstance, IOCTL_OTLWF_OT_RLOC, Result) != ERROR_SUCCESS) + { + free(Result); + Result = nullptr; + } + return Result; +} + OTAPI const otIp6Address * OTCALL diff --git a/examples/drivers/windows/otLwf/iocontrol.c b/examples/drivers/windows/otLwf/iocontrol.c index 08b83084d..772383936 100644 --- a/examples/drivers/windows/otLwf/iocontrol.c +++ b/examples/drivers/windows/otLwf/iocontrol.c @@ -148,6 +148,8 @@ OTLWF_IOCTL_HANDLER IoCtls[] = { "IOCTL_OTLWF_OT_CLEAR_MAC_FIXED_RSS", REF_IOCTL_FUNC_WITH_TUN(otClearMacFixedRss) }, { "IOCTL_OTLWF_OT_NEXT_ROUTE", REF_IOCTL_FUNC(otNextRoute) }, { "IOCTL_OTLWF_OT_MLE_COUNTERS", REF_IOCTL_FUNC(otMleCounters) }, + { "IOCTL_OTLWF_OT_LINK_LOCAL_ADDRESS", REF_IOCTL_FUNC(otLinkLocalAddress) }, + { "IOCTL_OTLWF_OT_RLOC", REF_IOCTL_FUNC(otRloc) }, }; // intentionally -1 in the end due to that IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY (#161) is removed now. @@ -1834,6 +1836,66 @@ otLwfTunIoCtl_otPSKc_Handler( return status; } +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +otLwfIoCtl_otLinkLocalAddress( + _In_ PMS_FILTER pFilter, + _In_reads_bytes_(InBufferLength) + PUCHAR InBuffer, + _In_ ULONG InBufferLength, + _Out_writes_bytes_(*OutBufferLength) + PVOID OutBuffer, + _Inout_ PULONG OutBufferLength + ) +{ + NTSTATUS status = STATUS_INVALID_PARAMETER; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferLength); + + if (*OutBufferLength >= sizeof(otIp6Address)) + { + memcpy(OutBuffer, otThreadGetLinkLocalIp6Address(pFilter->otCtx), sizeof(otIp6Address)); + status = STATUS_SUCCESS; + } + else + { + *OutBufferLength = 0; + } + + return status; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +otLwfIoCtl_otRloc( + _In_ PMS_FILTER pFilter, + _In_reads_bytes_(InBufferLength) + PUCHAR InBuffer, + _In_ ULONG InBufferLength, + _Out_writes_bytes_(*OutBufferLength) + PVOID OutBuffer, + _Inout_ PULONG OutBufferLength + ) +{ + NTSTATUS status = STATUS_INVALID_PARAMETER; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferLength); + + if (*OutBufferLength >= sizeof(otIp6Address)) + { + memcpy(OutBuffer, otThreadGetRloc(pFilter->otCtx), sizeof(otIp6Address)); + status = STATUS_SUCCESS; + } + else + { + *OutBufferLength = 0; + } + + return status; +} + _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS otLwfIoCtl_otMeshLocalEid( diff --git a/examples/drivers/windows/otLwf/iocontrol.h b/examples/drivers/windows/otLwf/iocontrol.h index aa34c4eab..71bde2154 100644 --- a/examples/drivers/windows/otLwf/iocontrol.h +++ b/examples/drivers/windows/otLwf/iocontrol.h @@ -234,5 +234,7 @@ DECL_IOCTL_FUNC(otNextMacFixedRss); DECL_IOCTL_FUNC_WITH_TUN(otClearMacFixedRss); DECL_IOCTL_FUNC(otNextRoute); DECL_IOCTL_FUNC(otMleCounters); +DECL_IOCTL_FUNC(otLinkLocalAddress); +DECL_IOCTL_FUNC(otRloc); #endif // _IOCONTROL_H diff --git a/include/openthread/thread.h b/include/openthread/thread.h index 67ed50991..517b2f61a 100644 --- a/include/openthread/thread.h +++ b/include/openthread/thread.h @@ -455,7 +455,7 @@ OTAPI otError OTCALL otThreadSetMeshLocalPrefix(otInstance *aInstance, const otM * @returns A pointer to Thread link-local IPv6 address. * */ -const otIp6Address *otThreadGetLinkLocalIp6Address(otInstance *aInstance); +OTAPI const otIp6Address *OTCALL otThreadGetLinkLocalIp6Address(otInstance *aInstance); /** * Get the Thread Network Name. diff --git a/src/cli/README.md b/src/cli/README.md index b9f0c62c6..04c951731 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -506,6 +506,36 @@ Delete an IPv6 address from the Thread interface. Done ``` +### ipaddr linklocal + +Print Thread link-local IPv6 address. + +```bash +> ipaddr linklocal +fe80:0:0:0:f3d9:2a82:c8d8:fe43 +Done +``` + +### ipaddr mleid + +Print Thread Mesh Local EID address. + +```bash +> ipaddr mleid +fdde:ad00:beef:0:558:f56b:d688:799 +Done +``` + +### ipaddr rloc + +Print Thread Routing Locator (RLOC) address. + +```bash +> ipaddr rloc +fdde:ad00:beef:0:0:ff:fe00:0 +Done +``` + ### ipmaddr List all IPv6 multicast addresses subscribed to the Thread interface. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 1d875dc6e..69630c8bc 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -1328,6 +1328,21 @@ void Interpreter::ProcessIpAddr(int argc, char *argv[]) { SuccessOrExit(error = ProcessIpAddrDel(argc - 1, argv + 1)); } + else if (strcmp(argv[0], "linklocal") == 0) + { + OutputIp6Address(*otThreadGetLinkLocalIp6Address(mInstance)); + mServer->OutputFormat("\r\n"); + } + else if (strcmp(argv[0], "rloc") == 0) + { + OutputIp6Address(*otThreadGetRloc(mInstance)); + mServer->OutputFormat("\r\n"); + } + else if (strcmp(argv[0], "mleid") == 0) + { + OutputIp6Address(*otThreadGetMeshLocalEid(mInstance)); + mServer->OutputFormat("\r\n"); + } else { ExitNow(error = OT_ERROR_INVALID_ARGS);