home *** CD-ROM | disk | FTP | other *** search
- #include "copyright.h"
- #include "wattcp.h"
- #include "errors.h"
- #include "elib.h"
- #include <dos.h>
- #include <windows.h>
- #include "dpmi.h"
-
- #define OLD
- #ifdef OLD
- int bufcmp( char far *first, char far *last, int len )
- {
- while ( len-- ) {
- if ( *first++ != *last++ )
- return( 1 );
- }
- return( 0 );
- }
- #endif OLD
-
- #define INT_FIRST 0x60
- #define INT_LAST 0x80
- #define PKT_LINE "PKT DRVR"
- #define PD_DRIVER_INFO 0x1ff
- #define PD_ACCESS 0x200
- #define PD_RELEASE 0x300
- #define PD_SEND 0x400
- #define PD_GET_ADDRESS 0x600
- #define CARRY 1 /* carry bit in flags register */
-
-
- static struct pkt_struct static_pkt_struct = {0x0008, 0x608};
- /* intelled values */
- struct pkt_struct far *pktstruct = &static_pkt_struct;
- struct pkt_struct far *pktstruct_raddr = &static_pkt_struct;
-
- word _pktipofs = 0; /* offset from header to start of pkt */
- word pkt_interrupt;
- word pkt_ip_handle;
- word pkt_arp_handle;
- longword far *interrupts = 0L;
-
- #define ASMPKT
- /*far we may decide to use far later on */
-
- extern void ASMPKT _pktentry();
- void far (*_pktentry_raddr)() = _pktentry;
- extern void ASMPKT _pktasminit( void far *, int, int );
- extern int qcmp( void far *, void far *, int );
- void (*do_intr)() = intr;
-
- pkt_init()
- {
- struct REGPACK regs, regs2;
- char far *temp;
- int pd_type; /* packet driver type */
- int class;
-
- _pktasminit( pktstruct_raddr->buf, MAXBUFS, BUFSIZE);
- for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
- /* Map_real() is safe whether we're in protected mode or not. */
- #ifdef WINDOWS
- temp = (char far *)map_real((char far *)(interrupts[pkt_interrupt]),
- (long)(sizeof(PKT_LINE)+3));
- #else
- temp = (char far *)(interrupts[pkt_interrupt]);
- #endif
-
- #ifdef OLD
- class = bufcmp( &(temp[3]), PKT_LINE, sizeof( PKT_LINE ));
- #else
- class = qcmp( &(temp[3]), PKT_LINE, sizeof( PKT_LINE ));
- #endif OLD
- #ifdef WINDOWS
- unmap_real(temp);
- #endif
- if ( !class ) {
- break;
- }
- }
- if ( pkt_interrupt > INT_LAST ) {
- return(ER_NOPKTD);
- }
-
- /* lets find out about the driver */
- regs.r_ax = PD_DRIVER_INFO;
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
-
- /* handle old versions, assume a class and just keep trying */
- if (regs.r_flags & CARRY ) {
- for ( class = 0; class < 2; ++class ) {
- _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
-
- for (pd_type = 1; pd_type < 128; ++pd_type ) {
- regs.r_ax = PD_ACCESS | _pktdevclass; /* ETH, SLIP */
- regs.r_bx = pd_type; /* type */
- regs.r_dx = 0; /* if number */
- regs.r_cx = sizeof( pktstruct_raddr->ip_type );
- regs.r_ds = FP_SEG( &pktstruct_raddr->ip_type );
- regs.r_si = FP_OFF( &pktstruct_raddr->ip_type );
- regs.r_es = FP_SEG( _pktentry_raddr);
- regs.r_di = FP_OFF( _pktentry_raddr);
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if ( ! (regs.r_flags & CARRY) ) break;
- }
-
- if (pd_type == 128 ) {
- return(ER_PKTDINIT);
- }
- /* we have found a working type, so kill it */
- regs.r_bx = regs.r_ax; /* handle */
- regs.r_ax = PD_RELEASE;
- do_intr( pkt_interrupt, ®s );
- }
- } else {
- pd_type = regs.r_dx;
- switch ( _pktdevclass = (regs.r_cx >> 8)) {
- case PD_ETHER : _pktipofs = 14;
- case PD_SLIP : break;
- default : return(ER_PKTDTYPE);
- }
- }
- regs.r_ax = PD_ACCESS | _pktdevclass;
- regs.r_bx = 0xffff; /* any type - was pd_type type */
- regs.r_dx = 0; /* if number */
- regs.r_cx = sizeof( pktstruct_raddr->ip_type );
- regs.r_ds = FP_SEG( &pktstruct_raddr->ip_type );
- regs.r_si = FP_OFF( &pktstruct_raddr->ip_type );
- regs.r_es = FP_SEG( _pktentry_raddr);
- regs.r_di = FP_OFF( _pktentry_raddr);
- memcpy( ®s2, ®s, sizeof( regs ));
- regs2.r_si = FP_OFF( &pktstruct_raddr->arp_type );
- regs2.r_ds = FP_SEG( &pktstruct_raddr->arp_type );
-
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY ) {
- #ifdef WINDOWS
- /* nothing */
- #else
- outs("ERROR # 0x");
- outhex( regs.r_dx >> 8 );
- outs(" accessing packet driver\n\r" );
- #endif
- return(ER_PKTDACCESS);
- }
- pkt_ip_handle = regs.r_ax;
-
- if (_pktdevclass != PD_SLIP) {
- regs2.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s2 );
- if ( regs2.r_flags & CARRY ) {
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_ip_handle;
- do_intr( pkt_interrupt, ®s );
-
- #ifdef WINDOWS
- /* nothing */
- #else
- outs("ERROR # 0x");
- outhex( regs2.r_dx >> 8 );
- outs(" accessing packet driver\n\r" );
- #endif
- return(ER_PKTDACCESS);
- }
- pkt_arp_handle = regs2.r_ax;
- }
-
- /* get ethernet address */
- regs.r_ax = PD_GET_ADDRESS;
- regs.r_bx = pkt_ip_handle;
- regs.r_es = FP_SEG( &pktstruct_raddr->eth_addr );
- regs.r_di = FP_OFF( &pktstruct_raddr->eth_addr );
- regs.r_cx = sizeof( &pktstruct_raddr->eth_addr );
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY ) {
- return(ER_ETHADDR);
- }
-
- return( 0 );
- }
- pkt_release()
- {
- struct REGPACK regs;
- int error;
-
- error = 0;
-
- if ( _pktdevclass != PD_SLIP ) {
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_arp_handle;
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if (regs.r_flags & CARRY ) {
- error = ER_PKTDRELSE;
- }
- }
-
- regs.r_ax = PD_RELEASE;
- regs.r_bx = pkt_ip_handle;
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if (regs.r_flags & CARRY ) {
- error = ER_PKTDRELSE;
- }
-
- return( error );
- }
-
- int pkt_send( register char *buffer, int length )
- {
- register int i;
- register char far *p;
- struct REGPACK regs;
- int retries;
-
- if(length > sizeof(pktstruct->send_buf))
- return(1);
- for(p = &pktstruct->send_buf, i = length; i > 0; --i) /* YECH! */
- *p++ = *buffer++;
-
- retries = 5;
- while(retries--) {
- regs.r_ax = PD_SEND;
- regs.r_ds = FP_SEG( &pktstruct_raddr->send_buf );
- regs.r_si = FP_OFF( &pktstruct_raddr->send_buf );
- regs.r_cx = length;
- regs.r_flags = CARRY;
- do_intr( pkt_interrupt, ®s );
- if ( regs.r_flags & CARRY )
- continue;
- return( 0 );
- }
- return( 1 );
- }
-
- /* return a buffer to the pool */
- pkt_buf_wipe()
- {
- char far *fp;
-
- for(fp = &pktstruct->buf[sizeof(pktstruct->buf)-1]; fp >= (char far *)pktstruct->buf;)
- *fp-- = 0;
- }
- pkt_buf_release( char *ptr )
- {
- char far *fptr;
-
- *(ptr - (2 + 14)) = 0;
-
- if(pktstruct != &static_pkt_struct) {
- fptr=(char far *)pktstruct->buf + (ptr - (char *)static_pkt_struct.buf);
- *(fptr - (2 + 14)) = 0;
- }
- }
- void * pkt_received()
- {
- register int i;
- int old;
- word oldin, newin; /* ip sequence numbers */
- register char far *fp;
- register char *np;
-
- /* check if there are any */
- old = oldin = 0xffff;
-
- /* Scan for the packet with the lowest sequence number */
- for ( i = 0 ; i < MAXBUFS; ++i ) {
- if ( *pktstruct->buf[i] != 1 ) continue;
- newin = *(word*)(&pktstruct->buf[i][ _pktipofs + 4 + 2]);
- if ( newin <= oldin ) {
- oldin = newin;
- old = i;
- }
- }
- /* If a packet was found mark it used, copy the contents over to */
- /* the local buffer, and return the address of the local buffer */
- if(old == -1)
- return NULL;
- else {
- if(pktstruct != &static_pkt_struct) {
- fp = pktstruct->buf[old]; np = static_pkt_struct.buf[old];
- for(i = sizeof(pktstruct->buf[0]); i > 0; --i) *np++ = *fp++;
- }
- return( &static_pkt_struct.buf[old][2] );
- }
- #ifdef OLD
- for (i=0; i < MAXBUFS; ++i) {
- if ( *pktstruct->buf[i] == 1 ) {
- *pktstruct->buf[i] = 2;
- if(pktstruct != &static_pkt_struct) {
- fp = pktstruct->buf[i]; np = static_pkt_struct.buf[i];
- for(i = sizeof(pktstruct->buf[i]); i > 0; --i) *np++ = *fp++;
- }
- return( &static_pkt_struct.buf[i][2] );
- }
- }
- #endif
- }
-
- void * _pkt_eth_init()
- {
- register char far *fp;
- register char *np;
- register int i;
-
- if ( pkt_init() ) {
- sock_exit();
- return NULL;
- }
- if(pktstruct != &static_pkt_struct) {
- fp = &pktstruct->eth_addr, np = &static_pkt_struct.eth_addr;
- for(i = sizeof(pktstruct->eth_addr); i > 0; --i) *np++ = *fp++;
- }
- return( &static_pkt_struct.eth_addr );
- }
-