module Resolv::WsControl

Constants

CL_NL_ENTITY
CL_NL_IP
ENTITY_LIST_ID
ENTITY_TYPE_ID
GENERIC_ENTITY
IF_ENTITY
IF_MIB
IF_MIB_STATS_ID
INFO_CLASS_GENERIC
INFO_CLASS_PROTOCOL
INFO_TYPE_PROVIDER
IPPROTO_TCP
IP_MIB_ADDRTABLE_ENTRY_ID
MAX_TDI_ENTITIES
WSAGetLastError
WSCTL_TCP_QUERY_INFORMATION
WsControl

Public Class Methods

get_iflist() click to toggle source
# File win32/lib/win32/resolv9x.rb, line 189
def self.get_iflist
  # Get TDI Entity List
  entities, size =
    wsctl(GENERIC_ENTITY, 0,
          INFO_CLASS_GENERIC,
          INFO_TYPE_PROVIDER,
          ENTITY_LIST_ID,
          MAX_TDI_ENTITIES * 8)  # sizeof(TDIEntityID)
  entities = entities[0, size].
               scan(/.{8}/).
               collect { |e| e.unpack('VV') }

  # Get MIB Interface List
  iflist = []
  ifcount = 0
  entities.each do |entity, instance|
    if( (entity & IF_ENTITY)>0 )
      ifcount += 1
      etype, = wsctl(entity, instance,
                     INFO_CLASS_GENERIC,
                     INFO_TYPE_PROVIDER,
                     ENTITY_TYPE_ID,
                     4)
      if( (API.unpackdw(etype) & IF_MIB)==IF_MIB )
        ifentry, = wsctl(entity, instance,
                         INFO_CLASS_PROTOCOL,
                         INFO_TYPE_PROVIDER,
                         IF_MIB_STATS_ID,
                         21 * 4 + 8 + 130)  # sizeof(IFEntry)
        iflist << [
          API.unpackdw(ifentry[0,4]),
          ifentry[20, 6]
        ]
      end
    end
  end

  # Get IP Addresses
  entities.each do |entity, instance|
    if entity == CL_NL_ENTITY
      etype, = wsctl(entity, instance,
                     INFO_CLASS_GENERIC,
                     INFO_TYPE_PROVIDER,
                     ENTITY_TYPE_ID,
                     4)
      if API.unpackdw(etype) == CL_NL_IP
        ipentries, = wsctl(entity, instance,
                           INFO_CLASS_PROTOCOL,
                           INFO_TYPE_PROVIDER,
                           IP_MIB_ADDRTABLE_ENTRY_ID,
                           24 * (ifcount+1))  # sizeof(IPAddrEntry)
        ipentries.scan(/.{24}/) do |ipentry|
          ipaddr, index = ipentry.unpack('VV')
          if ifitem = iflist.assoc(index)
            ifitem << ipaddr
          end
        end
      end
    end
  end
  iflist
end

Private Class Methods

wsctl(tei_entity, tei_instance, toi_class, toi_type, toi_id, buffsize) click to toggle source
# File win32/lib/win32/resolv9x.rb, line 163
def self.wsctl(tei_entity, tei_instance,
               toi_class, toi_type, toi_id,
               buffsize)
  reqinfo = [
            ## TDIEntityID
              tei_entity, tei_instance,
            ## TDIObjectID
              toi_class, toi_type, toi_id,
            ## TCP_REQUEST_INFORMATION_EX
              ""
            ].pack('VVVVVa16')
  reqsize = API.packdw(reqinfo.size)
  buff = "\0" * buffsize
  buffsize = API.packdw(buffsize)
  result = WsControl.call(
             IPPROTO_TCP,
             WSCTL_TCP_QUERY_INFORMATION,
             reqinfo, reqsize,
             buff, buffsize)
  if result != 0
    raise RuntimeError, "WsControl failed.(#{result})"
  end
  [ buff, API.unpackdw(buffsize) ]
end