home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
MAGAZINE
/
LANTIMES
/
LT9002.ZIP
/
NB.C
< prev
next >
Wrap
Text File
|
1989-12-11
|
7KB
|
249 lines
/*--------------------------------------------------------------------------*
* 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));
}