home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*
- * nb.c -- C interface to the netbios
- *
- * The routines in this package provide a simplified C method of access
- * to the NetBios. The simplifications are achieved by assuming that
- * each network interface card (NIC) has only one assigned name (in addition
- * to its permanent name), and hence that only one name number is required.
- *
- * The global conventions are as follows:
- *
- * Routines return 0 for failure, non-0 for success. In case of
- * failure, the variable nb_errno contains the NetBios error
- * number from the last request. In case of success, the return
- * code may be a name number or a session number or neither,
- * depending on context.
- *
- * Routines that wait for completion before returning use
- * a static NCB and maintain all of its fields. Routines
- * that return immediately ("no wait" forms) use an NCB initialized
- * and supplied by the caller.
- *
- * NetBios routines may be called from within POST routines,
- * bearing in mind that the just-completed NCB may not be
- * reused, and DOS functions may only be called if the reentrancy
- * check permits them.
- *
- * Compiler: Microsoft C V5.0. Stack probes removed by #pragma.
- *
- * Tom Nolan - 9/20/89
- *
- *-------------------------------------------------------------------------*/
-
- #include <dos.h>
- #include "netbios.h"
-
- static union REGS regs;
- static struct SREGS sregs;
- static NCB ncb;
-
- int nb_errno;
-
- #pragma check_stack(off)
-
- /*-------------------------------------------------------------------------*/
- int isnodename(char *str) /* check if a string is a node name */
- {
- int len = strlen(str);
-
- return(len > 1 && len <= NODE_NAME_LEN && str[0] == '\\' && \
- str[1] == '\\');
- }
-
- /*-------------------------------------------------------------------------*/
- void namecpy(char *dst, char *src) /* copy name, padding with nulls */
- {
- int i;
-
- for(i = 0; (i < NODE_NAME_LEN) && *src; i++)
- *dst++ = *src++;
- for( ; i < NODE_NAME_LEN; i++)
- *dst++ = '\0';
- }
-
- /*-------------------------------------------------------------------------*/
- void clear_ncb(NCB *ncb_ptr) /* zero out an NCB */
- {
- int i;
- char *char_ptr = (char *) ncb_ptr;
-
- for(i = 0; i < sizeof(NCB); i++)
- *char_ptr++ = 0;
- }
-
- /*-------------------------------------------------------------------------*/
- int nb_request(int cmd, NCB *ncb_ptr) /* issue NetBIOS request */
- {
- segread(&sregs);
-
- ncb_ptr->command = cmd;
- sregs.es = sregs.ds;
- regs.x.bx = (int) ncb_ptr;
- int86x(NB_INT, ®s, ®s, &sregs);
- return(nb_errno = regs.h.al);
- }
-
- /*-------------------------------------------------------------------------*/
- int nb_cancel(NCB *ncb_ptr) /* cancel a NetBIOS request */
- {
- clear_ncb(&ncb);
- ncb.buffer = (char *) ncb_ptr;
- return(!nb_request(NB_CANCEL, &ncb));
- }
-
- /*-------------------------------------------------------------------------*/
- int get_name(char *str) /* get my own node name */
- {
- char status[78]; /* status buffer (60 bytes + 18 bytes) */
-
- *(int *)(status+58) = 0; /* in case NetBIOS isn't there... */
- clear_ncb(&ncb);
- ncb.buffer = (char far *) status;
- ncb.length = sizeof(status);
- strcpy(ncb.callname, "*");
- nb_request(NB_ADAPTER_STATUS, &ncb); /* issue status request */
- if(*(int *)(status+58) == 0) /* if no name table entries */
- return(0); /* ...failure */
- namecpy(str, status+60); /* copy out 1st name table entry */
- return(2); /* which is name for name num 2 */
- }
-
- /*-------------------------------------------------------------------------*/
- int reset(void) /* reset the NIC */
- {
- clear_ncb(&ncb);
- return(!nb_request(NB_RESET, &ncb));
- }
-
- /*-------------------------------------------------------------------------*/
- int add_name(char *str) /* add a node name to the name table */
- {
- int err;
-
- clear_ncb(&ncb);
- namecpy(ncb.name, str);
- err = nb_request(NB_ADD_NAME, &ncb);
- if(!err || (err == 0x0d))
- return(ncb.num);
- else
- return(0);
- }
-
- /*-------------------------------------------------------------------------*/
- int call(char *remote, char *local) /* call remote NIC by node name */
- {
- int err;
-
- clear_ncb(&ncb);
- namecpy(ncb.callname, remote);
- namecpy(ncb.name, local);
- ncb.sto = ncb.rto = 60;
- err = nb_request(NB_CALL, &ncb);
- if(err)
- return(0);
- else
- return(ncb.lsn);
- }
-
- /*-------------------------------------------------------------------------*/
- int listen(char *remote, char *local) /* listen for a call from a */
- { /* remote NIC */
- clear_ncb(&ncb);
- namecpy(ncb.callname, remote);
- namecpy(ncb.name, local);
- ncb.sto = ncb.rto = 60;
- if(nb_request(NB_LISTEN, &ncb))
- return(0);
- else
- return(ncb.lsn);
- }
-
- /*-------------------------------------------------------------------------*/
- int send_datagram(char *node, void *buf, int len) /* send datagram to a */
- { /* named node */
- clear_ncb(&ncb);
- ncb.num = 2;
- ncb.buffer = (char far *) buf;
- ncb.length = len;
- namecpy(ncb.callname, node);
- return(!nb_request(NB_SEND_DATAGRAM, &ncb));
- }
-
- /*-------------------------------------------------------------------------*/
- int send_brdcst_datagram(void *buf, int len) /* send a broadcast datagram */
- {
- clear_ncb(&ncb);
- ncb.num = 2;
- ncb.buffer = (char far *) buf;
- ncb.length = len;
- return(!nb_request(NB_SEND_BDATAGRAM, &ncb));
- }
-
- /*-------------------------------------------------------------------------*/
- int recv_datagram(void *buf, int len, char *sender) /* recv a datagram */
- { /* from any node */
- int err;
-
- clear_ncb(&ncb);
- ncb.num = 2;
- ncb.buffer = (char far *) buf;
- ncb.length = len;
- err = nb_request(NB_RECEIVE_DATAGRAM, &ncb);
- if(err)
- return(0);
- else
- {
- if(sender)
- namecpy(sender, ncb.callname);
- return(ncb.length);
- }
- }
-
- /*-------------------------------------------------------------------------*/
- int nw_recv_datagram(void *buf, int len, NCB *ncbptr) /* recv a datagram */
- { /* w/no wait option */
- int err;
-
- ncbptr->num = 2;
- ncbptr->buffer = (char far *) buf;
- ncbptr->length = len;
- return(!nb_request(NB_RECEIVE_DATAGRAM | NO_WAIT, ncbptr));
- }
-
- /*-------------------------------------------------------------------------*/
- int send(int lsn, void *buf, int len) /* send data to a session */
- {
- clear_ncb(&ncb);
- ncb.lsn = lsn;
- ncb.buffer = (char far *) buf;
- ncb.length = len;
- if(nb_request(NB_SEND, &ncb))
- return(0);
- else
- return(len);
- }
-
- /*-------------------------------------------------------------------------*/
- int receive(int lsn, void *buf, int len) /* recv data from session */
- {
- int ret;
-
- clear_ncb(&ncb);
- ncb.lsn = lsn;
- ncb.buffer = (char far *) buf;
- ncb.length = len;
- ret = nb_request(NB_RECEIVE, &ncb);
- if(ret == 0 || ret == 6) /* success or message incomplete */
- return(ncb.length);
- else
- return(0);
- }
-
- /*-------------------------------------------------------------------------*/
- int hangup(int lsn) /* hang up and clear a session */
- {
- clear_ncb(&ncb);
- ncb.lsn = lsn;
- return(!nb_request(NB_HANGUP, &ncb));
- }