sing-tun/internal/winipcfg/types.go
2022-07-13 20:51:53 +08:00

1018 lines
40 KiB
Go

/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
*/
package winipcfg
import (
"encoding/binary"
"fmt"
"net/netip"
"strconv"
"unsafe"
"golang.org/x/sys/windows"
)
const (
anySize = 1
maxDNSSuffixStringLength = 256
maxDHCPv6DUIDLength = 130
ifMaxStringSize = 256
ifMaxPhysAddressLength = 32
)
// AddressFamily enumeration specifies protocol family and is one of the windows.AF_* constants.
type AddressFamily uint16
// IPAAFlags enumeration describes adapter addresses flags
// https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-_ip_adapter_addresses_lh
type IPAAFlags uint32
const (
IPAAFlagDdnsEnabled IPAAFlags = 1 << iota
IPAAFlagRegisterAdapterSuffix
IPAAFlagDhcpv4Enabled
IPAAFlagReceiveOnly
IPAAFlagNoMulticast
IPAAFlagIpv6OtherStatefulConfig
IPAAFlagNetbiosOverTcpipEnabled
IPAAFlagIpv4Enabled
IPAAFlagIpv6Enabled
IPAAFlagIpv6ManagedAddressConfigurationSupported
)
// IfOperStatus enumeration specifies the operational status of an interface.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-if_oper_status
type IfOperStatus uint32
const (
IfOperStatusUp IfOperStatus = iota + 1
IfOperStatusDown
IfOperStatusTesting
IfOperStatusUnknown
IfOperStatusDormant
IfOperStatusNotPresent
IfOperStatusLowerLayerDown
)
// IfType enumeration specifies interface type.
type IfType uint32
const (
IfTypeOther IfType = 1 // None of the below
IfTypeRegular1822 = 2
IfTypeHdh1822 = 3
IfTypeDdnX25 = 4
IfTypeRfc877X25 = 5
IfTypeEthernetCSMACD = 6
IfTypeISO88023CSMACD = 7
IfTypeISO88024Tokenbus = 8
IfTypeISO88025Tokenring = 9
IfTypeISO88026Man = 10
IfTypeStarlan = 11
IfTypeProteon10Mbit = 12
IfTypeProteon80Mbit = 13
IfTypeHyperchannel = 14
IfTypeFddi = 15
IfTypeLapB = 16
IfTypeSdlc = 17
IfTypeDs1 = 18 // DS1-MIB
IfTypeE1 = 19 // Obsolete; see DS1-MIB
IfTypeBasicISDN = 20
IfTypePrimaryISDN = 21
IfTypePropPoint2PointSerial = 22 // proprietary serial
IfTypePPP = 23
IfTypeSoftwareLoopback = 24
IfTypeEon = 25 // CLNP over IP
IfTypeEthernet3Mbit = 26
IfTypeNsip = 27 // XNS over IP
IfTypeSlip = 28 // Generic Slip
IfTypeUltra = 29 // ULTRA Technologies
IfTypeDs3 = 30 // DS3-MIB
IfTypeSip = 31 // SMDS, coffee
IfTypeFramerelay = 32 // DTE only
IfTypeRs232 = 33
IfTypePara = 34 // Parallel port
IfTypeArcnet = 35
IfTypeArcnetPlus = 36
IfTypeAtm = 37 // ATM cells
IfTypeMioX25 = 38
IfTypeSonet = 39 // SONET or SDH
IfTypeX25Ple = 40
IfTypeIso88022LLC = 41
IfTypeLocaltalk = 42
IfTypeSmdsDxi = 43
IfTypeFramerelayService = 44 // FRNETSERV-MIB
IfTypeV35 = 45
IfTypeHssi = 46
IfTypeHippi = 47
IfTypeModem = 48 // Generic Modem
IfTypeAal5 = 49 // AAL5 over ATM
IfTypeSonetPath = 50
IfTypeSonetVt = 51
IfTypeSmdsIcip = 52 // SMDS InterCarrier Interface
IfTypePropVirtual = 53 // Proprietary virtual/internal
IfTypePropMultiplexor = 54 // Proprietary multiplexing
IfTypeIEEE80212 = 55 // 100BaseVG
IfTypeFibrechannel = 56
IfTypeHippiinterface = 57
IfTypeFramerelayInterconnect = 58 // Obsolete, use 32 or 44
IfTypeAflane8023 = 59 // ATM Emulated LAN for 802.3
IfTypeAflane8025 = 60 // ATM Emulated LAN for 802.5
IfTypeCctemul = 61 // ATM Emulated circuit
IfTypeFastether = 62 // Fast Ethernet (100BaseT)
IfTypeISDN = 63 // ISDN and X.25
IfTypeV11 = 64 // CCITT V.11/X.21
IfTypeV36 = 65 // CCITT V.36
IfTypeG703_64k = 66 // CCITT G703 at 64Kbps
IfTypeG703_2mb = 67 // Obsolete; see DS1-MIB
IfTypeQllc = 68 // SNA QLLC
IfTypeFastetherFX = 69 // Fast Ethernet (100BaseFX)
IfTypeChannel = 70
IfTypeIEEE80211 = 71 // Radio spread spectrum
IfTypeIBM370parchan = 72 // IBM System 360/370 OEMI Channel
IfTypeEscon = 73 // IBM Enterprise Systems Connection
IfTypeDlsw = 74 // Data Link Switching
IfTypeISDNS = 75 // ISDN S/T interface
IfTypeISDNU = 76 // ISDN U interface
IfTypeLapD = 77 // Link Access Protocol D
IfTypeIpswitch = 78 // IP Switching Objects
IfTypeRsrb = 79 // Remote Source Route Bridging
IfTypeAtmLogical = 80 // ATM Logical Port
IfTypeDs0 = 81 // Digital Signal Level 0
IfTypeDs0Bundle = 82 // Group of ds0s on the same ds1
IfTypeBsc = 83 // Bisynchronous Protocol
IfTypeAsync = 84 // Asynchronous Protocol
IfTypeCnr = 85 // Combat Net Radio
IfTypeIso88025rDtr = 86 // ISO 802.5r DTR
IfTypeEplrs = 87 // Ext Pos Loc Report Sys
IfTypeArap = 88 // Appletalk Remote Access Protocol
IfTypePropCnls = 89 // Proprietary Connectionless Proto
IfTypeHostpad = 90 // CCITT-ITU X.29 PAD Protocol
IfTypeTermpad = 91 // CCITT-ITU X.3 PAD Facility
IfTypeFramerelayMpi = 92 // Multiproto Interconnect over FR
IfTypeX213 = 93 // CCITT-ITU X213
IfTypeAdsl = 94 // Asymmetric Digital Subscrbr Loop
IfTypeRadsl = 95 // Rate-Adapt Digital Subscrbr Loop
IfTypeSdsl = 96 // Symmetric Digital Subscriber Loop
IfTypeVdsl = 97 // Very H-Speed Digital Subscrb Loop
IfTypeIso88025Crfprint = 98 // ISO 802.5 CRFP
IfTypeMyrinet = 99 // Myricom Myrinet
IfTypeVoiceEm = 100 // Voice recEive and transMit
IfTypeVoiceFxo = 101 // Voice Foreign Exchange Office
IfTypeVoiceFxs = 102 // Voice Foreign Exchange Station
IfTypeVoiceEncap = 103 // Voice encapsulation
IfTypeVoiceOverip = 104 // Voice over IP encapsulation
IfTypeAtmDxi = 105 // ATM DXI
IfTypeAtmFuni = 106 // ATM FUNI
IfTypeAtmIma = 107 // ATM IMA
IfTypePPPmultilinkbundle = 108 // PPP Multilink Bundle
IfTypeIpoverCdlc = 109 // IBM ipOverCdlc
IfTypeIpoverClaw = 110 // IBM Common Link Access to Workstn
IfTypeStacktostack = 111 // IBM stackToStack
IfTypeVirtualipaddress = 112 // IBM VIPA
IfTypeMpc = 113 // IBM multi-proto channel support
IfTypeIpoverAtm = 114 // IBM ipOverAtm
IfTypeIso88025Fiber = 115 // ISO 802.5j Fiber Token Ring
IfTypeTdlc = 116 // IBM twinaxial data link control
IfTypeGigabitethernet = 117
IfTypeHdlc = 118
IfTypeLapF = 119
IfTypeV37 = 120
IfTypeX25Mlp = 121 // Multi-Link Protocol
IfTypeX25Huntgroup = 122 // X.25 Hunt Group
IfTypeTransphdlc = 123
IfTypeInterleave = 124 // Interleave channel
IfTypeFast = 125 // Fast channel
IfTypeIP = 126 // IP (for APPN HPR in IP networks)
IfTypeDocscableMaclayer = 127 // CATV Mac Layer
IfTypeDocscableDownstream = 128 // CATV Downstream interface
IfTypeDocscableUpstream = 129 // CATV Upstream interface
IfTypeA12mppswitch = 130 // Avalon Parallel Processor
IfTypeTunnel = 131 // Encapsulation interface
IfTypeCoffee = 132 // Coffee pot
IfTypeCes = 133 // Circuit Emulation Service
IfTypeAtmSubinterface = 134 // ATM Sub Interface
IfTypeL2Vlan = 135 // Layer 2 Virtual LAN using 802.1Q
IfTypeL3Ipvlan = 136 // Layer 3 Virtual LAN using IP
IfTypeL3Ipxvlan = 137 // Layer 3 Virtual LAN using IPX
IfTypeDigitalpowerline = 138 // IP over Power Lines
IfTypeMediamailoverip = 139 // Multimedia Mail over IP
IfTypeDtm = 140 // Dynamic syncronous Transfer Mode
IfTypeDcn = 141 // Data Communications Network
IfTypeIpforward = 142 // IP Forwarding Interface
IfTypeMsdsl = 143 // Multi-rate Symmetric DSL
IfTypeIEEE1394 = 144 // IEEE1394 High Perf Serial Bus
IfTypeIfGsn = 145
IfTypeDvbrccMaclayer = 146
IfTypeDvbrccDownstream = 147
IfTypeDvbrccUpstream = 148
IfTypeAtmVirtual = 149
IfTypeMplsTunnel = 150
IfTypeSrp = 151
IfTypeVoiceoveratm = 152
IfTypeVoiceoverframerelay = 153
IfTypeIdsl = 154
IfTypeCompositelink = 155
IfTypeSs7Siglink = 156
IfTypePropWirelessP2P = 157
IfTypeFrForward = 158
IfTypeRfc1483 = 159
IfTypeUsb = 160
IfTypeIEEE8023adLag = 161
IfTypeBgpPolicyAccounting = 162
IfTypeFrf16MfrBundle = 163
IfTypeH323Gatekeeper = 164
IfTypeH323Proxy = 165
IfTypeMpls = 166
IfTypeMfSiglink = 167
IfTypeHdsl2 = 168
IfTypeShdsl = 169
IfTypeDs1Fdl = 170
IfTypePos = 171
IfTypeDvbAsiIn = 172
IfTypeDvbAsiOut = 173
IfTypePlc = 174
IfTypeNfas = 175
IfTypeTr008 = 176
IfTypeGr303Rdt = 177
IfTypeGr303Idt = 178
IfTypeIsup = 179
IfTypePropDocsWirelessMaclayer = 180
IfTypePropDocsWirelessDownstream = 181
IfTypePropDocsWirelessUpstream = 182
IfTypeHiperlan2 = 183
IfTypePropBwaP2MP = 184
IfTypeSonetOverheadChannel = 185
IfTypeDigitalWrapperOverheadChannel = 186
IfTypeAal2 = 187
IfTypeRadioMac = 188
IfTypeAtmRadio = 189
IfTypeImt = 190
IfTypeMvl = 191
IfTypeReachDsl = 192
IfTypeFrDlciEndpt = 193
IfTypeAtmVciEndpt = 194
IfTypeOpticalChannel = 195
IfTypeOpticalTransport = 196
IfTypeIEEE80216Wman = 237
IfTypeWwanpp = 243 // WWAN devices based on GSM technology
IfTypeWwanpp2 = 244 // WWAN devices based on CDMA technology
IfTypeIEEE802154 = 259 // IEEE 802.15.4 WPAN interface
IfTypeXboxWireless = 281
)
// MibIfEntryLevel enumeration specifies level of interface information to retrieve in GetIfTable2Ex function call.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getifentry2ex
type MibIfEntryLevel uint32
const (
MibIfEntryNormal MibIfEntryLevel = 0
MibIfEntryNormalWithoutStatistics = 2
)
// NdisMedium enumeration type identifies the medium types that NDIS drivers support.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddndis/ne-ntddndis-_ndis_medium
type NdisMedium uint32
const (
NdisMedium802_3 NdisMedium = iota
NdisMedium802_5
NdisMediumFddi
NdisMediumWan
NdisMediumLocalTalk
NdisMediumDix // defined for convenience, not a real medium
NdisMediumArcnetRaw
NdisMediumArcnet878_2
NdisMediumAtm
NdisMediumWirelessWan
NdisMediumIrda
NdisMediumBpc
NdisMediumCoWan
NdisMedium1394
NdisMediumInfiniBand
NdisMediumTunnel
NdisMediumNative802_11
NdisMediumLoopback
NdisMediumWiMAX
NdisMediumIP
NdisMediumMax
)
// NdisPhysicalMedium describes NDIS physical medium type.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/ns-netioapi-_mib_if_row2
type NdisPhysicalMedium uint32
const (
NdisPhysicalMediumUnspecified NdisPhysicalMedium = iota
NdisPhysicalMediumWirelessLan
NdisPhysicalMediumCableModem
NdisPhysicalMediumPhoneLine
NdisPhysicalMediumPowerLine
NdisPhysicalMediumDSL // includes ADSL and UADSL (G.Lite)
NdisPhysicalMediumFibreChannel
NdisPhysicalMedium1394
NdisPhysicalMediumWirelessWan
NdisPhysicalMediumNative802_11
NdisPhysicalMediumBluetooth
NdisPhysicalMediumInfiniband
NdisPhysicalMediumWiMax
NdisPhysicalMediumUWB
NdisPhysicalMedium802_3
NdisPhysicalMedium802_5
NdisPhysicalMediumIrda
NdisPhysicalMediumWiredWAN
NdisPhysicalMediumWiredCoWan
NdisPhysicalMediumOther
NdisPhysicalMediumNative802_15_4
NdisPhysicalMediumMax
)
// NetIfAccessType enumeration type specifies the NDIS network interface access type.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-_net_if_access_type
type NetIfAccessType uint32
const (
NetIfAccessLoopback NetIfAccessType = iota + 1
NetIfAccessBroadcast
NetIfAccessPointToPoint
NetIfAccessPointToMultiPoint
NetIfAccessMax
)
// NetIfAdminStatus enumeration type specifies the NDIS network interface administrative status, as described in RFC 2863.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-net_if_admin_status
type NetIfAdminStatus uint32
const (
NetIfAdminStatusUp NetIfAdminStatus = iota + 1
NetIfAdminStatusDown
NetIfAdminStatusTesting
)
// NetIfConnectionType enumeration type specifies the NDIS network interface connection type.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-_net_if_connection_type
type NetIfConnectionType uint32
const (
NetIfConnectionDedicated NetIfConnectionType = iota + 1
NetIfConnectionPassive
NetIfConnectionDemand
NetIfConnectionMaximum
)
// NetIfDirectionType enumeration type specifies the NDIS network interface direction type.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-net_if_direction_type
type NetIfDirectionType uint32
const (
NetIfDirectionSendReceive NetIfDirectionType = iota
NetIfDirectionSendOnly
NetIfDirectionReceiveOnly
NetIfDirectionMaximum
)
// NetIfMediaConnectState enumeration type specifies the NDIS network interface connection state.
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-_net_if_media_connect_state
type NetIfMediaConnectState uint32
const (
MediaConnectStateUnknown NetIfMediaConnectState = iota
MediaConnectStateConnected
MediaConnectStateDisconnected
)
// DadState enumeration specifies information about the duplicate address detection (DAD) state for an IPv4 or IPv6 address.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-nl_dad_state
type DadState uint32
const (
DadStateInvalid DadState = iota
DadStateTentative
DadStateDuplicate
DadStateDeprecated
DadStatePreferred
)
// PrefixOrigin enumeration specifies the origin of an IPv4 or IPv6 address prefix, and is used with the IP_ADAPTER_UNICAST_ADDRESS structure.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-nl_prefix_origin
type PrefixOrigin uint32
const (
PrefixOriginOther PrefixOrigin = iota
PrefixOriginManual
PrefixOriginWellKnown
PrefixOriginDHCP
PrefixOriginRouterAdvertisement
PrefixOriginUnchanged = 1 << 4
)
// LinkLocalAddressBehavior enumeration type defines the link local address behavior.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-_nl_link_local_address_behavior
type LinkLocalAddressBehavior int32
const (
LinkLocalAddressAlwaysOff LinkLocalAddressBehavior = iota // Never use link locals.
LinkLocalAddressDelayed // Use link locals only if no other addresses. (default for IPv4). Legacy mapping: IPAutoconfigurationEnabled.
LinkLocalAddressAlwaysOn // Always use link locals (default for IPv6).
LinkLocalAddressUnchanged = -1
)
// OffloadRod enumeration specifies a set of flags that indicate the offload capabilities for an IP interface.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ns-nldef-_nl_interface_offload_rod
type OffloadRod uint8
const (
ChecksumSupported OffloadRod = 1 << iota
OptionsSupported
DatagramChecksumSupported
StreamChecksumSupported
StreamOptionsSupported
FastPathCompatible
LargeSendOffloadSupported
GiantSendOffloadSupported
)
// RouteOrigin enumeration type defines the origin of the IP route.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-nl_route_origin
type RouteOrigin uint32
const (
RouteOriginManual RouteOrigin = iota
RouteOriginWellKnown
RouteOriginDHCP
RouteOriginRouterAdvertisement
RouteOrigin6to4
)
// RouteProtocol enumeration type defines the routing mechanism that an IP route was added with, as described in RFC 4292.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-nl_route_protocol
type RouteProtocol uint32
const (
RouteProtocolOther RouteProtocol = iota + 1
RouteProtocolLocal
RouteProtocolNetMgmt
RouteProtocolIcmp
RouteProtocolEgp
RouteProtocolGgp
RouteProtocolHello
RouteProtocolRip
RouteProtocolIsIs
RouteProtocolEsIs
RouteProtocolCisco
RouteProtocolBbn
RouteProtocolOspf
RouteProtocolBgp
RouteProtocolIdpr
RouteProtocolEigrp
RouteProtocolDvmrp
RouteProtocolRpl
RouteProtocolDHCP
RouteProtocolNTAutostatic = 10002
RouteProtocolNTStatic = 10006
RouteProtocolNTStaticNonDOD = 10007
)
// RouterDiscoveryBehavior enumeration type defines the router discovery behavior, as described in RFC 2461.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-_nl_router_discovery_behavior
type RouterDiscoveryBehavior int32
const (
RouterDiscoveryDisabled RouterDiscoveryBehavior = iota
RouterDiscoveryEnabled
RouterDiscoveryDHCP
RouterDiscoveryUnchanged = -1
)
// SuffixOrigin enumeration specifies the origin of an IPv4 or IPv6 address suffix, and is used with the IP_ADAPTER_UNICAST_ADDRESS structure.
// https://docs.microsoft.com/en-us/windows/desktop/api/nldef/ne-nldef-nl_suffix_origin
type SuffixOrigin uint32
const (
SuffixOriginOther SuffixOrigin = iota
SuffixOriginManual
SuffixOriginWellKnown
SuffixOriginDHCP
SuffixOriginLinkLayerAddress
SuffixOriginRandom
SuffixOriginUnchanged = 1 << 4
)
// MibNotificationType enumeration defines the notification type passed to a callback function when a notification occurs.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/ne-netioapi-_mib_notification_type
type MibNotificationType uint32
const (
MibParameterNotification MibNotificationType = iota // Parameter change
MibAddInstance // Addition
MibDeleteInstance // Deletion
MibInitialNotification // Initial notification
)
type ChangeCallback interface {
Unregister() error
}
// TunnelType enumeration type defines the encapsulation method used by a tunnel, as described by the Internet Assigned Names Authority (IANA).
// https://docs.microsoft.com/en-us/windows/desktop/api/ifdef/ne-ifdef-tunnel_type
type TunnelType uint32
const (
TunnelTypeNone TunnelType = 0
TunnelTypeOther = 1
TunnelTypeDirect = 2
TunnelType6to4 = 11
TunnelTypeIsatap = 13
TunnelTypeTeredo = 14
TunnelTypeIPHTTPS = 15
)
// InterfaceAndOperStatusFlags enumeration type defines interface and operation flags
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/ns-netioapi-_mib_if_row2
type InterfaceAndOperStatusFlags uint8
const (
IAOSFHardwareInterface InterfaceAndOperStatusFlags = 1 << iota
IAOSFFilterInterface
IAOSFConnectorPresent
IAOSFNotAuthenticated
IAOSFNotMediaConnected
IAOSFPaused
IAOSFLowPower
IAOSFEndPointInterface
)
// GAAFlags enumeration defines flags used in GetAdaptersAddresses calls
// https://docs.microsoft.com/en-us/windows/desktop/api/iphlpapi/nf-iphlpapi-getadaptersaddresses
type GAAFlags uint32
const (
GAAFlagSkipUnicast GAAFlags = 1 << iota
GAAFlagSkipAnycast
GAAFlagSkipMulticast
GAAFlagSkipDNSServer
GAAFlagIncludePrefix
GAAFlagSkipFriendlyName
GAAFlagIncludeWinsInfo
GAAFlagIncludeGateways
GAAFlagIncludeAllInterfaces
GAAFlagIncludeAllCompartments
GAAFlagIncludeTunnelBindingOrder
GAAFlagSkipDNSInfo
GAAFlagDefault GAAFlags = 0
GAAFlagSkipAll = GAAFlagSkipUnicast | GAAFlagSkipAnycast | GAAFlagSkipMulticast | GAAFlagSkipDNSServer | GAAFlagSkipFriendlyName | GAAFlagSkipDNSInfo
GAAFlagIncludeAll = GAAFlagIncludePrefix | GAAFlagIncludeWinsInfo | GAAFlagIncludeGateways | GAAFlagIncludeAllInterfaces | GAAFlagIncludeAllCompartments | GAAFlagIncludeTunnelBindingOrder
)
// ScopeLevel enumeration is used with the IP_ADAPTER_ADDRESSES structure to identify scope levels for IPv6 addresses.
// https://docs.microsoft.com/en-us/windows/desktop/api/ws2def/ne-ws2def-scope_level
type ScopeLevel uint32
const (
ScopeLevelInterface ScopeLevel = 1
ScopeLevelLink = 2
ScopeLevelSubnet = 3
ScopeLevelAdmin = 4
ScopeLevelSite = 5
ScopeLevelOrganization = 8
ScopeLevelGlobal = 14
ScopeLevelCount = 16
)
// RouteData structure describes a route to add
type RouteData struct {
Destination netip.Prefix
NextHop netip.Addr
Metric uint32
}
func (routeData *RouteData) String() string {
return fmt.Sprintf("%+v", *routeData)
}
// IPAdapterDNSSuffix structure stores a DNS suffix in a linked list of DNS suffixes for a particular adapter.
// https://docs.microsoft.com/en-us/windows/desktop/api/iptypes/ns-iptypes-_ip_adapter_dns_suffix
type IPAdapterDNSSuffix struct {
Next *IPAdapterDNSSuffix
str [maxDNSSuffixStringLength]uint16
}
// String method returns the DNS suffix for this DNS suffix entry.
func (obj *IPAdapterDNSSuffix) String() string {
return windows.UTF16ToString(obj.str[:])
}
// AdapterName method returns the name of the adapter with which these addresses are associated.
// Unlike an adapter's friendly name, the adapter name returned by AdapterName is permanent and cannot be modified by the user.
func (addr *IPAdapterAddresses) AdapterName() string {
return windows.BytePtrToString(addr.adapterName)
}
// DNSSuffix method returns adapter DNS suffix associated with this adapter.
func (addr *IPAdapterAddresses) DNSSuffix() string {
if addr.dnsSuffix == nil {
return ""
}
return windows.UTF16PtrToString(addr.dnsSuffix)
}
// Description method returns description for the adapter.
func (addr *IPAdapterAddresses) Description() string {
if addr.description == nil {
return ""
}
return windows.UTF16PtrToString(addr.description)
}
// FriendlyName method returns a user-friendly name for the adapter. For example: "Local Area Connection 1."
// This name appears in contexts such as the ipconfig command line program and the Connection folder.
func (addr *IPAdapterAddresses) FriendlyName() string {
if addr.friendlyName == nil {
return ""
}
return windows.UTF16PtrToString(addr.friendlyName)
}
// PhysicalAddress method returns the Media Access Control (MAC) address for the adapter.
// For example, on an Ethernet network this member would specify the Ethernet hardware address.
func (addr *IPAdapterAddresses) PhysicalAddress() []byte {
return addr.physicalAddress[:addr.physicalAddressLength]
}
// DHCPv6ClientDUID method returns the DHCP unique identifier (DUID) for the DHCPv6 client.
// This information is only applicable to an IPv6 adapter address configured using DHCPv6.
func (addr *IPAdapterAddresses) DHCPv6ClientDUID() []byte {
return addr.dhcpv6ClientDUID[:addr.dhcpv6ClientDUIDLength]
}
// Init method initializes the members of an MIB_IPINTERFACE_ROW entry with default values.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeipinterfaceentry
func (row *MibIPInterfaceRow) Init() {
initializeIPInterfaceEntry(row)
}
// get method retrieves IP information for the specified interface on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getipinterfaceentry
func (row *MibIPInterfaceRow) get() error {
if err := getIPInterfaceEntry(row); err != nil {
return err
}
// Patch that fixes SitePrefixLength issue
// https://stackoverflow.com/questions/54857292/setipinterfaceentry-returns-error-invalid-parameter?noredirect=1
switch row.Family {
case windows.AF_INET:
if row.SitePrefixLength > 32 {
row.SitePrefixLength = 0
}
case windows.AF_INET6:
if row.SitePrefixLength > 128 {
row.SitePrefixLength = 128
}
}
return nil
}
// Set method sets the properties of an IP interface on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-setipinterfaceentry
func (row *MibIPInterfaceRow) Set() error {
return setIPInterfaceEntry(row)
}
// get method returns all table rows as a Go slice.
func (tab *mibIPInterfaceTable) get() (s []MibIPInterfaceRow) {
return unsafe.Slice(&tab.table[0], tab.numEntries)
}
// free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-freemibtable
func (tab *mibIPInterfaceTable) free() {
freeMibTable(unsafe.Pointer(tab))
}
// Alias method returns a string that contains the alias name of the network interface.
func (row *MibIfRow2) Alias() string {
return windows.UTF16ToString(row.alias[:])
}
// Description method returns a string that contains a description of the network interface.
func (row *MibIfRow2) Description() string {
return windows.UTF16ToString(row.description[:])
}
// PhysicalAddress method returns the physical hardware address of the adapter for this network interface.
func (row *MibIfRow2) PhysicalAddress() []byte {
return row.physicalAddress[:row.physicalAddressLength]
}
// PermanentPhysicalAddress method returns the permanent physical hardware address of the adapter for this network interface.
func (row *MibIfRow2) PermanentPhysicalAddress() []byte {
return row.permanentPhysicalAddress[:row.physicalAddressLength]
}
// get method retrieves information for the specified interface on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getifentry2
func (row *MibIfRow2) get() (ret error) {
return getIfEntry2(row)
}
// get method returns all table rows as a Go slice.
func (tab *mibIfTable2) get() (s []MibIfRow2) {
return unsafe.Slice(&tab.table[0], tab.numEntries)
}
// free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-freemibtable
func (tab *mibIfTable2) free() {
freeMibTable(unsafe.Pointer(tab))
}
// RawSockaddrInet union contains an IPv4, an IPv6 address, or an address family.
// https://docs.microsoft.com/en-us/windows/desktop/api/ws2ipdef/ns-ws2ipdef-_sockaddr_inet
type RawSockaddrInet struct {
Family AddressFamily
data [26]byte
}
func ntohs(i uint16) uint16 {
return binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&i))[:])
}
func htons(i uint16) uint16 {
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, i)
return *(*uint16)(unsafe.Pointer(&b[0]))
}
// SetAddrPort method sets family, address, and port to the given IPv4 or IPv6 address and port.
// All other members of the structure are set to zero.
func (addr *RawSockaddrInet) SetAddrPort(addrPort netip.AddrPort) error {
if addrPort.Addr().Is4() {
addr4 := (*windows.RawSockaddrInet4)(unsafe.Pointer(addr))
addr4.Family = windows.AF_INET
addr4.Addr = addrPort.Addr().As4()
addr4.Port = htons(addrPort.Port())
for i := 0; i < 8; i++ {
addr4.Zero[i] = 0
}
return nil
} else if addrPort.Addr().Is6() {
addr6 := (*windows.RawSockaddrInet6)(unsafe.Pointer(addr))
addr6.Family = windows.AF_INET6
addr6.Addr = addrPort.Addr().As16()
addr6.Port = htons(addrPort.Port())
addr6.Flowinfo = 0
scopeId := uint32(0)
if z := addrPort.Addr().Zone(); z != "" {
if s, err := strconv.ParseUint(z, 10, 32); err == nil {
scopeId = uint32(s)
}
}
addr6.Scope_id = scopeId
return nil
}
return windows.ERROR_INVALID_PARAMETER
}
// SetAddr method sets family and address to the given IPv4 or IPv6 address.
// All other members of the structure are set to zero.
func (addr *RawSockaddrInet) SetAddr(netAddr netip.Addr) error {
return addr.SetAddrPort(netip.AddrPortFrom(netAddr, 0))
}
// AddrPort returns the IP address and port.
func (addr *RawSockaddrInet) AddrPort() netip.AddrPort {
return netip.AddrPortFrom(addr.Addr(), addr.Port())
}
// Addr returns IPv4 or IPv6 address, or an invalid address if the address is neither.
func (addr *RawSockaddrInet) Addr() netip.Addr {
switch addr.Family {
case windows.AF_INET:
return netip.AddrFrom4((*windows.RawSockaddrInet4)(unsafe.Pointer(addr)).Addr)
case windows.AF_INET6:
raw := (*windows.RawSockaddrInet6)(unsafe.Pointer(addr))
a := netip.AddrFrom16(raw.Addr)
if raw.Scope_id != 0 {
a = a.WithZone(strconv.FormatUint(uint64(raw.Scope_id), 10))
}
return a
}
return netip.Addr{}
}
// Port returns the port if the address if IPv4 or IPv6, or 0 if neither.
func (addr *RawSockaddrInet) Port() uint16 {
switch addr.Family {
case windows.AF_INET:
return ntohs((*windows.RawSockaddrInet4)(unsafe.Pointer(addr)).Port)
case windows.AF_INET6:
return ntohs((*windows.RawSockaddrInet6)(unsafe.Pointer(addr)).Port)
}
return 0
}
// Init method initializes a MibUnicastIPAddressRow structure with default values for a unicast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeunicastipaddressentry
func (row *MibUnicastIPAddressRow) Init() {
initializeUnicastIPAddressEntry(row)
}
// get method retrieves information for an existing unicast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getunicastipaddressentry
func (row *MibUnicastIPAddressRow) get() error {
return getUnicastIPAddressEntry(row)
}
// Set method sets the properties of an existing unicast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-setunicastipaddressentry
func (row *MibUnicastIPAddressRow) Set() error {
return setUnicastIPAddressEntry(row)
}
// Create method adds a new unicast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-createunicastipaddressentry
func (row *MibUnicastIPAddressRow) Create() error {
return createUnicastIPAddressEntry(row)
}
// Delete method deletes an existing unicast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-deleteunicastipaddressentry
func (row *MibUnicastIPAddressRow) Delete() error {
return deleteUnicastIPAddressEntry(row)
}
// get method returns all table rows as a Go slice.
func (tab *mibUnicastIPAddressTable) get() (s []MibUnicastIPAddressRow) {
return unsafe.Slice(&tab.table[0], tab.numEntries)
}
// free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-freemibtable
func (tab *mibUnicastIPAddressTable) free() {
freeMibTable(unsafe.Pointer(tab))
}
// get method retrieves information for an existing anycast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getanycastipaddressentry
func (row *MibAnycastIPAddressRow) get() error {
return getAnycastIPAddressEntry(row)
}
// Create method adds a new anycast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-createanycastipaddressentry
func (row *MibAnycastIPAddressRow) Create() error {
return createAnycastIPAddressEntry(row)
}
// Delete method deletes an existing anycast IP address entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-deleteanycastipaddressentry
func (row *MibAnycastIPAddressRow) Delete() error {
return deleteAnycastIPAddressEntry(row)
}
// get method returns all table rows as a Go slice.
func (tab *mibAnycastIPAddressTable) get() (s []MibAnycastIPAddressRow) {
return unsafe.Slice(&tab.table[0], tab.numEntries)
}
// free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-freemibtable
func (tab *mibAnycastIPAddressTable) free() {
freeMibTable(unsafe.Pointer(tab))
}
// IPAddressPrefix structure stores an IP address prefix.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/ns-netioapi-_ip_address_prefix
type IPAddressPrefix struct {
RawPrefix RawSockaddrInet
PrefixLength uint8
_ [2]byte
}
// SetPrefix method sets IP address prefix using netip.Prefix.
func (prefix *IPAddressPrefix) SetPrefix(netPrefix netip.Prefix) error {
err := prefix.RawPrefix.SetAddr(netPrefix.Addr())
if err != nil {
return err
}
prefix.PrefixLength = uint8(netPrefix.Bits())
return nil
}
// Prefix returns IP address prefix as netip.Prefix.
func (prefix *IPAddressPrefix) Prefix() netip.Prefix {
switch prefix.RawPrefix.Family {
case windows.AF_INET:
return netip.PrefixFrom(netip.AddrFrom4((*windows.RawSockaddrInet4)(unsafe.Pointer(&prefix.RawPrefix)).Addr), int(prefix.PrefixLength))
case windows.AF_INET6:
return netip.PrefixFrom(netip.AddrFrom16((*windows.RawSockaddrInet6)(unsafe.Pointer(&prefix.RawPrefix)).Addr), int(prefix.PrefixLength))
}
return netip.Prefix{}
}
// MibIPforwardRow2 structure stores information about an IP route entry.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/ns-netioapi-_mib_ipforward_row2
type MibIPforwardRow2 struct {
InterfaceLUID LUID
InterfaceIndex uint32
DestinationPrefix IPAddressPrefix
NextHop RawSockaddrInet
SitePrefixLength uint8
ValidLifetime uint32
PreferredLifetime uint32
Metric uint32
Protocol RouteProtocol
Loopback bool
AutoconfigureAddress bool
Publish bool
Immortal bool
Age uint32
Origin RouteOrigin
}
// Init method initializes a MIB_IPFORWARD_ROW2 structure with default values for an IP route entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-initializeipforwardentry
func (row *MibIPforwardRow2) Init() {
initializeIPForwardEntry(row)
}
// get method retrieves information for an IP route entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-getipforwardentry2
func (row *MibIPforwardRow2) get() error {
return getIPForwardEntry2(row)
}
// Set method sets the properties of an IP route entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-setipforwardentry2
func (row *MibIPforwardRow2) Set() error {
return setIPForwardEntry2(row)
}
// Create method creates a new IP route entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-createipforwardentry2
func (row *MibIPforwardRow2) Create() error {
return createIPForwardEntry2(row)
}
// Delete method deletes an IP route entry on the local computer.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-deleteipforwardentry2
func (row *MibIPforwardRow2) Delete() error {
return deleteIPForwardEntry2(row)
}
// get method returns all table rows as a Go slice.
func (tab *mibIPforwardTable2) get() (s []MibIPforwardRow2) {
return unsafe.Slice(&tab.table[0], tab.numEntries)
}
// free method frees the buffer allocated by the functions that return tables of network interfaces, addresses, and routes.
// https://docs.microsoft.com/en-us/windows/desktop/api/netioapi/nf-netioapi-freemibtable
func (tab *mibIPforwardTable2) free() {
freeMibTable(unsafe.Pointer(tab))
}
//
// DNS API
//
// DnsInterfaceSettings is meant to be used with SetInterfaceDnsSettings
type DnsInterfaceSettings struct {
Version uint32
_ [4]byte
Flags uint64
Domain *uint16
NameServer *uint16
SearchList *uint16
RegistrationEnabled uint32
RegisterAdapterName uint32
EnableLLMNR uint32
QueryAdapterName uint32
ProfileNameServer *uint16
}
const (
DnsInterfaceSettingsVersion1 = 1 // for DnsInterfaceSettings
DnsInterfaceSettingsVersion2 = 2 // for DnsInterfaceSettingsEx
DnsInterfaceSettingsVersion3 = 3 // for DnsInterfaceSettings3
DnsInterfaceSettingsFlagIPv6 = 0x0001
DnsInterfaceSettingsFlagNameserver = 0x0002
DnsInterfaceSettingsFlagSearchList = 0x0004
DnsInterfaceSettingsFlagRegistrationEnabled = 0x0008
DnsInterfaceSettingsFlagRegisterAdapterName = 0x0010
DnsInterfaceSettingsFlagDomain = 0x0020
DnsInterfaceSettingsFlagHostname = 0x0040
DnsInterfaceSettingsFlagEnableLLMNR = 0x0080
DnsInterfaceSettingsFlagQueryAdapterName = 0x0100
DnsInterfaceSettingsFlagProfileNameserver = 0x0200
DnsInterfaceSettingsFlagDisableUnconstrainedQueries = 0x0400 // v2 only
DnsInterfaceSettingsFlagSupplementalSearchList = 0x0800 // v2 only
DnsInterfaceSettingsFlagDOH = 0x1000 // v3 only
DnsInterfaceSettingsFlagDOHProfile = 0x2000 // v3 only
)