NetBIOS

NetBIOS

The NetBIOS address family is more of an unusual protocol family accessible from Winsock. NetBIOS itself is a network programming interface (instead of a network protocol) that can communicate over many network protocols, such as TCP/IP. Winsock interfaces with the NetBIOS programming interface through the NetBIOS address family. Addressing NetBIOS from Winsock requires that you know NetBIOS names and LANA numbers. You can familiarize yourself with many NetBIOS concepts with the Chapter 17 NetBIOS API discussion included on the companion CD. We won't discuss the entire core NetBIOS interface concepts here, instead, we'll continue with the specifics of accessing NetBIOS from Winsock.

note

The NetBIOS address family is exposed by Winsock only on Windows NT platforms. It is not available on Windows 95, Windows 98, or Windows Me platforms or on Windows CE.

Addressing

The basis for addressing a machine under NetBIOS is a NetBIOS name. A NetBIOS name is 16 characters long, with the last character reserved as a qualifier to define what type of service the name belongs to. There are two types of NetBIOS names: unique and group. A unique name can be registered by only one process on the entire network. For example, a session-based server would register the name FOO, and clients who wanted to contact that server would attempt a connection to FOO. Group names allow a group of applications to register the same name, so datagrams sent to that name will be received by all processes that registered that name.

In Winsock, the NetBIOS addressing structure is defined in WSNETBS.H, as follows:

#define NETBIOS_NAME_LENGTH 16 typedef struct sockaddr_nb {     short   snb_family;     u_short snb_type;     char    snb_name[NETBIOS_NAME_LENGTH]; } SOCKADDR_NB, *PSOCKADDR_NB, FAR *LPSOCKADDR_NB;

The snb_family field specifies the address family of this structure and should always be set to AF_NETBIOS. The snb_type field is used to specify a unique or a group name. The following defines can be used for this field:

#define NETBIOS_UNIQUE_NAME         (0x0000) #define NETBIOS_GROUP_NAME          (0x0001)

Finally, the snb_name field is the actual NetBIOS name.

Now that you know what each field means and what it should be set to, the following handy macro defined in the header file sets all of this for you:

#define SET_NETBIOS_SOCKADDR(_snb, _type, _name, _port)       \     {                                                         \         int _i;                                               \         (_snb)->snb_family = AF_NETBIOS;                      \         (_snb)->snb_type = (_type);                           \         for (_i = 0; _i < NETBIOS_NAME_LENGTH - 1; _i++) {    \             (_snb)->snb_name[_i] = ' ';                       \         }                                                     \         for (_i = 0;                                          \              *((_name) + _i) != '\0'                          \              && _i < NETBIOS_NAME_LENGTH - 1;                 \              _i++)                                            \         {                                                     \             (_snb)->snb_name[_i] = *((_name)+_i);             \         }                                                     \         (_snb)->snb_name[NETBIOS_NAME_LENGTH - 1] = (_port);  \     }

The first parameter to the macro, called _snb, is the address of the SOCKADDR_NB structure you are filling in. As you can see, it automatically sets the snb_family field to AF_NETBIOS. For the _type parameter to the macro, specify NETBIOS_UNIQUE_NAME or NETBIOS_GROUP_NAME. The _name parameter is the NetBIOS name. The macro assumes it is either at least NETBIOS_NAME_LENGTH – 1 characters in length or is null-terminated if shorter. Notice that the snb_name field is prefilled with spaces. Finally, the macro sets the 16th character of the snb_name character string to the value of the _port parameter.

You can see that the NetBIOS name structure in Winsock is straightforward and shouldn't present any particular difficulties. The name resolution is performed under the hood, so you don't have to resolve a name into a physical address before performing any operations like you have to with TCP and IrDA. This becomes clear when you consider that NetBIOS is implemented over multiple protocols and each protocol has its own addressing scheme.

Creating a Socket

The most important consideration when you create a NetBIOS socket is the LANA number. Just as in the native NetBIOS API, you have to be aware of which LANA numbers concern your application. For a NetBIOS client and server to communicate, they must have a common transport protocol on which they both listen or connect. There are two ways to create a NetBIOS socket. The first is to call socket or WSASocket, as follows:

s = WSASocket(AF_NETBIOS, SOCK_DGRAM, -lana,               NULL, 0, WSA_FLAG_OVERLAPPED);

The type parameter of WSASocket is either SOCK_DGRAM or SOCK_SEQPACKET, depending on whether you want a connectionless datagram or a connection-oriented session socket. The third parameter, protocol, is the LANA number on which the socket should be created, except that you have to make it negative. The fourth parameter is null because you are specifying your own parameters, not using a WSAPROTOCOL_INFO structure. The fifth parameter is not used. Finally, the dwFlags parameter is set to WSA_FLAG_ OVERLAPPED; you should specify WSA_FLAG_OVERLAPPED on all calls to WSASocket. If you plan on using overlapped IO (as described in the next chapter), then this flag needs to be present when creating the socket.

The drawback to the first method of socket creation is that you need to know which LANA numbers are valid to begin with. Unfortunately, Winsock doesn't have a nice, short method of enumerating available LANA numbers. The alternative in Winsock is to enumerate all transport protocols with WSAEnumProtocols. Of course, you could call the Netbios function with the NCBENUM command as described in Chapter 17 to get the valid LANAs. Chapter 2 described how to call WSAEnumProtocols. The following sample enumerates all transport protocols, searches for a NetBIOS transport, and creates a socket for each one.

dwNum = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); if (dwNum == SOCKET_ERROR) {     // Error } for (i = 0; i < dwNum; i++) {     // Look for those entries in the AF_NETBIOS address family     if (lpProtocolBuf[i].iAddressFamily == AF_NETBIOS)     {         // Look for either SOCK_SEQPACKET or SOCK_DGRAM         if (lpProtocolBuf[i].iSocketType == SOCK_SEQPACKET)         {              s[j++] = WSASocket(FROM_PROTOCOL_INFO,                 FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,                    &lpProtocolBuf[i], 0, WSA_FLAG_OVERLAPPED);         }     } }

In the pseudocode shown, we enumerate the available protocols and iterate through them looking for those belonging to the AF_NETBIOS address family. Next, we check the socket type, and in this case, look for entries of type SOCK_SEQPACKET. Otherwise, if we wanted datagrams we would check for SOCK_DGRAM. If this matches, we have a NetBIOS transport we can use. If you need the LANA number, take the absolute value of the iProtocol field in the WSAPROTOCOL_INFO structure. The only exception is LANA 0. The iProtocol field for this LANA is 0x80000000 because 0 is reserved for use by Winsock. The variable j will contain the number of valid transports.

note

On the companion CD you will find a NetBIOS client and server application named WSNBCLNT.CPP and WSNBSVR.CPP, respectively.



Network Programming for Microsoft Windows
Network Programming for Microsoft Windows (Microsoft Professional Series)
ISBN: 0735605602
EAN: 2147483647
Year: 2001
Pages: 172
Authors: Anthony Jones

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net