home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / WNWATTCP.ZIP / SRC / PCPKT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-10  |  8.1 KB  |  320 lines

  1. #include "copyright.h"
  2. #include "wattcp.h"
  3. #include "errors.h"
  4. #include "elib.h"
  5. #include <dos.h>
  6. #include <windows.h>
  7. #include "dpmi.h"
  8.  
  9. #define OLD
  10. #ifdef OLD
  11. int bufcmp( char far *first, char far *last, int len )
  12. {
  13.     while ( len-- ) {
  14.     if ( *first++ != *last++ )
  15.         return( 1 );
  16.     }
  17.     return( 0 );
  18. }
  19. #endif OLD
  20.  
  21. #define INT_FIRST 0x60
  22. #define INT_LAST  0x80
  23. #define PKT_LINE "PKT DRVR"
  24. #define PD_DRIVER_INFO  0x1ff
  25. #define PD_ACCESS       0x200
  26. #define PD_RELEASE      0x300
  27. #define PD_SEND        0x400
  28. #define PD_GET_ADDRESS  0x600
  29. #define CARRY        1    /* carry bit in flags register */
  30.  
  31.  
  32. static struct pkt_struct static_pkt_struct = {0x0008, 0x608};
  33.                         /* intelled values */
  34. struct pkt_struct far *pktstruct = &static_pkt_struct;
  35. struct pkt_struct far *pktstruct_raddr = &static_pkt_struct;
  36.  
  37. word _pktipofs = 0;            /* offset from header to start of pkt */
  38. word pkt_interrupt;
  39. word  pkt_ip_handle;
  40. word  pkt_arp_handle;
  41. longword far *interrupts = 0L;
  42.  
  43. #define ASMPKT
  44.         /*far     we may decide to use far later on */
  45.  
  46. extern void ASMPKT _pktentry();
  47. void far (*_pktentry_raddr)() = _pktentry;
  48. extern void ASMPKT _pktasminit( void far *, int, int );
  49. extern int qcmp( void far *, void far *, int );
  50. void (*do_intr)() = intr;
  51.  
  52. pkt_init()
  53. {
  54.     struct REGPACK regs, regs2;
  55.     char far *temp;
  56.     int pd_type;    /* packet driver type */
  57.     int class;
  58.  
  59.     _pktasminit( pktstruct_raddr->buf, MAXBUFS, BUFSIZE);
  60.     for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
  61.         /* Map_real() is safe whether we're in protected mode or not. */
  62. #ifdef WINDOWS
  63.         temp = (char far *)map_real((char far *)(interrupts[pkt_interrupt]),
  64.             (long)(sizeof(PKT_LINE)+3));
  65. #else
  66.         temp = (char far *)(interrupts[pkt_interrupt]);
  67. #endif
  68.  
  69. #ifdef OLD
  70.         class = bufcmp( &(temp[3]), PKT_LINE, sizeof( PKT_LINE ));
  71. #else
  72.         class = qcmp( &(temp[3]), PKT_LINE, sizeof( PKT_LINE ));
  73. #endif OLD
  74. #ifdef WINDOWS
  75.         unmap_real(temp);
  76. #endif
  77.         if ( !class ) {
  78.         break;
  79.     }
  80.     }
  81.     if ( pkt_interrupt > INT_LAST ) {
  82.     return(ER_NOPKTD);
  83.     }
  84.  
  85.     /* lets find out about the driver */
  86.     regs.r_ax = PD_DRIVER_INFO;
  87.     regs.r_flags = CARRY;
  88.     do_intr( pkt_interrupt, ®s );
  89.  
  90.     /* handle old versions, assume a class and just keep trying */
  91.     if (regs.r_flags & CARRY ) {
  92.     for ( class = 0; class < 2; ++class ) {
  93.         _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  94.  
  95.         for (pd_type = 1; pd_type < 128; ++pd_type ) {
  96.         regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  97.         regs.r_bx = pd_type;        /* type */
  98.         regs.r_dx = 0;            /* if number */
  99.         regs.r_cx = sizeof( pktstruct_raddr->ip_type );
  100.         regs.r_ds = FP_SEG( &pktstruct_raddr->ip_type );
  101.         regs.r_si = FP_OFF( &pktstruct_raddr->ip_type );
  102.         regs.r_es = FP_SEG( _pktentry_raddr);
  103.         regs.r_di = FP_OFF( _pktentry_raddr);
  104.         regs.r_flags = CARRY;
  105.         do_intr( pkt_interrupt, ®s );
  106.         if ( ! (regs.r_flags & CARRY) ) break;
  107.         }
  108.  
  109.         if (pd_type == 128 ) {
  110.         return(ER_PKTDINIT);
  111.         }
  112.         /* we have found a working type, so kill it */
  113.         regs.r_bx = regs.r_ax;      /* handle */
  114.         regs.r_ax = PD_RELEASE;
  115.         do_intr( pkt_interrupt, ®s );
  116.     }
  117.     } else {
  118.     pd_type = regs.r_dx;
  119.     switch ( _pktdevclass = (regs.r_cx >> 8)) {
  120.         case PD_ETHER : _pktipofs = 14;
  121.         case PD_SLIP  : break;
  122.         default       : return(ER_PKTDTYPE);
  123.     }
  124.     }
  125.     regs.r_ax = PD_ACCESS | _pktdevclass;
  126.     regs.r_bx = 0xffff;        /* any type - was pd_type  type */
  127.     regs.r_dx = 0;        /* if number */
  128.     regs.r_cx = sizeof( pktstruct_raddr->ip_type );
  129.     regs.r_ds = FP_SEG( &pktstruct_raddr->ip_type );
  130.     regs.r_si = FP_OFF( &pktstruct_raddr->ip_type );
  131.     regs.r_es = FP_SEG( _pktentry_raddr);
  132.     regs.r_di = FP_OFF( _pktentry_raddr);
  133.     memcpy( ®s2, ®s, sizeof( regs ));
  134.     regs2.r_si = FP_OFF( &pktstruct_raddr->arp_type );
  135.     regs2.r_ds = FP_SEG( &pktstruct_raddr->arp_type );
  136.  
  137.     regs.r_flags = CARRY;
  138.     do_intr( pkt_interrupt, ®s );
  139.     if ( regs.r_flags & CARRY ) {
  140. #ifdef WINDOWS
  141.     /* nothing */
  142. #else
  143.     outs("ERROR # 0x");
  144.     outhex( regs.r_dx >> 8 );
  145.     outs(" accessing packet driver\n\r" );
  146. #endif
  147.     return(ER_PKTDACCESS);
  148.     }
  149.     pkt_ip_handle = regs.r_ax;
  150.  
  151.     if (_pktdevclass != PD_SLIP) {
  152.     regs2.r_flags = CARRY;
  153.     do_intr( pkt_interrupt, ®s2 );
  154.     if ( regs2.r_flags & CARRY ) {
  155.         regs.r_ax = PD_RELEASE;
  156.         regs.r_bx = pkt_ip_handle;
  157.         do_intr( pkt_interrupt, ®s );
  158.  
  159. #ifdef WINDOWS
  160.         /* nothing */
  161. #else
  162.         outs("ERROR # 0x");
  163.         outhex( regs2.r_dx >> 8 );
  164.         outs(" accessing packet driver\n\r" );
  165. #endif
  166.         return(ER_PKTDACCESS);
  167.     }
  168.     pkt_arp_handle = regs2.r_ax;
  169.     }
  170.  
  171.     /* get ethernet address */
  172.     regs.r_ax = PD_GET_ADDRESS;
  173.     regs.r_bx = pkt_ip_handle;
  174.     regs.r_es = FP_SEG( &pktstruct_raddr->eth_addr );
  175.     regs.r_di = FP_OFF( &pktstruct_raddr->eth_addr );
  176.     regs.r_cx = sizeof( &pktstruct_raddr->eth_addr );
  177.     regs.r_flags = CARRY;
  178.     do_intr( pkt_interrupt, ®s );
  179.     if ( regs.r_flags & CARRY ) {
  180.     return(ER_ETHADDR);
  181.     }
  182.  
  183.     return( 0 );
  184. }
  185. pkt_release()
  186. {
  187.     struct REGPACK regs;
  188.     int error;
  189.  
  190.     error = 0;
  191.  
  192.     if ( _pktdevclass != PD_SLIP ) {
  193.     regs.r_ax = PD_RELEASE;
  194.     regs.r_bx = pkt_arp_handle;
  195.     regs.r_flags = CARRY;
  196.     do_intr( pkt_interrupt, ®s );
  197.     if (regs.r_flags & CARRY ) {
  198.         error = ER_PKTDRELSE;
  199.     }
  200.     }
  201.  
  202.     regs.r_ax = PD_RELEASE;
  203.     regs.r_bx = pkt_ip_handle;
  204.     regs.r_flags = CARRY;
  205.     do_intr( pkt_interrupt, ®s );
  206.     if (regs.r_flags & CARRY ) {
  207.     error = ER_PKTDRELSE;
  208.     }
  209.  
  210.     return( error );
  211. }
  212.  
  213. int pkt_send( register char *buffer, int length )
  214. {
  215.     register int i;
  216.     register char far *p;
  217.     struct REGPACK regs;
  218.     int retries;
  219.  
  220.     if(length > sizeof(pktstruct->send_buf))
  221.     return(1);
  222.     for(p = &pktstruct->send_buf, i = length; i > 0; --i)    /* YECH! */
  223.     *p++ = *buffer++;
  224.  
  225.     retries = 5;
  226.     while(retries--) {
  227.     regs.r_ax = PD_SEND;
  228.     regs.r_ds = FP_SEG( &pktstruct_raddr->send_buf );
  229.     regs.r_si = FP_OFF( &pktstruct_raddr->send_buf );
  230.     regs.r_cx = length;
  231.     regs.r_flags = CARRY;
  232.     do_intr( pkt_interrupt, ®s );
  233.     if ( regs.r_flags & CARRY )
  234.         continue;
  235.     return( 0 );
  236.     }
  237.     return( 1 );
  238. }
  239.  
  240. /* return a buffer to the pool */
  241. pkt_buf_wipe()
  242. {
  243.     char far *fp;
  244.  
  245.     for(fp = &pktstruct->buf[sizeof(pktstruct->buf)-1]; fp >= (char far *)pktstruct->buf;)
  246.         *fp-- = 0;
  247. }
  248. pkt_buf_release( char *ptr )
  249. {
  250.     char far *fptr;
  251.  
  252.     *(ptr - (2 + 14)) = 0;
  253.  
  254.     if(pktstruct != &static_pkt_struct) {
  255.         fptr=(char far *)pktstruct->buf + (ptr - (char *)static_pkt_struct.buf);
  256.     *(fptr - (2 + 14)) = 0;
  257.     }
  258. }
  259. void * pkt_received()
  260. {
  261.     register int i;
  262.     int old;
  263.     word oldin, newin;    /* ip sequence numbers */
  264.     register char far *fp;
  265.     register char *np;
  266.  
  267.     /* check if there are any */
  268.     old = oldin = 0xffff;
  269.  
  270.     /* Scan for the packet with the lowest sequence number */
  271.     for ( i = 0 ; i < MAXBUFS; ++i ) {
  272.     if ( *pktstruct->buf[i] != 1 ) continue;
  273.     newin = *(word*)(&pktstruct->buf[i][ _pktipofs + 4 + 2]);
  274.     if ( newin <= oldin ) {
  275.         oldin = newin;
  276.         old = i;
  277.     }
  278.     }
  279.     /* If a packet was found mark it used, copy the contents over to */
  280.     /* the local buffer, and return the address of the local buffer */
  281.     if(old == -1)
  282.         return NULL;
  283.     else {
  284.     if(pktstruct != &static_pkt_struct) {
  285.         fp = pktstruct->buf[old]; np = static_pkt_struct.buf[old];
  286.         for(i = sizeof(pktstruct->buf[0]); i > 0; --i) *np++ = *fp++;
  287.     }
  288.     return( &static_pkt_struct.buf[old][2] );
  289.     }
  290. #ifdef OLD
  291.     for (i=0; i < MAXBUFS; ++i) {
  292.     if ( *pktstruct->buf[i] == 1 ) {
  293.         *pktstruct->buf[i] = 2;
  294.         if(pktstruct != &static_pkt_struct) {
  295.             fp = pktstruct->buf[i]; np = static_pkt_struct.buf[i];
  296.         for(i = sizeof(pktstruct->buf[i]); i > 0; --i) *np++ = *fp++;
  297.         }
  298.         return( &static_pkt_struct.buf[i][2] );
  299.     }
  300.     }
  301. #endif
  302. }
  303.  
  304. void * _pkt_eth_init()
  305. {
  306.     register char far *fp;
  307.     register char *np;
  308.     register int i;
  309.  
  310.     if ( pkt_init() ) {
  311.     sock_exit();
  312.     return NULL;
  313.     }
  314.     if(pktstruct != &static_pkt_struct) {
  315.     fp = &pktstruct->eth_addr, np = &static_pkt_struct.eth_addr;
  316.     for(i = sizeof(pktstruct->eth_addr); i > 0; --i) *np++ = *fp++;
  317.     }
  318.     return( &static_pkt_struct.eth_addr );
  319. }
  320.