WinSock Helper 2.0 MIT Information Services
To display a list of topics by category, click any
of the contents entries below. To display an alphabetical list of
topics, choose the Index button.
Using WSHELPER, for the programmer
BIND-Compatible DNS Resolver API
Help file built: 11/20/96
The sources for this Help file were generated
by Autoduck, the source code documentation tool that generates Print or
Help files from tagged comments in C, C++, Assembly, and Basic source
files.
For more information, contact Eric Artzt (erica@microsoft.com).
Current source and binaries can be found at http://www.accessone.com/~ericartzt/
This software is being provided to you, the LICENSEE, by the Massachusetts Institute of Technology (M.I.T.) under the following license. By obtaining, using and/or copying this software, you agree that you have read, understood, and will comply with these terms and conditions. Permission to use, copy, modify and distribute this software and its documentation for any purpose and without fee or royalty is hereby granted, provided that you agree to comply with the following copyright notice and statements, including the disclaimer, and that the same appear on ALL copies of the software and documentation, including modifications that you make for internal use or for distribution:
Copyright 1994, 1995, 1996 by the Massachusetts Institute of Technology. All rights reserved.
THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
The name of the Massachusetts Institute of Technology or M.I.T. may NOT be used in advertising or publicity pertaining to distribution of the software. Title to copyright in this software and any associated documentation shall at all times remain with M.I.T., and USER agrees to preserve same.
This product includes software developed by the University of California, Berkeley and its contributors.
While the standard WinSock GetXbyY function calls suit many development needs, some applications require true nameserver resolution capability to function. WSHelper provides true resolver functions and resolver-based replacements to WinSock's gethostbyname() and gethostbyaddr() functions.
This version of wshelper and wshelp32 tries to make the end user configuration as simple
as possible. By default the libraries should support the following Winsock TCP/IP
implementations: Microsoft's TCP/IP as provided on Windows 95 and NT, Novell's LAN
WorkPlace, FTP, Inc's PCTCP (and some other their other products), Trumpet Winsock,
CORE Winsock. By using environment variables, simple text files, or a resource editor,
you should also be able to support your own local configuration if these defaults do
not suffice.
When running under Windows 95 or Windows NT both the 16 bit and 32 DLL
will attempt to read the IP addresses of the nameservers, also known as the BIND servers,
from the registry. The libraries will also attempt to read the default domain from
the registry.
This version assumes the registry values are those that Microsoft currently uses
for Windows 95 and NT 4.0. However these values may be configured differently on
other stacks or changed by Microsoft in the future. The actual values used are
defined in the header file mitwhich.h. These values are used to build string resources
in the DLL. So in most cases the string resource is what is actually used. This means
that you may use a resource editor to change the default registry values without
needing to recompile the source code.
When running on Windows 3.x, WFWG, or if the libraries are unable to find the correct
registry values, the library will try to find the configuration information in a file.
The file will be looked for in a variety of places. First it will check 4 different
environment variables, ETC, EXCELAN, NDIR, and PCTCP. If the ETC environment variable
is found the library will look for a file named resolv.cfg in the directory named by
the ETC variable. If the EXCELAN environment variable is found then the library will
use this value as a base directory name and then search the subdirectories etc and tcp
for the resolv.cfg file. If the PCTCP environment variable is found the library
expects this to point to a fully qualified pctcp.ini file as supported by products
from FTP, Inc.
The library goes to even more extreme lengths to get the users configuration data. It
will also look on the user's path for resolv.cfg, trumpwsk.ini, core.ini, and
pctcp.ini. The library does understand the format of the trumpwsk.ini, core.ini, and
pctcp.ini files. The library will also search for the file defined by the string
resource IDS_DEF_RESCONF_PATH, which is initially controlled by the _PATH_RESCONF
defined in the resolv.h header file of the source code.
If all else fails the user will be notified that the machine is not properly
configured but they will be given a chance to continue. In this case some hard coded
defaults will be used. These are defined as string resources. Site administrators
please use a resource editor to change these to your defaults rather than MIT's. It
will provide your users and ours with better performance.
Here is a sample resolv.cfg file:
domain mit.edu
nameserver 18.70.0.160
nameserver 18.71.0.151
nameserver 18.72.0.3
If you have to create a resolv.cfg file for your machine please determine the correct
IP address for your domain and change mit.edu to your own local domain.
For Hesiod support we do not go to quite such elaborate lengths to find the
configuration information. The library will check for a HES_DOMAIN environment
variable. If it is present then this will be used as the RHS or the Hesiod domain,
e.g. ATHENA.MIT.EDU. The LHS and RHS defaults are stringtable entries of
IDS_DEF_HES_LHS and IDS_DEF_HES_RHS. So these may be changed by modifying the source
or editing the resource. The string resource IDS_DEF_HES_CONFIG_FILE is also checked.
In this case the libraries will look to see if a Hesiod config file is present and if
so it will use the RHS and LHS defined in the file. Note that the environment variable
will take precedence over the config file, the config file takes precedence over the
default LHS and RHS string table entries.
Here is a sample hesiod.cfg file:
lhs .ns
rhs .ATHENA.MIT.EDU
At Stanford the proper values would be:
lhs .ns
rhs .STANFORD.EDU
A more formal description of the resolv.cfg and hesiod.cfg syntax:
To use either the DNS or Hesiod resolution functions, a resolver configuration
file (by default, C:\\NET\\TCP\\RESOLV.CFG - change _PATH_RESCONF in resolv.h) must
be set up. This should contain at least one entry of the form:
nameserver\tab < ip-address >
, where < ip-address > is the dotted-decimal IP address of a known BIND
server. If no nameserver is specified, the resolver code will assume that the
local machine is capable of handling resolver queries. If no BIND server is
running locally, the resolver routines will search a local hosts file (by
default, C:\\TCP\\HOSTS, change _PATH_HOSTS in gethna.c). If you wish the resolver
functions to search a default domain, add an entry of the form:
domain\tab \tab < default.domain >
to the resolver configuration file. Note that
domain\tab \tab MIT.EDU
would be valid whereas
domain\tab \tab .MIT.EDU
includes an unncecessary first dot.
To configure Hesiod name service lookup, create a Hesiod configuration file (by
default C:\\NET\\HESIOD.CFG) with two entries of the form:
lhs\tab \tab .ns
rhs\tab \tab .your.hesiod.domain
, noting that here a first dot is needed.
The WSHelper (Windows Sockets Helper) library was created in an effort to fill a gap in the current WinSock specification (1.1). This specification, while requiring implementors to provide getXbyY() style "database" functions which retrieve host address, service port, and protocol information, does not explicitly state how the functions should go about this. At the simple level, implementors could have the database functions search local files, which is fine for finding standard service and protocol information, but impractical for modern applications which could possibly require a canonical Internet host table, and thus this approach is suitable only for PC's that use TCP/IP on a LAN basis. More reasonably, implementors could search a local host table, then, failing that, go on to make a resolver query to a known nameserver, or vice versa. This is precisely what many implementors do, but since this functionality is abstracted at a fairly high level (the actual resolver functions are inaccessible to de
velopers), and because the specification is as vague as it is, a need exists for true WinSock-based BIND resolver functions, which WSHelper provides. In addition, WSHelper complements its BIND support with MIT Hesiod Name Service support, for queries on sites which support the Hesiod query class.
We have also found that in many Winsock 1.1 implementations the getXbyY() functions are poorly implemented. By provding the alternate implementation for which full source code is available we hope to improve this situation. At this time we have not attempted to implement non-blocking versions of these function nor have we implemented thread safe versions. We may provide this functionality in the future.
WSHelper also provides an interface to MIT Hesiod Name Service resolution functions.
WSHelper also provides an interface to other functions, most are related to name resolution.
First and foremost, it is the responsibility of the module calling WSHelper to take measures to ensure that a valid WINSOCK.DLL exists on the system and has been loaded (either automatically or dynamically), and as well that WSAStartup() has been called and successfully. The WinSock documentation describes how this is done.
The wshelper and wshelp32 DLLs consist of a set of C functions that may be used by any
application developer. The exported functions which are accessible to applications are
described individually in the C elements section of this document.
The wshelper.dll is a 16 bit DLL. It has been tested on Windows 3.11, WFWG 3.11,
Windows 95 and Windows NT 3.x and 4.0. The wshelp32.dll is the 32 bit version of the
same library. Currently we are only distributing the i386 build. This has been tested
on Windows 95, and Windows 4.0 with the Microsoft supplied TCP/IP stacks. Please see
the end user configuration section for more installation/configuration information.
Bugs may be reported to bugs@mit.edu.
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
For copying and distribution information, see the file < mit-copyright.h >
Original version by Steve Dyer, IBM/Project Athena.
WSHelper DNS/Hesiod Library for WINSOCK
For copying and distribution information, see the file < mit-copyright.h >
Original version by Steve Dyer, IBM/Project Athena.
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
Contains implementation of inet_aton
WSHelper DNS/Hesiod Library for WINSOCK
Notes on different Winsock stack configuration files.
The Microsoft stacks for Windows95 and NT 3.x, 4.x use the registry to store the
default domain and the IP addresses of the DNS servers. The wshelper and wshelp32
will use the registry information when possible.
Novell's LAN WorkPlace stack and the much older Excelan products use a resolv.cfg file
to store this information. The resolv.cfg file could be located in a number of places
over the years. Our DLL will try to search for it in:
C:\\etc\\resolv.cfg
C:\\excelan\\tcp\\resolv.cfg
C:\\net\\tcp\\resolv.cfg
%NDIR%\\etc\\resolv.cfg
%NDIR%\\tcp\\resolv.cfg
where %NDIR% is the expansion of the local environment variable NDIR. So setting NDIR to
be N:\\COMMON\\NET would mean that we would also look in N:\\common\\net\\etc\\resolv.cfg and
N:\\common\\net\\tcp\\resolv.cfg for the domain and nameserver information.
Here is a sample resolv.cfg file
LAN WorkPlace resolver configuration file
domain mit.edu
nameserver 18.70.0.160
nameserver 18.71.0.151
nameserver 18.72.0.3
end of file
The TRUMPET Winsock stack uses a TRUMPETWSK.INI file to store the domain and nameserver
configuration information. The section tag is [Trumpet Winsock]. The domain information
is identified by domain= and the nameserver information is identified by a single name,
dns=, multiple nameservers may be specified on the same line and they should be space
delimited.
trupwsk.ini
[Trumpet Winsock]
dns=18.71.0.151 18.70.0.160 18.72.0.3
domain=mit.edu
Core Internet-Connect uses a CORE.INI file, nameservers are comma delimited.
[winsock]
domainname=mit.edu
nameservers=18.71.0.151, 18.70.0.160, 18.72.0.3
FTP software uses a PCTCP.INI file. This file may be located by use of the environment
variable PCTCP.
[pctcp general]
domain=mit.edu
[pctcp addresses]
domain-name-server=18.70.0.160
domain-name-server=18.71.0.151
domain-name-server=18.72.0.3
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
WSHelper DNS/Hesiod Library for WINSOCK
Compress domain name 'exp_dn' into 'comp_dn'. Return the size of the compressed name or -1. 'length' is the size of the array pointed to by 'comp_dn'. 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] is a pointer to the beginning of the message. The list ends with NULL. 'lastdnptr' is a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect is to update the list of pointers for labels inserted into the message as we compress the name. If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' is NULL, we don't update the list.
Defined in: C:/WORK/WSHELPER/RES_COMP.C
Given the name of a host query the nameservers for the T_HINFO information associated with the host.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This function will query the nameservers for the MX records associated with the given hostname. Note that the return is a pointer to the mxent structure so an application making this call can iterate through the different records returned and can also reference the preference information associated with each hostname returned.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This function will query the nameservers about the given hostname for and DNS record type that the application wishes to query.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This function is only used when the library is running under a known 32 bit Microsoft Operating system
Defined in: C:/WORK/WSHELPER/RES_INIT.C
FALSE - if the subkey cannot be queried or possibly opened. TRUE - if the subkey can be queried but it is not of type: REG_EXPAND_SZ If the subkey can be queried, and its type is REG_EXPAND_SZ, and it can be expanded the return value is the number of characters stored in the buf parameter. If the number of characters is greater than the size of the of the destination buffer, the return value should be the size of the buffer required to hold the value.
print the error indicated by the h_errno value in a MessageBox.
Defined in: C:/WORK/WSHELPER/HERROR.C
The function hes_error may be called to determine the source of the error. It will return one of the HES_ER_* codes defined in hesiod.h. It does not take an argument.
Defined in: C:/WORK/WSHELPER/HESIOD.C
This will a pointer to a hes_postoffice structure. This call is used to obtain a user's type of mail account and the location of that account. E.g. POP PO10.MIT.EDU or IMAP IMAP-TEST.MIT.EDU
Defined in: C:/WORK/WSHELPER/HESMAILH.C
Given a username this function will return the pwd information, eg username, uid, gid, fullname, office location, phone number, home directory, and default shell
Defined in: C:/WORK/WSHELPER/HESPWNAM.C
Given a UID this function will return the pwd information, eg username, uid, gid, fullname, office location, phone number, home directory, and default shell
Defined in: C:/WORK/WSHELPER/HESPWNAM.C
This function will query a Hesiod server for a servent structure given a service name and protocol. This is a replacement for the Winsock getservbyname function which normally just uses a local services file. This allows a site to use a centralized database for adding new services.
Defined in: C:/WORK/WSHELPER/HESSERVB.C
This function is not exported. It takes no arguments. However it is important to understand how this works. It sets the global variables Hes_LHS and Hes_RHS which are used to form the Hesiod queries. Understanding how this works and setting up the correct configuration will determine if the Hesiod queries will work at your site. Settings can be configured by makgin source code changes and rebuilding the DLL, editing resources in the DLL, using a co9nfiguration file, or setting an environment variable.
The function first tries to open the HesConfigFile and set the Hes_RHS and Hes_LHS variables from this. If there is no config file then the function tries to load a string resource from the DLL to set the LHS and RHS. If the string resources cannot be loaded then the LHS and RHS will be set by the values of DEF_LHS and DEF_RHS, these are defined in hesiod.h. Note that the string resources are by default set to these same values since the RC files include hesiod.h
Finally if the user sets the environment variable HES_DOMAIN the RHS will be overridden by the value of the HES_DOMAIN value.
Note that LoadString requires us to first find the module handle of the DLL. We have to use the internal module name as defined in the DEF file. If you change the library name within the DEF file you also need to change the appropriate string in hesiod.c
Defined in: C:/WORK/WSHELPER/HESIOD.C
is the primary interface to the Hesiod name server. It takes two arguments, a name to be resolved and a string, known as a HesiodNameType. Remarks\tab If the environment variable HES_DOMAIN is set, this domain will override what is in /etc/athena/hesiod.conf. FILES: hesiod.h, hesiod.conf
Defined in: C:/WORK/WSHELPER/HESIOD.C
The hes_to_bind function use the LHS and RHS values and binds them with the parameters so that a well formed DNS query may be performed.
Defined in: C:/WORK/WSHELPER/HESIOD.C
Check whether "cp" is a valid ascii representation of an Internet address and convert to a binary address. Returns 1 if the address is valid, 0 if not. This replaces inet_addr, the return value from which cannot distinguish between failure and a local broadcast address.
Defined in: C:/WORK/WSHELPER/INETATON.C
Our replacement for dn_expand called rdn_expand. Older versions of the DLL used to export this as dn_expand but this has caused some conflict with more recent versions of the MSDEV libraries. rdn_expand() expands the compressed domain name comp_dn to a full domain name. Expanded names are converted to upper case.
.
Defined in: C:/WORK/WSHELPER/RES_COMP.C
Global information that is used by the resolver routines is kept in the variable _res. Most of the values have reasonable defaults and can be ignored. Options are a simple bit mask and are OR'ed in to enable. Options stored in _res.options are defined in < resolv.h > and are as follows.
Defined in: C:/WORK/WSHELPER/RES_INIT.C
RES_DEBUG Print debugging messages.
RES_AAONLY Accept authoritative answers only. res_send() will continue until it finds an authoritative answer or finds an error. Currently this is not implemented.
RES_USEVC Use TCP connections for queries instead of UDP.
RES_PRIMARY Query primary server only.
RES_IGNTC Unused currently (ignore truncation errors, that is, do not retry with TCP).
RES_RECURSE Set the recursion desired bit in queries. This is the default. res_send() does not do iterative queries and expects the name server to handle recursion.
RES_DEFNAMES Append the default domain name to single label queries. This is the default.
RES_STAYOPEN Used with RES_USEVC to keep the TCP connection open between queries. This is useful only in programs that regularly do many queries. UDP should be the normal mode used.
RES_DNSRCH Search up local domain tree.
This function reads the resolver configuration files and retrieves the default domain name, search order and name server address(es). If no server is given, the local host is tried. If no domain is given, that associated with the local host is used. It can be overriden with the environment variable LOCALDOMAIN. This function is normally executed by the first call to one of the other resolver functions.
Defined in: C:/WORK/WSHELPER/RES_INIT.C
Form all types of queries.
Defined in: C:/WORK/WSHELPER/RES_MKQU.C
Formulate a normal query, send, and await answer. Returned answer is placed in supplied buffer "answer". Perform preliminary check of answer, returning success only if no error is indicated and the answer count is nonzero. Return the size of the response on success, -1 on error. Error number is left in h_errno. Caller must parse answer and determine whether it answers the question.
Defined in: C:/WORK/WSHELPER/RES_QUER.C
Perform a call on res_query on the concatenation of name and domain, removing a trailing dot from name if domain is NULL.
Defined in: C:/WORK/WSHELPER/RES_QUER.C
Formulate a normal query, send, and retrieve answer in supplied buffer. Return the size of the response on success, -1 on error. If enabled, implement search rules until answer or unrecoverable failure is detected. Error number is left in h_errno. Only useful for queries in the same name hierarchy as the local host (not, for example, for host address-to-name lookups in domain in-addr.arpa).
Defined in: C:/WORK/WSHELPER/RES_QUER.C
sends a query to name servers and returns an answer. It will call res_init() if RES_INIT is not set, send the query to the local name server, and handle timeouts and retries. The length of the message is returned or -1 if there were errors.
Remarks
RES_AAONLY \tab Accept authoritative answers only. res_send() will continue until it finds an authoritative answer or finds an error. Currently this is not implemented.
RES_RECURSE Set the recursion desired bit in queries. This is the default. res_send() does not do iterative queries and expects the name server to handle recursion.
Defined in: C:/WORK/WSHELPER/RES_SEND.C
Global information that is used by the resolver routines is kept in the variable _res. Most of the values have reasonable defaults and can be ignored. Options are a simple bit mask and are OR'ed in to enable. Options stored in _res.options are defined in < resolv.h > and are as follows.
Defined in: C:/WORK/WSHELPER/RES_INIT.C
RES_DEBUG Print debugging messages.
RES_AAONLY Accept authoritative answers only. res_send() will continue until it finds an authoritative answer or finds an error. Currently this is not implemented.
RES_USEVC Use TCP connections for queries instead of UDP.
RES_PRIMARY Query primary server only.
RES_IGNTC Unused currently (ignore truncation errors, that is, do not retry with TCP).
RES_RECURSE Set the recursion desired bit in queries. This is the default. res_send() does not do iterative queries and expects the name server to handle recursion.
RES_DEFNAMES Append the default domain name to single label queries. This is the default.
RES_STAYOPEN Used with RES_USEVC to keep the TCP connection open between queries. This is useful only in programs that regularly do many queries. UDP should be the normal mode used.
RES_DNSRCH Search up local domain tree.
Our replacement for gethostbyaddr, called rgethostbyaddr These functions are used to obtain entries describing hosts. Gethostbyaddr() searches for information for a host with a given host address. The parameter type specifies the family of the address. This should be one of the address families defined in < sys/socket.h >. The parameter addr must be a pointer to a buffer containing the address. The address is given in a form specific to the address family. See the NOTES section below for more information. The parameter len specifies the length of the buffer indicated by addr.
Defined in: C:/WORK/WSHELPER/GETHNA.C
Searches for information for a host with the hostname specified by the character string parameter name.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This is equivalent to getservbyname but instead of just looking up the service entry in the local host file it will first query the Hesiod server(s) for the information. This allows a site to add new services in a centrally managed fashion instead of relying on propagation of a new services file to all machines on the network.
If the Hesiod query fails the function will fall back to the Winsock version of getservbyname which is usually implementated as a simple lookup in a local host file.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This function emulates the rhost function that was part of Excelan / Novell's LAN WorkPlace TCP/IP API. Given a pointer to an IP hostname it will return the IP address as a 32 bit integer.
Defined in: C:/WORK/WSHELPER/GETHNA.C
This function will attempt to determine which Operating System and subsystem is being used by the application. It should function under Win16, Windows NT amd Windows 95 at least. It does call WSAStartup() and WSACleanup(). This function does have side effects on some global variables. See the comments below.
Defined in: C:/WORK/WSHELPER/RES_INIT.C
these are defined in mitwhich.h
The low word contains one of the following, which is derived from the winsock implementation:
Get the local IP address using
the following algorithm:
get local host name with gethostname()
attempt to resolve local host name with gethostbyname()
If it fails:
get a UDP socket
connect UDP socket to aribitrary address and port
use getsockname() to get local address
Defined in: C:/WORK/WSHELPER/GETHNA.C
struct {
RES_TIMEOUT;
4;
RES_DEFAULT;
1;
} _res;
a structure of this type holds the state information for the
resolver optionsDefined in: C:/WORK/WSHELPER/RES_INIT.C
struct {
int len;
int ns_off;
int ar_off;
int count;
HEADER far * hd;
rr_t rr;
} nsmsg_t;
name server message structureDefined in: C:/WORK/WSHELPER/RESSCAN.H
struct {
short retrans;
short retry;
} retransXretry;
holds the retransmit and retry valuesDefined in: C:/WORK/WSHELPER/RESSCAN.H
struct {
short type;
short class;
int dlen;
LPSTR data;
} rr_t;
This structure is used by the resolve codeDefined in: C:/WORK/WSHELPER/RESSCAN.H