home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / WATTCP / WATTCP.ZIP / SRC / PCPKT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-04  |  7.1 KB  |  274 lines

  1.  
  2. // FRAGSUPPORT enables support for packet reassembly of fragmented packets
  3. #define FRAGSUPPORT
  4.  
  5. #include <copyright.h>
  6. #include <wattcp.h>
  7. #include <elib.h>
  8. #include <dos.h>
  9. #ifdef __BORLANDC__
  10. #include <mem.h>
  11. #endif
  12. #include <string.h>
  13. #include <stdlib.h>
  14.  
  15.  
  16.  
  17. #define MAXBUFS     5    /* maximum number of Ethernet buffers */
  18. #define BUFSIZE     2100
  19.  
  20. #define DOS         0x21
  21. #define GETVECT     0x35
  22.  
  23. #define INT_FIRST 0x60
  24. #define INT_LAST  0x80
  25. #define PD_DRIVER_INFO    0x1ff
  26. #define PD_ACCESS     0x200
  27. #define PD_RELEASE    0x300
  28. #define PD_SEND        0x400
  29. #define PD_GET_ADDRESS    0x600
  30. #define  CARRY         1         /* carry bit in flags register */
  31.  
  32. word _pktipofs = 0;            /* offset from header to start of pkt */
  33. word pkt_interrupt;
  34. word pkt_ip_type = 0x0008;        /* these are intelled values */
  35. word pkt_arp_type = 0x608;
  36.  
  37. byte pktbuf[MAXBUFS][ BUFSIZE + 2 ];    /* first byte is busy flag, 2nd spare */
  38. word  pkt_ip_handle;
  39. word  pkt_arp_handle;
  40. byte eth_addr[ 6 ] ;
  41. longword far *interrupts = 0L;
  42. char *pkt_line = "PKT DRVR";
  43.  
  44. #define IP_DF       0x0040      // Don't fragment bit set for FRAG Flags
  45.  
  46. // forwards and externs
  47. byte *fragment( in_Header *ip );
  48. int pkt_init(void);
  49. extern void _pktentry();
  50. extern void _pktasminit( void far *, int, int );
  51.  
  52.  
  53. int pkt_init(void)
  54. {
  55.     struct REGPACK regs, regs2;
  56.     char far *temp;
  57.     int pd_type;    /* packet driver type */
  58.     int class;
  59.  
  60.     _pktasminit( pktbuf, MAXBUFS, BUFSIZE);
  61.     for (pkt_interrupt = INT_FIRST; pkt_interrupt <= INT_LAST; ++pkt_interrupt ) {
  62.  
  63.         temp = (char far *)getvect( pkt_interrupt );
  64.         if ( ! _fmemcmp( &(temp[3]), pkt_line, strlen( pkt_line )))
  65.             break;
  66.     }
  67.     if ( pkt_interrupt > INT_LAST ) {
  68.         outs("NO PACKET DRIVER FOUND\r\n");
  69.     return( 1 );
  70.     }
  71.  
  72.     /* lets find out about the driver */
  73.     regs.r_ax = PD_DRIVER_INFO;
  74.     intr( pkt_interrupt, ®s );
  75.  
  76.     /* handle old versions, assume a class and just keep trying */
  77.     if (regs.r_flags & CARRY ) {
  78.     for ( class = 0; class < 2; ++class ) {
  79.         _pktdevclass = (class) ? PD_SLIP : PD_ETHER;
  80.  
  81.         for (pd_type = 1; pd_type < 128; ++pd_type ) {
  82.         regs.r_ax = PD_ACCESS | _pktdevclass;  /* ETH, SLIP */
  83.         regs.r_bx = pd_type;        /* type */
  84.         regs.r_dx = 0;            /* if number */
  85.                 regs.r_cx = (_pktdevclass == PD_SLIP ) ? 0 : sizeof( pkt_ip_type);
  86.         regs.r_ds = FP_SEG( &pkt_ip_type );
  87.         regs.r_si = FP_OFF( &pkt_ip_type );
  88.                 regs.r_es = FP_SEG( _pktentry);
  89.         regs.r_di = FP_OFF( _pktentry);
  90.         intr( pkt_interrupt, ®s );
  91.         if ( ! (regs.r_flags & CARRY) ) break;
  92.         }
  93.  
  94.         if (pd_type == 128 ) {
  95.         outs("ERROR initializing packet driver\n\r");
  96.         return( 1 );
  97.         }
  98.         /* we have found a working type, so kill it */
  99.         regs.r_bx = regs.r_ax;    /* handle */
  100.         regs.r_ax = PD_RELEASE;
  101.         intr( pkt_interrupt, ®s );
  102.     }
  103.     } else {
  104.     pd_type = regs.r_dx;
  105.     switch ( _pktdevclass = (regs.r_cx >> 8)) {
  106.         case PD_ETHER : _pktipofs = 14;
  107.  
  108.             case PD_SLIP  : break;
  109.             default       : outs("ERROR: only Ethernet or SLIP packet drivers allowed\n\r");
  110.                 return( 1 );
  111.     }
  112.     }
  113.     regs.r_ax = PD_ACCESS | _pktdevclass;
  114.     regs.r_bx = 0xffff;                 /* any type */
  115.     regs.r_dx = 0;            /* if number */
  116.     regs.r_cx = (_pktdevclass == PD_SLIP) ? 0 : sizeof( pkt_ip_type );
  117.     regs.r_ds = FP_SEG( &pkt_ip_type );
  118.     regs.r_si = FP_OFF( &pkt_ip_type );
  119.     regs.r_es = FP_SEG( _pktentry);
  120.     regs.r_di = FP_OFF( _pktentry);
  121.     memcpy( ®s2, ®s, sizeof( regs ));
  122.     regs2.r_si = FP_OFF( &pkt_arp_type );
  123.     regs2.r_ds = FP_SEG( &pkt_arp_type );
  124.  
  125.     intr( pkt_interrupt, ®s );
  126.     if ( regs.r_flags & CARRY ) {
  127.     outs("ERROR # 0x");
  128.     outhex( regs.r_dx >> 8 );
  129.     outs(" accessing packet driver\n\r" );
  130.     return( 1 );
  131.     }
  132.     pkt_ip_handle = regs.r_ax;
  133.  
  134.     if (_pktdevclass != PD_SLIP) {
  135.     intr( pkt_interrupt, ®s2 );
  136.     if ( regs2.r_flags & CARRY ) {
  137.         regs.r_ax = PD_RELEASE;
  138.         regs.r_bx = pkt_ip_handle;
  139.         intr( pkt_interrupt, ®s );
  140.  
  141.         outs("ERROR # 0x");
  142.         outhex( regs2.r_dx >> 8 );
  143.         outs(" accessing packet driver\n\r" );
  144.         return( 1 );
  145.     }
  146.     pkt_arp_handle = regs2.r_ax;
  147.     }
  148.  
  149.     /* get ethernet address */
  150.     regs.r_ax = PD_GET_ADDRESS;
  151.     regs.r_bx = pkt_ip_handle;
  152.     regs.r_es = FP_SEG( eth_addr );
  153.     regs.r_di = FP_OFF( eth_addr );
  154.     regs.r_cx = sizeof( eth_addr );
  155.     intr( pkt_interrupt, ®s );
  156.     if ( regs.r_flags & CARRY ) {
  157.     outs("ERROR # reading ethernet address\n\r" );
  158.     return( 1 );
  159.     }
  160.  
  161.     return( 0 );
  162. }
  163. void pkt_release()
  164. {
  165.     struct REGPACK regs;
  166.     int error;
  167.  
  168.     if ( _pktdevclass != PD_SLIP ) {
  169.     regs.r_ax = PD_RELEASE;
  170.     regs.r_bx = pkt_arp_handle;
  171.     intr( pkt_interrupt, ®s );
  172.     if (regs.r_flags & CARRY ) {
  173.         outs("ERROR releasing packet driver for ARP\n\r");
  174.     }
  175.     }
  176.  
  177.     regs.r_ax = PD_RELEASE;
  178.     regs.r_bx = pkt_ip_handle;
  179.     intr( pkt_interrupt, ®s );
  180.     if (regs.r_flags & CARRY )
  181.     outs("ERROR releasing packet driver for IP\n\r");
  182.  
  183.     return;
  184. }
  185.  
  186. int pkt_send( char *buffer, int length )
  187. {
  188.     struct REGPACK regs;
  189.     int retries;
  190.  
  191.     retries = 5;
  192.     while (retries--) {
  193.         regs.r_ax = PD_SEND;
  194.         regs.r_ds = FP_SEG( buffer );
  195.         regs.r_si = FP_OFF( buffer );
  196.         regs.r_cx = length;
  197.         intr( pkt_interrupt, ®s );
  198.         if ( regs.r_flags & CARRY )
  199.             continue;
  200.         return( 0 );
  201.     }
  202.     return( 1 );
  203. }
  204.  
  205. /* return a buffer to the pool */
  206. void pkt_buf_wipe()
  207. {
  208.     memset( pktbuf, 0, sizeof( byte ) * MAXBUFS * (BUFSIZE+ 2));
  209. }
  210. void pkt_buf_release( char *ptr )
  211. {
  212.     *(ptr - (2 + _pktipofs)) = 0;
  213.  
  214. }
  215. void * pkt_received()
  216. {
  217.     word old;
  218.     int i;
  219.     word oldin, newin;    /* ip sequence numbers */
  220.     eth_Header  * temp_e = NULL;
  221.     in_Header   * temp;
  222.     byte        * t_buf;
  223.     extern int active_frags;
  224.  
  225.     /* check if there are any */
  226.     old = oldin = 0xffff;
  227.  
  228.     // Do frag timeout bit sad if we got the bit of one we're about to kill
  229. #ifdef FRAGSUPPORT
  230.     if ( active_frags ) timeout_frags();
  231. #endif // FRAGSUPPORT
  232.     for ( i = 0 ; i < MAXBUFS; ++i ) {
  233.     if ( *pktbuf[i] != 1 ) continue;
  234.  
  235.         // check if fragmented - SLIP supported
  236.     temp = (in_Header *) &pktbuf[ i ][ 2 ];
  237.         if ( _pktdevclass == PD_ETHER ) {
  238.             temp_e = (eth_Header *) temp;
  239.             temp += sizeof( eth_Header );
  240.         }
  241.  
  242. #ifdef FRAGSUPPORT
  243.         if ((( _pktdevclass == PD_SLIP ) || ( temp_e->type == IP_TYPE ))
  244.             && ( temp->frags & IP_DF )) {
  245.  
  246.             if ( ( t_buf = fragment( temp )) == NULL )
  247.                 // pass pointer to ip section of buffer
  248.                 continue;
  249.             else
  250.                 return( t_buf );
  251.         }
  252. #endif // FRAGSUPPORT
  253.         newin = *(word *)( &pktbuf[i][ _pktipofs + 4 + 2 ]);
  254.         if ( newin <= oldin ) {
  255.             oldin = newin;
  256.             old = i;
  257.         }
  258.     }
  259.  
  260.     return( (old == 0xffff) ? NULL : &pktbuf[old][2] );
  261. }
  262.  
  263. void * _pkt_eth_init()
  264. {
  265.     if ( pkt_init() ) {
  266.         outs("Program halted\r\n");
  267.     exit( 1 );
  268.     }
  269.     return( eth_addr );
  270. }
  271.  
  272.  
  273.                              
  274.